various improvements
This commit is contained in:
@ -1,3 +1,18 @@
|
||||
# This file is part of Compute
|
||||
#
|
||||
# Compute is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Command line interface."""
|
||||
|
||||
import argparse
|
||||
@ -15,10 +30,7 @@ import yaml
|
||||
from pydantic import ValidationError
|
||||
|
||||
from compute import __version__
|
||||
from compute.exceptions import (
|
||||
ComputeServiceError,
|
||||
GuestAgentTimeoutExceededError,
|
||||
)
|
||||
from compute.exceptions import ComputeError, GuestAgentTimeoutExceededError
|
||||
from compute.instance import GuestAgent
|
||||
from compute.session import Session
|
||||
from compute.utils import ids
|
||||
@ -198,10 +210,23 @@ def _create_instance(session: Session, file: io.TextIOWrapper) -> None:
|
||||
sys.exit()
|
||||
|
||||
|
||||
def _shutdown_instance(session: Session, args: argparse.Namespace) -> None:
|
||||
instance = session.get_instance(args.instance)
|
||||
if args.soft:
|
||||
method = 'SOFT'
|
||||
elif args.hard:
|
||||
method = 'HARD'
|
||||
elif args.unsafe:
|
||||
method = 'UNSAFE'
|
||||
else:
|
||||
method = 'NORMAL'
|
||||
instance.shutdown(method)
|
||||
|
||||
|
||||
def main(session: Session, args: argparse.Namespace) -> None:
|
||||
"""Perform actions."""
|
||||
match args.command:
|
||||
case 'create':
|
||||
case 'init':
|
||||
_create_instance(session, args.file)
|
||||
case 'exec':
|
||||
_exec_guest_agent_command(session, args)
|
||||
@ -211,14 +236,16 @@ def main(session: Session, args: argparse.Namespace) -> None:
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.start()
|
||||
case 'shutdown':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.shutdown(args.method)
|
||||
_shutdown_instance(session, args)
|
||||
case 'reboot':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.reboot()
|
||||
case 'reset':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.reset()
|
||||
case 'powrst':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.power_reset()
|
||||
case 'pause':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.pause()
|
||||
@ -234,7 +261,7 @@ def main(session: Session, args: argparse.Namespace) -> None:
|
||||
case 'setmem':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.set_memory(args.memory, live=True)
|
||||
case 'setpasswd':
|
||||
case 'setpass':
|
||||
instance = session.get_instance(args.instance)
|
||||
instance.set_user_password(
|
||||
args.username,
|
||||
@ -261,7 +288,6 @@ def cli() -> None: # noqa: PLR0915
|
||||
'-c',
|
||||
'--connect',
|
||||
metavar='URI',
|
||||
default='qemu:///system',
|
||||
help='libvirt connection URI',
|
||||
)
|
||||
root.add_argument(
|
||||
@ -270,7 +296,7 @@ def cli() -> None: # noqa: PLR0915
|
||||
type=str.lower,
|
||||
metavar='LEVEL',
|
||||
choices=log_levels,
|
||||
help='log level [envvar: CMP_LOG]',
|
||||
help='log level',
|
||||
)
|
||||
root.add_argument(
|
||||
'-V',
|
||||
@ -280,13 +306,16 @@ def cli() -> None: # noqa: PLR0915
|
||||
)
|
||||
subparsers = root.add_subparsers(dest='command', metavar='COMMAND')
|
||||
|
||||
# create command
|
||||
create = subparsers.add_parser(
|
||||
'create', help='create new instance from YAML config file'
|
||||
# init command
|
||||
init = subparsers.add_parser(
|
||||
'init', help='initialise instance using YAML config file'
|
||||
)
|
||||
create.add_argument(
|
||||
init.add_argument(
|
||||
'file',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
nargs='?',
|
||||
default='instance.yaml',
|
||||
help='instance config [default: instance.yaml]',
|
||||
)
|
||||
|
||||
# exec subcommand
|
||||
@ -307,14 +336,14 @@ def cli() -> None: # noqa: PLR0915
|
||||
default=60,
|
||||
help=(
|
||||
'waiting time in seconds for a command to be executed '
|
||||
'in guest, 60 sec by default'
|
||||
'in guest [default: 60]'
|
||||
),
|
||||
)
|
||||
execute.add_argument(
|
||||
'-x',
|
||||
'--executable',
|
||||
default='/bin/sh',
|
||||
help='path to executable in guest, /bin/sh by default',
|
||||
help='path to executable in guest [default: /bin/sh]',
|
||||
)
|
||||
execute.add_argument(
|
||||
'-e',
|
||||
@ -352,12 +381,36 @@ def cli() -> None: # noqa: PLR0915
|
||||
# shutdown subcommand
|
||||
shutdown = subparsers.add_parser('shutdown', help='shutdown instance')
|
||||
shutdown.add_argument('instance')
|
||||
shutdown.add_argument(
|
||||
'-m',
|
||||
'--method',
|
||||
choices=['soft', 'normal', 'hard', 'unsafe'],
|
||||
default='normal',
|
||||
help='use shutdown method',
|
||||
shutdown_opts = shutdown.add_mutually_exclusive_group()
|
||||
shutdown_opts.add_argument(
|
||||
'-s',
|
||||
'--soft',
|
||||
action='store_true',
|
||||
help='normal guest OS shutdown, guest agent is used',
|
||||
)
|
||||
shutdown_opts.add_argument(
|
||||
'-n',
|
||||
'--normal',
|
||||
action='store_true',
|
||||
help='shutdown with hypervisor selected method [default]',
|
||||
)
|
||||
shutdown_opts.add_argument(
|
||||
'-H',
|
||||
'--hard',
|
||||
action='store_true',
|
||||
help=(
|
||||
"gracefully destroy instance, it's like long "
|
||||
'pressing the power button'
|
||||
),
|
||||
)
|
||||
shutdown_opts.add_argument(
|
||||
'-u',
|
||||
'--unsafe',
|
||||
action='store_true',
|
||||
help=(
|
||||
'destroy instance, this is similar to a power outage '
|
||||
'and may result in data loss or corruption'
|
||||
),
|
||||
)
|
||||
|
||||
# reboot subcommand
|
||||
@ -368,6 +421,10 @@ def cli() -> None: # noqa: PLR0915
|
||||
reset = subparsers.add_parser('reset', help='reset instance')
|
||||
reset.add_argument('instance')
|
||||
|
||||
# powrst subcommand
|
||||
powrst = subparsers.add_parser('powrst', help='power reset instance')
|
||||
powrst.add_argument('instance')
|
||||
|
||||
# pause subcommand
|
||||
pause = subparsers.add_parser('pause', help='pause instance')
|
||||
pause.add_argument('instance')
|
||||
@ -390,15 +447,15 @@ def cli() -> None: # noqa: PLR0915
|
||||
setmem.add_argument('instance')
|
||||
setmem.add_argument('memory', type=int, help='memory in MiB')
|
||||
|
||||
# setpasswd subcommand
|
||||
setpasswd = subparsers.add_parser(
|
||||
'setpasswd',
|
||||
# setpass subcommand
|
||||
setpass = subparsers.add_parser(
|
||||
'setpass',
|
||||
help='set user password in guest',
|
||||
)
|
||||
setpasswd.add_argument('instance')
|
||||
setpasswd.add_argument('username')
|
||||
setpasswd.add_argument('password')
|
||||
setpasswd.add_argument(
|
||||
setpass.add_argument('instance')
|
||||
setpass.add_argument('username')
|
||||
setpass.add_argument('password')
|
||||
setpass.add_argument(
|
||||
'-e',
|
||||
'--encrypted',
|
||||
action='store_true',
|
||||
@ -419,10 +476,18 @@ def cli() -> None: # noqa: PLR0915
|
||||
)
|
||||
|
||||
log.debug('CLI started with args: %s', args)
|
||||
|
||||
connect_uri = (
|
||||
args.connect
|
||||
or os.getenv('CMP_LIBVIRT_URI')
|
||||
or os.getenv('LIBVIRT_DEFAULT_URI')
|
||||
or 'qemu:///system'
|
||||
)
|
||||
|
||||
try:
|
||||
with Session(args.connect) as session:
|
||||
with Session(connect_uri) as session:
|
||||
main(session, args)
|
||||
except ComputeServiceError as e:
|
||||
except ComputeError as e:
|
||||
sys.exit(f'error: {e}')
|
||||
except KeyboardInterrupt:
|
||||
sys.exit()
|
||||
|
Reference in New Issue
Block a user