2023-07-22 23:59:49 +03:00
|
|
|
"""
|
|
|
|
Manage virtual machines.
|
|
|
|
|
|
|
|
Usage: na-vmctl [options] status <machine>
|
|
|
|
na-vmctl [options] is-running <machine>
|
|
|
|
na-vmctl [options] start <machine>
|
|
|
|
na-vmctl [options] shutdown <machine> [-f|--force] [-9|--sigkill]
|
2023-08-27 23:42:56 +03:00
|
|
|
na-vmctl [options] set-vcpus <machine> <nvcpus>
|
|
|
|
na-vmctl [options] set-memory <machine> <memory>
|
|
|
|
na-vmctl [options] list [-a|--all]
|
2023-07-22 23:59:49 +03:00
|
|
|
|
|
|
|
Options:
|
|
|
|
-c, --config <file> Config file [default: /etc/node-agent/config.yaml]
|
2023-07-29 15:10:30 +03:00
|
|
|
-l, --loglvl <lvl> Logging level
|
2023-08-27 23:42:56 +03:00
|
|
|
-a, --all List all machines including inactive
|
2023-07-22 23:59:49 +03:00
|
|
|
-f, --force Force action. On shutdown calls graceful destroy()
|
|
|
|
-9, --sigkill Send SIGKILL to QEMU process. Not affects without --force
|
|
|
|
"""
|
|
|
|
|
|
|
|
import logging
|
2023-08-24 22:36:12 +03:00
|
|
|
import pathlib
|
|
|
|
import sys
|
2023-07-22 23:59:49 +03:00
|
|
|
|
2023-07-28 01:01:32 +03:00
|
|
|
import libvirt
|
2023-07-22 23:59:49 +03:00
|
|
|
from docopt import docopt
|
|
|
|
|
2023-08-24 22:36:12 +03:00
|
|
|
from ..session import LibvirtSession
|
2023-07-29 15:35:36 +03:00
|
|
|
from ..vm import VirtualMachine, VMError, VMNotFound
|
2023-07-22 23:59:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
levels = logging.getLevelNamesMapping()
|
|
|
|
|
|
|
|
|
|
|
|
class Color:
|
|
|
|
RED = '\033[31m'
|
|
|
|
GREEN = '\033[32m'
|
|
|
|
YELLOW = '\033[33m'
|
|
|
|
NONE = '\033[0m'
|
|
|
|
|
|
|
|
|
2023-08-27 23:42:56 +03:00
|
|
|
class Table:
|
|
|
|
"""Print table. Example::
|
|
|
|
|
|
|
|
t = Table()
|
|
|
|
t.header(['KEY', 'VALUE']) # header is optional
|
|
|
|
t.row(['key 1', 'value 1'])
|
|
|
|
t.row(['key 2', 'value 2'])
|
|
|
|
t.rows(
|
|
|
|
[
|
|
|
|
['key 3', 'value 3'],
|
|
|
|
['key 4', 'value 4']
|
|
|
|
]
|
|
|
|
)
|
|
|
|
t.print()
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, whitespace: str = '\t'):
|
|
|
|
self.__rows = []
|
|
|
|
self.__whitespace = whitespace
|
|
|
|
|
|
|
|
def header(self, columns: list):
|
|
|
|
self.__rows.insert(0, [str(col) for col in columns])
|
|
|
|
|
|
|
|
def row(self, row: list):
|
|
|
|
self.__rows.append([str(col) for col in row])
|
|
|
|
|
|
|
|
def rows(self, rows: list):
|
|
|
|
for row in rows:
|
|
|
|
self.row(row)
|
|
|
|
|
|
|
|
def print(self):
|
|
|
|
widths = [max(map(len, col)) for col in zip(*self.__rows)]
|
|
|
|
for row in self.__rows:
|
|
|
|
print(self.__whitespace.join(
|
|
|
|
(val.ljust(width) for val, width in zip(row, widths))))
|
|
|
|
|
|
|
|
|
2023-07-22 23:59:49 +03:00
|
|
|
def cli():
|
|
|
|
args = docopt(__doc__)
|
|
|
|
config = pathlib.Path(args['--config']) or None
|
2023-07-29 15:10:30 +03:00
|
|
|
loglvl = None
|
2023-07-28 01:01:32 +03:00
|
|
|
machine = args['<machine>']
|
2023-07-22 23:59:49 +03:00
|
|
|
|
2023-07-29 15:10:30 +03:00
|
|
|
if args['--loglvl']:
|
|
|
|
loglvl = args['--loglvl'].upper()
|
|
|
|
|
2023-07-22 23:59:49 +03:00
|
|
|
if loglvl in levels:
|
|
|
|
logging.basicConfig(level=levels[loglvl])
|
|
|
|
|
|
|
|
with LibvirtSession(config) as session:
|
|
|
|
try:
|
2023-08-27 23:42:56 +03:00
|
|
|
if args['list']:
|
|
|
|
vms = session.list_domains()
|
|
|
|
table = Table()
|
|
|
|
table.header(['NAME', 'STATE', 'AUTOSTART'])
|
|
|
|
for vm_ in vms:
|
|
|
|
vm_ = VirtualMachine(vm_)
|
|
|
|
table.row([vm_.name, vm_.status, vm_.is_autostart])
|
|
|
|
table.print()
|
|
|
|
sys.exit()
|
|
|
|
|
2023-07-28 01:01:32 +03:00
|
|
|
vm = VirtualMachine(session, machine)
|
2023-07-22 23:59:49 +03:00
|
|
|
if args['status']:
|
|
|
|
print(vm.status)
|
|
|
|
if args['is-running']:
|
|
|
|
if vm.is_running:
|
|
|
|
print('running')
|
|
|
|
else:
|
|
|
|
sys.exit(vm.status)
|
|
|
|
if args['start']:
|
|
|
|
vm.start()
|
|
|
|
print(f'{vm.name} started')
|
|
|
|
if args['shutdown']:
|
|
|
|
vm.shutdown(force=args['--force'], sigkill=args['sigkill'])
|
|
|
|
except VMNotFound as nferr:
|
2023-07-28 01:01:32 +03:00
|
|
|
sys.exit(f'{Color.RED}VM {machine} not found.{Color.NONE}')
|
2023-07-22 23:59:49 +03:00
|
|
|
except VMError as vmerr:
|
|
|
|
sys.exit(f'{Color.RED}{vmerr}{Color.NONE}')
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
cli()
|