From bf2a2a08c9b7295214a74ceefd573a3f0b3de99f Mon Sep 17 00:00:00 2001 From: Seth Grover Date: Wed, 30 Oct 2024 16:44:40 -0600 Subject: [PATCH] major work on getting tests in place --- README.md | 14 +- pyproject.toml | 7 +- src/{malcolm_test => maltest}/__init__.py | 4 +- src/maltest/maltest.py | 308 +++++++++++++++++ .../tests/.gitignore | 0 src/maltest/tests/conftest.py | 9 + src/maltest/tests/test_malcolm_exists.py | 2 + .../malcolm_test.py => maltest/utils.py} | 318 ++---------------- .../virter/debian-12/init/00-system.toml | 0 .../virter/debian-12/init/01-apt-init.toml | 0 .../virter/debian-12/init/02-docker.toml | 0 .../virter/debian-12/init/03-podman.toml | 0 .../virter/malcolm-fini/01-wipe.toml | 0 .../virter/malcolm-init/01-clone-install.toml | 0 .../virter/malcolm-init/02-auth_setup.toml | 0 .../virter/malcolm-init/03-pull.toml | 0 .../virter/malcolm-init/99-reboot.toml | 0 17 files changed, 365 insertions(+), 297 deletions(-) rename src/{malcolm_test => maltest}/__init__.py (68%) create mode 100755 src/maltest/maltest.py rename src/{malcolm_test => maltest}/tests/.gitignore (100%) create mode 100644 src/maltest/tests/conftest.py create mode 100644 src/maltest/tests/test_malcolm_exists.py rename src/{malcolm_test/malcolm_test.py => maltest/utils.py} (69%) mode change 100755 => 100644 rename src/{malcolm_test => maltest}/virter/debian-12/init/00-system.toml (100%) rename src/{malcolm_test => maltest}/virter/debian-12/init/01-apt-init.toml (100%) rename src/{malcolm_test => maltest}/virter/debian-12/init/02-docker.toml (100%) rename src/{malcolm_test => maltest}/virter/debian-12/init/03-podman.toml (100%) rename src/{malcolm_test => maltest}/virter/malcolm-fini/01-wipe.toml (100%) rename src/{malcolm_test => maltest}/virter/malcolm-init/01-clone-install.toml (100%) rename src/{malcolm_test => maltest}/virter/malcolm-init/02-auth_setup.toml (100%) rename src/{malcolm_test => maltest}/virter/malcolm-init/03-pull.toml (100%) rename src/{malcolm_test => maltest}/virter/malcolm-init/99-reboot.toml (100%) diff --git a/README.md b/README.md index 0c88b6c..19359fc 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ This project makes use of: * [Virter](https://github.com/LINBIT/virter) for the creation and execution of libvirt-based virtual machines running Malcolm * [pytest](https://docs.pytest.org/en/stable/) for the testing framework -## Package source highlights (under `src/malcolm_test`) +## Package source highlights (under `src/maltest`) -* 🐍 [`malcolm_test.py`](#MalcolmVMInitScript) - A Python script for running Malcolm in a VM with virter (see below) +* 🐍 [`maltest.py`](#MalcolmVMInitScript) - A Python script for running Malcolm in a VM with virter (see below) * 🗁 `virter/` - A directory structure containing TOML files for [provisioning](https://github.com/LINBIT/virter/blob/master/doc/provisioning.md) the virter VMs in which Malcolm will run. Its subdirectories are arranged thusly: - - 🗁 `debian-12/` - A directory matching the name of the virter image (supplied to [`malcolm_test.py`](#MalcolmVMInitScript) with the `-i`/`--image` argument) + - 🗁 `debian-12/` - A directory matching the name of the virter image (supplied to [`maltest.py`](#MalcolmVMInitScript) with the `-i`/`--image` argument) + 🗁 `init/` - TOML files for the initial steps of provisioning the OS (before setting up and starting Malcolm) + 🗁 `fini/` - TOML files for the final stages of provisioning the OS (after shutting down Malcolm) - 🗁 `malcolm-init/` - Distribution-agnostic provisioning TOML files for setting up Malcolm prior to starting it @@ -37,14 +37,14 @@ python3 -m pip install -U 'git+https://github.com/idaholab/Malcolm-Test' ## The `malcolm-test` script -`malcolm_test.py` is a Python script for Linux that uses [virter](https://github.com/LINBIT/virter) (a command line tool for simple creation and cloning of virtual machines) to run an instance of [Malcolm](https://idaholab.github.io/Malcolm/) against which automated system tests can be run. +`maltest.py` is a Python script for Linux that uses [virter](https://github.com/LINBIT/virter) (a command line tool for simple creation and cloning of virtual machines) to run an instance of [Malcolm](https://idaholab.github.io/Malcolm/) against which automated system tests can be run. When [installed](#Installation) via pip, this script may be executed as `malcolm-test` from the Linux command line. ### Usage ``` -usage: malcolm_test.py +usage: maltest.py See README.md for usage details. @@ -80,7 +80,7 @@ Virtual machine specifications: --vm-provision-malcolm [true|false] Perform VM provisioning (Malcolm-specific) --vm-provision-path - Path containing subdirectories with TOML files for VM provisioning (e.g., /home/tlacuache/.asdf/installs/python/3.12.7/lib/python3.12/site-packages/malcolm_test/virter) + Path containing subdirectories with TOML files for VM provisioning (e.g., /home/tlacuache/.asdf/installs/python/3.12.7/lib/python3.12/site-packages/maltest/virter) --build-vm The name for a new VM image to build and commit instead of running one --build-vm-keep-layers [true|false] Don't remove intermediate layers when building a new VM image @@ -98,7 +98,7 @@ Malcolm runtime configuration: *with INFO-level `-vv` verbosity, output reduced for length* ``` -2024-10-25 12:42:51 INFO: /home/user/Malcolm-Test/malcolm_test.py +2024-10-25 12:42:51 INFO: /home/user/Malcolm-Test/maltest.py 2024-10-25 12:42:51 INFO: Arguments: ['-vv', '--rm', '--github-url', 'https://github.com/idaholab/Malcolm', '--github-branch', 'main'] 2024-10-25 12:42:51 INFO: Arguments: Namespace(verbose=20, removeAfterExec=True, repoUrl='https://github.com/idaholab/Malcolm', repoBranch='main', vmCpuCount=8, vmMemoryGigabytes=31, vmDiskGigabytes=64, vmImage='debian-12', vmImageUsername='debian', vmNamePrefix='malcolm', vmExistingName='', vmProvision=True, vmProvisionPath='/home/user/Malcolm-Test/virter', containerImageFile='', startMalcolm=True, postInitSleep=30) 2024-10-25 12:42:51 INFO: ['virter', 'vm', 'run', 'debian-12', '--id', '0', '--name', 'malcolm-126', '--vcpus', '8', '--memory', '31GB', '--bootcapacity', '64GB', '--user', 'debian', '--wait-ssh'] diff --git a/pyproject.toml b/pyproject.toml index 6e860a7..940c20f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "malcolm-test" -version = "0.1.0" +version = "0.2.0" authors = [ { name="Seth Grover", email="mero.mero.guero@gmail.com" }, ] @@ -29,7 +29,10 @@ Homepage = "https://github.com/idaholab/malcolm-test" Issues = "https://github.com/idaholab/malcolm-test/issues" [project.scripts] -malcolm-test = "malcolm_test:main" +malcolm-test = "maltest:main" + +[tool.hatch.build.targets.wheel] +packages = ["src/maltest"] [tool.pytest.ini_options] pythonpath = "src" diff --git a/src/malcolm_test/__init__.py b/src/maltest/__init__.py similarity index 68% rename from src/malcolm_test/__init__.py rename to src/maltest/__init__.py index 6ec5ae3..49535f7 100644 --- a/src/malcolm_test/__init__.py +++ b/src/maltest/__init__.py @@ -5,6 +5,6 @@ except PackageNotFoundError: __version__ = None -__all__ = ["main", "MalcolmVM"] +__all__ = ["main"] -from .malcolm_test import main, MalcolmVM +from .maltest import main diff --git a/src/maltest/maltest.py b/src/maltest/maltest.py new file mode 100755 index 0000000..5a162ee --- /dev/null +++ b/src/maltest/maltest.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import argparse +import json +import logging +import mmguero +import multiprocessing +import os +import psutil +import pytest +import signal +import sys + +from maltest.utils import MalcolmVM, ShuttingDown, set_malcolm_vm_info + +################################################################################################### +script_name = os.path.basename(__file__) +script_path = os.path.dirname(os.path.realpath(__file__)) + + +################################################################################################### +# handle sigint/sigterm and set a global shutdown variable +def shutdown_handler(signum, frame): + ShuttingDown[0] = True + + +################################################################################################### +# main +def main(): + parser = argparse.ArgumentParser( + description='\n'.join( + [ + 'See README.md for usage details.', + ] + ), + formatter_class=argparse.RawTextHelpFormatter, + add_help=True, + usage=f'{script_name} ', + ) + parser.add_argument( + '--verbose', + '-v', + action='count', + default=1, + help='Increase verbosity (e.g., -v, -vv, etc.)', + ) + parser.add_argument( + '-r', + '--rm', + dest='removeAfterExec', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=False, + help="Remove virtual Malcolm instance after execution is complete", + ) + + repoArgGroup = parser.add_argument_group('Malcolm Git repo') + repoArgGroup.add_argument( + '-g', + '--github-url', + required=False, + dest='repoUrl', + metavar='', + type=str, + default=os.getenv('MALCOLM_REPO_URL', 'idaholab'), + help='Malcolm repository url (e.g., https://github.com/idaholab/Malcolm)', + ) + repoArgGroup.add_argument( + '-b', + '--github-branch', + required=False, + dest='repoBranch', + metavar='', + type=str, + default=os.getenv('MALCOLM_REPO_BRANCH', 'main'), + help='Malcolm repository branch (e.g., main)', + ) + + vmSpecsArgGroup = parser.add_argument_group('Virtual machine specifications') + vmSpecsArgGroup.add_argument( + '-c', + '--cpus', + dest='vmCpuCount', + required=False, + metavar='', + type=int, + default=(multiprocessing.cpu_count() // 2), + help='Number of CPUs for virtual Malcolm instance', + ) + vmSpecsArgGroup.add_argument( + '-m', + '--memory', + dest='vmMemoryGigabytes', + required=False, + metavar='', + type=int, + default=max(16, int(round(psutil.virtual_memory().total / (1024.0**3))) // 2), + help='System memory (GB) for virtual Malcolm instance', + ) + vmSpecsArgGroup.add_argument( + '-d', + '--disk', + dest='vmDiskGigabytes', + required=False, + metavar='', + type=int, + default=64, + help='Disk size (GB) for virtual Malcolm instance', + ) + vmSpecsArgGroup.add_argument( + '-i', + '--image', + required=False, + dest='vmImage', + metavar='', + type=str, + default=os.getenv('VIRTER_IMAGE', 'debian-12'), + help='Malcolm virtual instance base image name (e.g., debian-12)', + ) + vmSpecsArgGroup.add_argument( + '--image-user', + required=False, + dest='vmImageUsername', + metavar='', + type=str, + default=os.getenv('VIRTER_USER', 'debian'), + help='Malcolm virtual instance base image username (e.g., debian)', + ) + vmSpecsArgGroup.add_argument( + '--vm-name-prefix', + required=False, + dest='vmNamePrefix', + metavar='', + type=str, + default=os.getenv('VIRTER_NAME_PREFIX', 'malcolm'), + help='Prefix for Malcolm VM name (e.g., malcolm)', + ) + vmSpecsArgGroup.add_argument( + '--existing-vm', + required=False, + dest='vmExistingName', + metavar='', + type=str, + default=os.getenv('VIRTER_EXISTING', ''), + help='Name of an existing virter VM to use rather than starting up a new one', + ) + vmSpecsArgGroup.add_argument( + '--vm-provision', + dest='vmProvision', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=True, + help=f'Perform VM provisioning', + ) + vmSpecsArgGroup.add_argument( + '--vm-provision-malcolm', + dest='vmProvisionMalcolm', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=True, + help=f'Perform VM provisioning (Malcolm-specific)', + ) + vmSpecsArgGroup.add_argument( + '--vm-provision-path', + required=False, + dest='vmProvisionPath', + metavar='', + type=str, + default=os.getenv('VIRTER_PROVISION_PATH', os.path.join(script_path, 'virter')), + help=f'Path containing subdirectories with TOML files for VM provisioning (e.g., {os.path.join(script_path, "virter")})', + ) + vmSpecsArgGroup.add_argument( + '--build-vm', + required=False, + dest='vmBuildName', + metavar='', + type=str, + default=os.getenv('VIRTER_BUILD_VM', ''), + help='The name for a new VM image to build and commit instead of running one', + ) + vmSpecsArgGroup.add_argument( + '--build-vm-keep-layers', + dest='vmBuildKeepLayers', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=False, + help=f"Don't remove intermediate layers when building a new VM image", + ) + + configArgGroup = parser.add_argument_group('Malcolm runtime configuration') + configArgGroup.add_argument( + '--container-image-file', + required=False, + dest='containerImageFile', + metavar='', + type=str, + default='', + help='Malcolm container images .tar.xz file for installation (instead of "docker pull")', + ) + configArgGroup.add_argument( + '-s', + '--start', + dest='startMalcolm', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=True, + help=f'Start Malcolm once provisioning is complete (default true)', + ) + configArgGroup.add_argument( + '--sleep', + dest='postInitSleep', + required=False, + metavar='', + type=int, + default=30, + help='Seconds to sleep after init before starting Malcolm (default 30)', + ) + + testArgGroup = parser.add_argument_group('Testing configuration') + testArgGroup.add_argument( + '--test-path', + required=False, + dest='testPath', + metavar='', + type=str, + default=os.getenv('MALCOLM_TEST_PATH', os.path.join(script_path, 'tests')), + help=f'Path containing test definitions (e.g., {os.path.join(script_path, 'tests')})', + ) + configArgGroup.add_argument( + '-t', + '--run-tests', + dest='runTests', + type=mmguero.str2bool, + nargs='?', + metavar="true|false", + const=True, + default=True, + help=f'Run test suite once Malcolm is started', + ) + + try: + parser.error = parser.exit + args = parser.parse_args() + except SystemExit as e: + mmguero.eprint(f'Invalid argument(s): {e}') + sys.exit(2) + + # configure logging levels based on -v, -vv, -vvv, etc. + args.verbose = logging.CRITICAL - (10 * args.verbose) if args.verbose > 0 else 0 + logging.basicConfig( + level=args.verbose, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' + ) + logging.info(os.path.join(script_path, script_name)) + logging.info("Arguments: {}".format(sys.argv[1:])) + logging.info("Arguments: {}".format(args)) + if args.verbose > logging.DEBUG: + sys.tracebacklimit = 0 + + # the whole thing runs on virter, so if we don't have that what are we even doing here + err, _ = mmguero.RunProcess(['virter', 'version']) + if err != 0: + logging.error(f'{script_name} requires virter, please see https://github.com/LINBIT/virter') + return 1 + + # handle sigint and sigterm for graceful shutdown + signal.signal(signal.SIGINT, shutdown_handler) + signal.signal(signal.SIGTERM, shutdown_handler) + + malcolmVm = MalcolmVM( + args=args, + debug=(args.verbose <= logging.DEBUG), + logger=logging, + ) + try: + if args.vmBuildName: + exitCode = malcolmVm.Build() + else: + exitCode = malcolmVm.Start() + malcolmInfo = malcolmVm.Info() + logging.info(json.dumps(malcolmInfo)) + set_malcolm_vm_info(malcolmInfo) + if args.runTests and os.path.isdir(args.testPath): + exitCode = pytest.main(['-p', 'no:cacheprovider', args.testPath]) + malcolmVm.WaitForShutdown() + finally: + del malcolmVm + + logging.info(f'{script_name} returning {exitCode}') + return exitCode + + +################################################################################################### +if __name__ == '__main__': + if main() > 0: + sys.exit(0) + else: + sys.exit(1) diff --git a/src/malcolm_test/tests/.gitignore b/src/maltest/tests/.gitignore similarity index 100% rename from src/malcolm_test/tests/.gitignore rename to src/maltest/tests/.gitignore diff --git a/src/maltest/tests/conftest.py b/src/maltest/tests/conftest.py new file mode 100644 index 0000000..9662871 --- /dev/null +++ b/src/maltest/tests/conftest.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +import pytest +from maltest.utils import get_malcolm_vm_info + + +@pytest.fixture +def malcolm_vm_info(): + return get_malcolm_vm_info() diff --git a/src/maltest/tests/test_malcolm_exists.py b/src/maltest/tests/test_malcolm_exists.py new file mode 100644 index 0000000..e425e7b --- /dev/null +++ b/src/maltest/tests/test_malcolm_exists.py @@ -0,0 +1,2 @@ +def test_malcolm_exists(malcolm_vm_info): + assert isinstance(malcolm_vm_info, dict) and malcolm_vm_info.get("ip", None) diff --git a/src/malcolm_test/malcolm_test.py b/src/maltest/utils.py old mode 100755 new mode 100644 similarity index 69% rename from src/malcolm_test/malcolm_test.py rename to src/maltest/utils.py index 9ba9da6..de261d3 --- a/src/malcolm_test/malcolm_test.py +++ b/src/maltest/utils.py @@ -1,39 +1,33 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- -import argparse -import copy -import errno import glob import json -import logging import mmguero -import multiprocessing import os import petname -import psutil import re -import signal import subprocess import sys import time import tomli import tomli_w -from random import randrange from collections import defaultdict -################################################################################################### -script_name = os.path.basename(__file__) -script_path = os.path.dirname(os.path.realpath(__file__)) -shuttingDown = [False] +ShuttingDown = [False] + +MalcolmVmInfo = None ################################################################################################### -# handle sigint/sigterm and set a global shutdown variable -def shutdown_handler(signum, frame): - global shuttingDown - shuttingDown[0] = True +def set_malcolm_vm_info(info): + global MalcolmVmInfo + MalcolmVmInfo = info + + +def get_malcolm_vm_info(): + global MalcolmVmInfo + return MalcolmVmInfo ################################################################################################### @@ -96,7 +90,13 @@ def __init__( for varName, varVal in [ (key.upper(), value) for key, value in self.osEnv.items() - if key.upper().startswith('MALCOLM_') and key.upper() not in ('MALCOLM_REPO_URL', 'MALCOLM_REPO_BRANCH') + if key.upper().startswith('MALCOLM_') + and key.upper() + not in ( + 'MALCOLM_REPO_URL', + 'MALCOLM_REPO_BRANCH', + 'MALCOLM_TEST_PATH', + ) ]: self.provisionEnvArgs.extend( [ @@ -204,10 +204,11 @@ def Build(self): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def Start(self): - global shuttingDown + global ShuttingDown self.buildMode = False + cmd = [] output = [] exitCode = 1 if self.vmExistingName: @@ -219,7 +220,7 @@ def Start(self): else: self.logger.error(f'{self.name} does not already exist') - elif shuttingDown[0] == False: + elif ShuttingDown[0] == False: # use virter to execute a virtual machine self.name = f"{self.vmNamePrefix}-{petname.Generate()}" cmd = [ @@ -243,7 +244,7 @@ def Start(self): ] cmd = [str(x) for x in list(mmguero.Flatten(cmd))] - logging.info(cmd) + self.logger.info(cmd) exitCode, output = mmguero.RunProcess( cmd, env=self.osEnv, @@ -272,10 +273,12 @@ def ProvisionFile( tolerateFailure=False, overrideBuildName=None, ): - global shuttingDown + global ShuttingDown skipped = False - if (shuttingDown[0] == False) or (continueThroughShutdown == True): + out = [] + cmd = [] + if (ShuttingDown[0] == False) or (continueThroughShutdown == True): if self.buildMode: if os.path.basename(provisionFile) == '99-reboot.toml': @@ -425,7 +428,7 @@ def CopyFile( # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def ProvisionInit(self): - global shuttingDown + global ShuttingDown if (self.vmProvision or self.vmBuildName) and os.path.isdir(self.vmProvisionPath): @@ -459,12 +462,12 @@ def ProvisionInit(self): # sleep a bit, if indicated sleepCtr = 0 - while (shuttingDown[0] == False) and (self.buildMode == False) and (sleepCtr < self.postInitSleep): + while (ShuttingDown[0] == False) and (self.buildMode == False) and (sleepCtr < self.postInitSleep): sleepCtr = sleepCtr + 1 time.sleep(1) # start Malcolm and wait for it to become ready to process data - if (self.buildMode == False) and self.startMalcolm and (shuttingDown[0] == False): + if (self.buildMode == False) and self.startMalcolm and (ShuttingDown[0] == False): self.ProvisionTOML( data={ 'version': 1, @@ -535,13 +538,13 @@ def ProvisionFini(self): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def WaitForShutdown(self): - global shuttingDown + global ShuttingDown returnCode = 0 sleepCtr = 0 noExistCtr = 0 - while shuttingDown[0] == False: + while ShuttingDown[0] == False: time.sleep(1) sleepCtr = sleepCtr + 1 if sleepCtr > 60: @@ -553,264 +556,7 @@ def WaitForShutdown(self): self.logger.warning(f'Failed to ascertain existence of {self.name} (x {noExistCtr})') if noExistCtr >= 5: self.logger.error(f'{self.name} no longer exists, giving up') - shuttingDown[0] = True + ShuttingDown[0] = True returnCode = 1 return returnCode - - -################################################################################################### -# main -def main(): - parser = argparse.ArgumentParser( - description='\n'.join( - [ - 'See README.md for usage details.', - ] - ), - formatter_class=argparse.RawTextHelpFormatter, - add_help=True, - usage=f'{script_name} ', - ) - parser.add_argument( - '--verbose', - '-v', - action='count', - default=1, - help='Increase verbosity (e.g., -v, -vv, etc.)', - ) - parser.add_argument( - '-r', - '--rm', - dest='removeAfterExec', - type=mmguero.str2bool, - nargs='?', - metavar="true|false", - const=True, - default=False, - help="Remove virtual Malcolm instance after execution is complete", - ) - - repoArgGroup = parser.add_argument_group('Malcolm Git repo') - repoArgGroup.add_argument( - '-g', - '--github-url', - required=False, - dest='repoUrl', - metavar='', - type=str, - default=os.getenv('MALCOLM_REPO_URL', 'idaholab'), - help='Malcolm repository url (e.g., https://github.com/idaholab/Malcolm)', - ) - repoArgGroup.add_argument( - '-b', - '--github-branch', - required=False, - dest='repoBranch', - metavar='', - type=str, - default=os.getenv('MALCOLM_REPO_BRANCH', 'main'), - help='Malcolm repository branch (e.g., main)', - ) - - vmSpecsArgGroup = parser.add_argument_group('Virtual machine specifications') - vmSpecsArgGroup.add_argument( - '-c', - '--cpus', - dest='vmCpuCount', - required=False, - metavar='', - type=int, - default=(multiprocessing.cpu_count() // 2), - help='Number of CPUs for virtual Malcolm instance', - ) - vmSpecsArgGroup.add_argument( - '-m', - '--memory', - dest='vmMemoryGigabytes', - required=False, - metavar='', - type=int, - default=max(16, int(round(psutil.virtual_memory().total / (1024.0**3))) // 2), - help='System memory (GB) for virtual Malcolm instance', - ) - vmSpecsArgGroup.add_argument( - '-d', - '--disk', - dest='vmDiskGigabytes', - required=False, - metavar='', - type=int, - default=64, - help='Disk size (GB) for virtual Malcolm instance', - ) - vmSpecsArgGroup.add_argument( - '-i', - '--image', - required=False, - dest='vmImage', - metavar='', - type=str, - default=os.getenv('VIRTER_IMAGE', 'debian-12'), - help='Malcolm virtual instance base image name (e.g., debian-12)', - ) - vmSpecsArgGroup.add_argument( - '--image-user', - required=False, - dest='vmImageUsername', - metavar='', - type=str, - default=os.getenv('VIRTER_USER', 'debian'), - help='Malcolm virtual instance base image username (e.g., debian)', - ) - vmSpecsArgGroup.add_argument( - '--vm-name-prefix', - required=False, - dest='vmNamePrefix', - metavar='', - type=str, - default=os.getenv('VIRTER_NAME_PREFIX', 'malcolm'), - help='Prefix for Malcolm VM name (e.g., malcolm)', - ) - vmSpecsArgGroup.add_argument( - '--existing-vm', - required=False, - dest='vmExistingName', - metavar='', - type=str, - default=os.getenv('VIRTER_EXISTING', ''), - help='Name of an existing virter VM to use rather than starting up a new one', - ) - vmSpecsArgGroup.add_argument( - '--vm-provision', - dest='vmProvision', - type=mmguero.str2bool, - nargs='?', - metavar="true|false", - const=True, - default=True, - help=f'Perform VM provisioning', - ) - vmSpecsArgGroup.add_argument( - '--vm-provision-malcolm', - dest='vmProvisionMalcolm', - type=mmguero.str2bool, - nargs='?', - metavar="true|false", - const=True, - default=True, - help=f'Perform VM provisioning (Malcolm-specific)', - ) - vmSpecsArgGroup.add_argument( - '--vm-provision-path', - required=False, - dest='vmProvisionPath', - metavar='', - type=str, - default=os.getenv('VIRTER_PROVISION_PATH', os.path.join(script_path, 'virter')), - help=f'Path containing subdirectories with TOML files for VM provisioning (e.g., {os.path.join(script_path, "virter")})', - ) - vmSpecsArgGroup.add_argument( - '--build-vm', - required=False, - dest='vmBuildName', - metavar='', - type=str, - default=os.getenv('VIRTER_BUILD_VM', ''), - help='The name for a new VM image to build and commit instead of running one', - ) - vmSpecsArgGroup.add_argument( - '--build-vm-keep-layers', - dest='vmBuildKeepLayers', - type=mmguero.str2bool, - nargs='?', - metavar="true|false", - const=True, - default=False, - help=f"Don't remove intermediate layers when building a new VM image", - ) - - configArgGroup = parser.add_argument_group('Malcolm runtime configuration') - configArgGroup.add_argument( - '--container-image-file', - required=False, - dest='containerImageFile', - metavar='', - type=str, - default='', - help='Malcolm container images .tar.xz file for installation (instead of "docker pull")', - ) - configArgGroup.add_argument( - '-s', - '--start', - dest='startMalcolm', - type=mmguero.str2bool, - nargs='?', - metavar="true|false", - const=True, - default=True, - help=f'Start Malcolm once provisioning is complete (default true)', - ) - configArgGroup.add_argument( - '--sleep', - dest='postInitSleep', - required=False, - metavar='', - type=int, - default=30, - help='Seconds to sleep after init before starting Malcolm (default 30)', - ) - - try: - parser.error = parser.exit - args = parser.parse_args() - except SystemExit as e: - mmguero.eprint(f'Invalid argument(s): {e}') - sys.exit(2) - - # configure logging levels based on -v, -vv, -vvv, etc. - args.verbose = logging.CRITICAL - (10 * args.verbose) if args.verbose > 0 else 0 - logging.basicConfig( - level=args.verbose, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' - ) - logging.info(os.path.join(script_path, script_name)) - logging.info("Arguments: {}".format(sys.argv[1:])) - logging.info("Arguments: {}".format(args)) - if args.verbose > logging.DEBUG: - sys.tracebacklimit = 0 - - # the whole thing runs on virter, so if we don't have that what are we even doing here - err, _ = mmguero.RunProcess(['virter', 'version']) - if err != 0: - logging.error(f'{script_name} requires virter, please see https://github.com/LINBIT/virter') - return 1 - - # handle sigint and sigterm for graceful shutdown - signal.signal(signal.SIGINT, shutdown_handler) - signal.signal(signal.SIGTERM, shutdown_handler) - - malcolmVm = MalcolmVM( - args=args, - debug=(args.verbose <= logging.DEBUG), - logger=logging, - ) - try: - if args.vmBuildName: - exitCode = malcolmVm.Build() - else: - exitCode = malcolmVm.Start() - logging.info(json.dumps(malcolmVm.Info())) - malcolmVm.WaitForShutdown() - finally: - del malcolmVm - - logging.info(f'{script_name} returning {exitCode}') - return exitCode - - -################################################################################################### -if __name__ == '__main__': - if main() > 0: - sys.exit(0) - else: - sys.exit(1) diff --git a/src/malcolm_test/virter/debian-12/init/00-system.toml b/src/maltest/virter/debian-12/init/00-system.toml similarity index 100% rename from src/malcolm_test/virter/debian-12/init/00-system.toml rename to src/maltest/virter/debian-12/init/00-system.toml diff --git a/src/malcolm_test/virter/debian-12/init/01-apt-init.toml b/src/maltest/virter/debian-12/init/01-apt-init.toml similarity index 100% rename from src/malcolm_test/virter/debian-12/init/01-apt-init.toml rename to src/maltest/virter/debian-12/init/01-apt-init.toml diff --git a/src/malcolm_test/virter/debian-12/init/02-docker.toml b/src/maltest/virter/debian-12/init/02-docker.toml similarity index 100% rename from src/malcolm_test/virter/debian-12/init/02-docker.toml rename to src/maltest/virter/debian-12/init/02-docker.toml diff --git a/src/malcolm_test/virter/debian-12/init/03-podman.toml b/src/maltest/virter/debian-12/init/03-podman.toml similarity index 100% rename from src/malcolm_test/virter/debian-12/init/03-podman.toml rename to src/maltest/virter/debian-12/init/03-podman.toml diff --git a/src/malcolm_test/virter/malcolm-fini/01-wipe.toml b/src/maltest/virter/malcolm-fini/01-wipe.toml similarity index 100% rename from src/malcolm_test/virter/malcolm-fini/01-wipe.toml rename to src/maltest/virter/malcolm-fini/01-wipe.toml diff --git a/src/malcolm_test/virter/malcolm-init/01-clone-install.toml b/src/maltest/virter/malcolm-init/01-clone-install.toml similarity index 100% rename from src/malcolm_test/virter/malcolm-init/01-clone-install.toml rename to src/maltest/virter/malcolm-init/01-clone-install.toml diff --git a/src/malcolm_test/virter/malcolm-init/02-auth_setup.toml b/src/maltest/virter/malcolm-init/02-auth_setup.toml similarity index 100% rename from src/malcolm_test/virter/malcolm-init/02-auth_setup.toml rename to src/maltest/virter/malcolm-init/02-auth_setup.toml diff --git a/src/malcolm_test/virter/malcolm-init/03-pull.toml b/src/maltest/virter/malcolm-init/03-pull.toml similarity index 100% rename from src/malcolm_test/virter/malcolm-init/03-pull.toml rename to src/maltest/virter/malcolm-init/03-pull.toml diff --git a/src/malcolm_test/virter/malcolm-init/99-reboot.toml b/src/maltest/virter/malcolm-init/99-reboot.toml similarity index 100% rename from src/malcolm_test/virter/malcolm-init/99-reboot.toml rename to src/maltest/virter/malcolm-init/99-reboot.toml