Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package virt-scenario for openSUSE:Factory checked in at 2023-03-17 17:04:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/virt-scenario (Old) and /work/SRC/openSUSE:Factory/.virt-scenario.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "virt-scenario" Fri Mar 17 17:04:11 2023 rev:4 rq:1072452 version:0.7.4 Changes: -------- --- /work/SRC/openSUSE:Factory/virt-scenario/virt-scenario.changes 2023-03-15 18:56:15.232940703 +0100 +++ /work/SRC/openSUSE:Factory/.virt-scenario.new.31432/virt-scenario.changes 2023-03-17 17:04:39.133803557 +0100 @@ -1,0 +2,10 @@ +Thu Mar 16 16:27:50 UTC 2023 - Antoine Ginies <[email protected]> + +- version 0.7.4: + * add virt-scenario-launch (Joerg Roedel): + * tool to launch VMs created by virtscenario and do attestation + for SecureVMs + * rewrite and clean some part of the code + * remove check_container use (no more needed for now) + +------------------------------------------------------------------- Old: ---- virt-scenario-0.7.3.tar.gz New: ---- virt-scenario-0.7.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ virt-scenario.spec ++++++ --- /var/tmp/diff_new_pack.eg9pxi/_old 2023-03-17 17:04:39.673806402 +0100 +++ /var/tmp/diff_new_pack.eg9pxi/_new 2023-03-17 17:04:39.681806444 +0100 @@ -19,7 +19,7 @@ %define pythons python3 Name: virt-scenario -Version: 0.7.3 +Version: 0.7.4 Release: 0 Summary: Create XML guest configuration and prepare the host for a scenario License: GPL-3.0-or-later @@ -70,6 +70,7 @@ %{_bindir}/* %{python_sitelib}/virtscenario %{python_sitelib}/virt_select_firmware +%{python_sitelib}/virtscenario_launch %{python_sitelib}/*.egg-info %attr(0755,root,root) %{_datadir}/%name %{_mandir}/man1/%{name}.1%{ext_man} ++++++ virt-scenario-0.7.3.tar.gz -> virt-scenario-0.7.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/ChangeLog new/virt-scenario-0.7.4/ChangeLog --- old/virt-scenario-0.7.3/ChangeLog 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/ChangeLog 2023-03-16 17:38:01.000000000 +0100 @@ -1,3 +1,89 @@ +2023-03-16 aginies <[email protected]> + + update man page + + +2023-03-16 aginies <[email protected]> + + version 0.7.4 + + +2023-03-16 aginies <[email protected]> + + sync with code + + +2023-03-16 aginies <[email protected]> + + add more bin from package + + +2023-03-16 aginies <[email protected]> + + some pylint fixes + + +2023-03-16 aginies <[email protected]> + + typo + + +2023-03-16 aginies <[email protected]> + + remove loader_type + + +2023-03-16 Antoine Giniès <[email protected]> + + Merge pull request #4 from joergroedel/virtscenario-launch + Virtscenario launch + +2023-03-16 aginies <[email protected]> + + concatenate some code + + +2023-03-16 Joerg Roedel <[email protected]> + + Add virtscenario_launch tool + Add a tool to launch VMs created by virtscenario and do attestation + for SecureVMs. + + + +2023-03-16 Joerg Roedel <[email protected]> + + virtscenario: Set loader and firmware type for securevm + Make sure to include the specific firmware laoder and to specify the + firmware type on the <os/> section of the guest XML configuration. + + + +2023-03-16 aginies <[email protected]> + + use a more comprehensive code for color + + +2023-03-16 aginies <[email protected]> + + various small fixes + + +2023-03-16 aginies <[email protected]> + + remove check_container test as this is possible to this working in privileged mode + + +2023-03-15 aginies <[email protected]> + + fix path to default conf + + +2023-03-15 aginies <[email protected]> + + cosmetic change + + 2023-03-15 aginies <[email protected]> remove unwanted help (already provided by default) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/PKG-INFO new/virt-scenario-0.7.4/PKG-INFO --- old/virt-scenario-0.7.3/PKG-INFO 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/PKG-INFO 2023-03-16 17:38:01.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: virt-scenario -Version: 0.7.3 +Version: 0.7.4 Summary: Virt-scenario Home-page: https://github.com/aginies/virt-scenario Author: Antoine Ginies @@ -80,6 +80,8 @@ ## Get it and use it + ### From source code + **main.py** will create an **xml** based file on template and validate it. Second phase will prepare the host system and create the VM image file. Currently **desktop**, **computation** and **securevm** are available. @@ -92,6 +94,23 @@ > desktop ``` + Tool to select a firmware based on their features: + ``` + python3 -m virt_select_firmware + ``` + + Tool to launch the VM from the config file generated by virt-scenario: + ``` + python3 -m virtscenario-launch + ``` + + #### From Package + + Get the package for your Distribution and install it. For openSUSE, SLE: + + * [devel stable project](https://build.opensuse.org/package/show/Virtualization/virt-scenario) + * [devel unstable](https://build.opensuse.org/package/show/home:aginies/virt-scenario) + ## Default configuration The default configuration for VM definition are: @@ -130,7 +149,7 @@ * **computation**: Create an XML configuration and host config to do computation VM * **desktop**: Create an XML configuration and host config for Desktop VMU - * securevm**: Create an XML configuration and host config for Secure VM + * **securevm**: Create an XML configuration and host config for Secure VM ### Others @@ -194,7 +213,7 @@ # Devel Information - This **WIP**, a lot of changes can occur in current code. + This is still **WIP**, but the code is stable. It needs several cleanup and improvements. ## Devel planning / TODO diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/README.md new/virt-scenario-0.7.4/README.md --- old/virt-scenario-0.7.3/README.md 2023-03-14 17:49:50.000000000 +0100 +++ new/virt-scenario-0.7.4/README.md 2023-03-16 17:25:00.000000000 +0100 @@ -72,6 +72,8 @@ ## Get it and use it +### From source code + **main.py** will create an **xml** based file on template and validate it. Second phase will prepare the host system and create the VM image file. Currently **desktop**, **computation** and **securevm** are available. @@ -84,6 +86,23 @@ > desktop ``` +Tool to select a firmware based on their features: +``` +python3 -m virt_select_firmware +``` + +Tool to launch the VM from the config file generated by virt-scenario: +``` +python3 -m virtscenario-launch +``` + +#### From Package + +Get the package for your Distribution and install it. For openSUSE, SLE: + +* [devel stable project](https://build.opensuse.org/package/show/Virtualization/virt-scenario) +* [devel unstable](https://build.opensuse.org/package/show/home:aginies/virt-scenario) + ## Default configuration The default configuration for VM definition are: @@ -122,7 +141,7 @@ * **computation**: Create an XML configuration and host config to do computation VM * **desktop**: Create an XML configuration and host config for Desktop VMU -* securevm**: Create an XML configuration and host config for Secure VM +* **securevm**: Create an XML configuration and host config for Secure VM ### Others @@ -186,7 +205,7 @@ # Devel Information -This **WIP**, a lot of changes can occur in current code. +This is still **WIP**, but the code is stable. It needs several cleanup and improvements. ## Devel planning / TODO diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/man/virt-scenario.1 new/virt-scenario-0.7.4/man/virt-scenario.1 --- old/virt-scenario-0.7.3/man/virt-scenario.1 2023-03-15 09:01:56.000000000 +0100 +++ new/virt-scenario-0.7.4/man/virt-scenario.1 2023-03-16 17:37:40.000000000 +0100 @@ -97,6 +97,7 @@ .fi .SH Usage .SS Get it and use it +.SS From source code .PP \f[B]main.py\f[R] will create an \f[B]xml\f[R] based file on template and validate it. @@ -113,6 +114,32 @@ > desktop \f[R] .fi +.PP +Tool to select a firmware based on their features: +.IP +.nf +\f[C] +python3 -m virt_select_firmware +\f[R] +.fi +.PP +Tool to launch the VM from the config file generated by virt-scenario: +.IP +.nf +\f[C] +python3 -m virtscenario-launch +\f[R] +.fi +.SS From Package +.PP +Get the package for your Distribution and install it. +For openSUSE, SLE: +.IP \[bu] 2 +devel stable +project (https://build.opensuse.org/package/show/Virtualization/virt-scenario) +.IP \[bu] 2 +devel +unstable (https://build.opensuse.org/package/show/home:aginies/virt-scenario) .SS Default configuration .PP The default configuration for VM definition are: * \f[B]disk path @@ -159,7 +186,8 @@ \f[B]desktop\f[R]: Create an XML configuration and host config for Desktop VMU .IP \[bu] 2 -securevm**: Create an XML configuration and host config for Secure VM +\f[B]securevm\f[R]: Create an XML configuration and host config for +Secure VM .SS Others .IP \[bu] 2 \f[B]shell\f[R]: Execution of a system command @@ -544,7 +572,8 @@ Soft RT VM (latency improvments) .SH Devel Information .PP -This \f[B]WIP\f[R], a lot of changes can occur in current code. +This is still \f[B]WIP\f[R], but the code is stable. +It needs several cleanup and improvements. .SS Devel planning / TODO .IP \[bu] 2 [STRIKEOUT:mechanism to create the Guest XML file from template] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/setup.py new/virt-scenario-0.7.4/setup.py --- old/virt-scenario-0.7.3/setup.py 2023-03-15 08:53:42.000000000 +0100 +++ new/virt-scenario-0.7.4/setup.py 2023-03-16 16:55:25.000000000 +0100 @@ -80,8 +80,7 @@ rm_src_egg="rm -vrf src/*.egg-info/", rm_pycache="rm -vrf src/*/__pycache__/", ) - for _, cmd in cmd_list.items(): - os.system(cmd) + [os.system(cmd) for cmd in cmd_list.values()] class CheckLint(setuptools.Command): """ @@ -172,23 +171,18 @@ os.mkdir("build") if os.path.exists(".git"): - try: - self.gen_changelog() + self.gen_changelog() - sdist.run(self) + sdist.run(self) - finally: - files = ["ChangeLog"] - for item in files: - if os.path.exists(item): - os.unlink(item) - else: - sdist.run(self) + if os.path.exists(".git"): + files = ["ChangeLog"] + [os.unlink(item) for item in files if os.path.exists(item)] setuptools.setup( name="virt-scenario", - version="0.7.3", + version="0.7.4", author="Antoine Ginies", author_email="[email protected]", description="Virt-scenario", @@ -200,7 +194,9 @@ packages=setuptools.find_packages(where="src"), entry_points={ "console_scripts": [ - "virt-scenario=virtscenario.main:main", + "virt-scenario = virtscenario.main:main", + "virt-scenario-launch = virtscenario_launch.main:main", + "virt-select-firmware = virt_select_firmware.main:main", ] }, classifiers=[ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virt_scenario.egg-info/PKG-INFO new/virt-scenario-0.7.4/src/virt_scenario.egg-info/PKG-INFO --- old/virt-scenario-0.7.3/src/virt_scenario.egg-info/PKG-INFO 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virt_scenario.egg-info/PKG-INFO 2023-03-16 17:38:01.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: virt-scenario -Version: 0.7.3 +Version: 0.7.4 Summary: Virt-scenario Home-page: https://github.com/aginies/virt-scenario Author: Antoine Ginies @@ -80,6 +80,8 @@ ## Get it and use it + ### From source code + **main.py** will create an **xml** based file on template and validate it. Second phase will prepare the host system and create the VM image file. Currently **desktop**, **computation** and **securevm** are available. @@ -92,6 +94,23 @@ > desktop ``` + Tool to select a firmware based on their features: + ``` + python3 -m virt_select_firmware + ``` + + Tool to launch the VM from the config file generated by virt-scenario: + ``` + python3 -m virtscenario-launch + ``` + + #### From Package + + Get the package for your Distribution and install it. For openSUSE, SLE: + + * [devel stable project](https://build.opensuse.org/package/show/Virtualization/virt-scenario) + * [devel unstable](https://build.opensuse.org/package/show/home:aginies/virt-scenario) + ## Default configuration The default configuration for VM definition are: @@ -130,7 +149,7 @@ * **computation**: Create an XML configuration and host config to do computation VM * **desktop**: Create an XML configuration and host config for Desktop VMU - * securevm**: Create an XML configuration and host config for Secure VM + * **securevm**: Create an XML configuration and host config for Secure VM ### Others @@ -194,7 +213,7 @@ # Devel Information - This **WIP**, a lot of changes can occur in current code. + This is still **WIP**, but the code is stable. It needs several cleanup and improvements. ## Devel planning / TODO diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virt_scenario.egg-info/SOURCES.txt new/virt-scenario-0.7.4/src/virt_scenario.egg-info/SOURCES.txt --- old/virt-scenario-0.7.3/src/virt_scenario.egg-info/SOURCES.txt 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virt_scenario.egg-info/SOURCES.txt 2023-03-16 17:38:01.000000000 +0100 @@ -35,4 +35,7 @@ src/virtscenario/sev.py src/virtscenario/template.py src/virtscenario/util.py -src/virtscenario/xmlutil.py \ No newline at end of file +src/virtscenario/xmlutil.py +src/virtscenario_launch/__init__.py +src/virtscenario_launch/__main__.py +src/virtscenario_launch/main.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virt_scenario.egg-info/entry_points.txt new/virt-scenario-0.7.4/src/virt_scenario.egg-info/entry_points.txt --- old/virt-scenario-0.7.3/src/virt_scenario.egg-info/entry_points.txt 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virt_scenario.egg-info/entry_points.txt 2023-03-16 17:38:01.000000000 +0100 @@ -1,3 +1,5 @@ [console_scripts] virt-scenario = virtscenario.main:main +virt-scenario-launch = virtscenario_launch.main:main +virt-select-firmware = virt_select_firmware.main:main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virt_scenario.egg-info/top_level.txt new/virt-scenario-0.7.4/src/virt_scenario.egg-info/top_level.txt --- old/virt-scenario-0.7.3/src/virt_scenario.egg-info/top_level.txt 2023-03-15 09:42:14.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virt_scenario.egg-info/top_level.txt 2023-03-16 17:38:01.000000000 +0100 @@ -1,2 +1,3 @@ virt_select_firmware virtscenario +virtscenario_launch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/__init__.py new/virt-scenario-0.7.4/src/virtscenario/__init__.py --- old/virt-scenario-0.7.3/src/virtscenario/__init__.py 2023-03-15 08:53:31.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/__init__.py 2023-03-16 17:25:48.000000000 +0100 @@ -30,4 +30,4 @@ builtins.__dict__["_"] = str -__version__ = "0.7.3" +__version__ = "0.7.4" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/configstore.py new/virt-scenario-0.7.4/src/virtscenario/configstore.py --- old/virt-scenario-0.7.3/src/virtscenario/configstore.py 2023-03-07 14:36:03.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/configstore.py 2023-03-16 16:20:43.000000000 +0100 @@ -18,6 +18,8 @@ """ import os +import ast +import xml.etree.ElementTree as ET import yaml import virtscenario.util as util @@ -26,6 +28,9 @@ name = None hypervisor = None attestation = False + tik_file = "" + tek_file = "" + policy = 0 def __init__(self, base_path="./"): self.base_path = base_path @@ -76,6 +81,41 @@ with open(filename, 'w') as config_yaml: yaml.dump(config, config_yaml) + def load_config(self, vmname): + filename = self.base_path + "/" + vmname + "/config.yaml" + if not os.path.isfile(filename): + print("VM {} not found".format(vmname)) + return None + with open(filename, 'r') as file: + data = yaml.full_load(file) + for key, value in data.items(): + if key == 'name': + self.name = value + elif key == 'host': + self.hypervisor = value + elif key == 'domain-config': + self.domain_config = value + elif key == 'attestation' and value is True: + self.attestation = True + + if self.attestation is True and os.path.isfile(self.domain_config): + xmlroot = ET.parse(self.domain_config) + elem = xmlroot.findall("./launchSecurity[@type='sev']/policy") + if elem is None: + print("Failed to load SEV policy from {} - disabling attestation".format(self.domain_config)) + self.attestation = False + return self + + self.policy = ast.literal_eval(elem[0].text) + self.tik_file = self.base_path + "/" + vmname + "/tik.bin" + self.tek_file = self.base_path + "/" + vmname + "/tek.bin" + + return self + + def sev_validate_params(self): + params = "--tik {} --tek {} --policy {} --domain {}".format(self.tik_file, self.tek_file, str(self.policy), self.name) + return params + def create_config_store(config, vm_data, hypervisor, overwrite): cfg_store = ConfigStore(config.vm_config_store) cfg_store.initialize(vm_data.name['VM_name'], hypervisor) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/configuration.py new/virt-scenario-0.7.4/src/virtscenario/configuration.py --- old/virt-scenario-0.7.3/src/virtscenario/configuration.py 2023-03-08 10:16:13.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/configuration.py 2023-03-16 16:14:37.000000000 +0100 @@ -17,6 +17,19 @@ configure dict with data to use to create the XML config """ +def configure_memory(unit, max_memory, memory, pinned): + """ + memory to use + """ + memory_data = { + 'mem_unit': unit.mem_unit, + 'max_memory': max_memory, + 'current_mem_unit': unit.current_mem_unit, + 'memory': memory, + 'pin': pinned, + } + return memory_data + class BasicConfiguration: """ Basic configuration class @@ -141,15 +154,11 @@ return self.emulator_data def memory(self, unit, max_memory, memory): - """ - memory to use - """ - self.memory_data = { - 'mem_unit': unit.mem_unit, - 'max_memory': max_memory, - 'current_mem_unit': unit.current_mem_unit, - 'memory': memory, - } + self.memory_data = configure_memory(unit, max_memory, memory, False) + return self.memory_data + + def memory_pinned(self, unit, max_memory, memory): + self.memory_data = configure_memory(unit, max_memory, memory, True) return self.memory_data def osdef(self, arch, machine, boot_dev): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/guest.py new/virt-scenario-0.7.4/src/virtscenario/guest.py --- old/virt-scenario-0.7.3/src/virtscenario/guest.py 2023-03-08 10:29:49.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/guest.py 2023-03-16 16:14:37.000000000 +0100 @@ -64,7 +64,20 @@ 'current_mem_unit': memory_data['current_mem_unit'], 'memory': memory_data['memory'], } + xml = Template(xml_template).substitute(xml_mem) + + if memory_data['pin'] == True: + memory = int(memory_data['memory']) + if memory_data['mem_unit'] == 'Gib': + memory = memory * 1024 + elif memory_data['mem_unit'] == 'Kib': + memory = memory / 1024 + memory = memory + 256 + memtune_template = template.MEMTUNE_TEMPLATE + xml_memtune = { 'pinned': str(memory) } + xml = xml + Template(memtune_template).substitute(xml_memtune) + return xml def create_cpu(cpu_data): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/host.py new/virt-scenario-0.7.4/src/virtscenario/host.py --- old/virt-scenario-0.7.3/src/virtscenario/host.py 2023-03-14 18:02:13.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/host.py 2023-03-16 11:29:06.000000000 +0100 @@ -24,7 +24,6 @@ import virtscenario.template as template import virtscenario.util as util import virtscenario.sev as sev -import virtscenario.xmlutil as xmlutil def create_net_xml(file, net_data): """ @@ -190,13 +189,11 @@ """ enable sev on the system """ - if check_in_container() is True: - print("Create: /etc/modprobe.d/sev.conf") - print("options mem_encrypt=on kvm_amd sev=1 sev_es=1") - else: - sevconf = open("/etc/modprobe.d/sev.conf", "w") - sevconf.write("options mem_encrypt=on kvm_amd sev=1 sev_es=1") - sevconf.close() + print("Create: /etc/modprobe.d/sev.conf") + print("options mem_encrypt=on kvm_amd sev=1 sev_es=1") + sevconf = open("/etc/modprobe.d/sev.conf", "w") + sevconf.write("options mem_encrypt=on kvm_amd sev=1 sev_es=1") + sevconf.close() def hugepages_enable(num_hugepages=512): """ @@ -204,37 +201,31 @@ reserve 1 GB (1,048,576 KB) for your VM Guest (2M hugepages) """ hpconf = "/etc/sysctl.d/hugepages.conf" - if check_in_container() is True: - print("Create: /etc/sysctl.d/hugepages.conf") - print("sysctl vm.nr_hugepages="+num_hugepages) + if os.path.isfile(hpconf): + print(hpconf+" Already exist") + return True else: - if os.path.isfile(hpconf): - print(hpconf+" Already exist") - return True - else: - print("Creating "+hpconf) - fdhp = open(hpconf, "w") - fdhp.write("vm.nr_hugepages"+num_hugepages) - fdhp.close() - out, errs = util.system_command("sysctl vm.nr_hugepages="+num_hugepages) - util.print_summary("\nSetting vm.nr_hugepages="+num_hugepages) - if errs: - print(errs) - print(out) + print("Creating "+hpconf) + fdhp = open(hpconf, "w") + fdhp.write("vm.nr_hugepages"+num_hugepages) + fdhp.close() + out, errs = util.system_command("sysctl vm.nr_hugepages="+num_hugepages) + util.print_summary("\nSetting vm.nr_hugepages="+num_hugepages) + if errs: + print(errs) + print(out) def reprobe_kvm_amd_module(): """ reload the module """ cmd = "modprobe -vr kvm_amd ; modprobe -v kvm_amd" - if check_in_container() is True: - print(cmd) - else: - out, errs = util.system_command(cmd) - util.print_summary("\nReprobe the KVM module") - if errs: - print(errs) - print(out) + out, errs = util.system_command(cmd) + util.print_summary("\nReprobe the KVM module") + print(cmd) + if errs: + print(errs) + print(out) def manage_ksm(todo, merge_across): """ @@ -244,28 +235,34 @@ if os.path.isdir("/sys/kernel/mm/ksm"): if todo == "enable": action = "start" + number = "1" else: action = "stop" - cmd1 = "systemctl "+todo+" ksm" - cmd2 = "systemctl "+action+" ksm" + number = "0" + if os.path.isfile("/usr/lib/systemd/system/ksm.service"): + cmd1 = "systemctl "+todo+" ksm" + cmd2 = "systemctl "+action+" ksm" + else: + cmd1 = cmd2 = "" + # do it manually + cmd4 = "/bin/echo "+number+" > /sys/kernel/mm/ksm/run" + if merge_across == "enable": cmd3 = "echo 1 > /sys/kernel/mm/ksm/merge_across_nodes" elif merge_across == "disable": cmd3 = "echo 0 > /sys/kernel/mm/ksm/merge_across_nodes" else: cmd3 = "" - if check_in_container() is True: - for cmds in [cmd1, cmd2, cmd3]: - print(cmds) + + for cmds in [cmd1, cmd2, cmd3, cmd4]: + cmds != "" and print(cmds) + out, errs = util.system_command(cmds) + if errs: + print(str(errs)+" "+str(out)) + if todo == "enable": + print("KSM enabled") else: - for cmds in [cmd1, cmd2, cmd3]: - out, errs = util.system_command(cmds) - if errs: - print(str(errs)+" "+str(out)) - if todo == "enable": - print("KSM enabled") - else: - print("KSM disabled") + print("KSM disabled") else: print("KSM not available on this system") @@ -277,14 +274,11 @@ #echo 35 > /proc/sys/vm/swappiness #/etc/systcl.conf #vm.swappiness = 35 - cmd = "echo "+number+"> /proc/sys/vm/swappiness" - if check_in_container() is True: - print(cmd) - else: - out, errs = util.system_command(cmd) - if errs: - print(str(errs)+" "+str(out)) - print(cmd) + cmd = "echo "+number+" > /proc/sys/vm/swappiness" + out, errs = util.system_command(cmd) + print(cmd) + if errs: + print(str(errs)+" "+str(out)) def list_all_disk(): """ @@ -307,15 +301,11 @@ listdisk = list_all_disk() cmdstart = "echo "+scheduler+" > /sys/block" cmdend = "/queue/scheduler" - if check_in_container() is True: - for disk in listdisk: - print(cmdstart+disk+cmdend) - else: - for disk in listdisk: - out, errs = util.system_command(cmdstart+disk+cmdend) - if errs: - print(str(errs)+" "+str(out)) - print(cmdstart+disk+cmdend) + for disk in listdisk: + print(cmdstart+disk+cmdend) + out, errs = util.system_command(cmdstart+disk+cmdend) + if errs: + print(str(errs)+" "+str(out)) print("\nRecommended IO Scheduler inside VM guest is 'none'") def kvm_amd_sev(sev_info): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/hypervisors.py new/virt-scenario-0.7.4/src/virtscenario/hypervisors.py --- old/virt-scenario-0.7.3/src/virtscenario/hypervisors.py 2023-02-28 14:38:47.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/hypervisors.py 2023-03-16 16:22:17.000000000 +0100 @@ -18,8 +18,8 @@ """ import os -import libvirt import yaml +import libvirt import virtscenario.util as util @@ -53,6 +53,23 @@ def domain_capabilities(self): return self.conn.getDomainCapabilities() + def dominfo(self, name): + try: + return self.conn.lookupByName(name) + except libvirt.libvirtError: + return None + + def define_domain(self, xmlfile): + file = open(xmlfile, 'r') + xml = file.read() + file.close() + + try: + dom = self.conn.defineXML(xml) + except libvirt.libvirtError as e: + print(repr(e)) + return + def has_sev_cert(self): return self.sev_cert is not None @@ -107,6 +124,15 @@ selected = '*' print(" {} {}".format(selected, hyperv.name)) +def get_hypervisor(name): + global HV_LIST + + for hyperv in HV_LIST: + if hyperv.name == name: + return hyperv + + return None + def set_default_hv(name): global HV_LIST global HV_SELECTED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/main.py new/virt-scenario-0.7.4/src/virtscenario/main.py --- old/virt-scenario-0.7.3/src/virtscenario/main.py 2023-03-15 09:16:30.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/main.py 2023-03-16 16:16:30.000000000 +0100 @@ -117,8 +117,8 @@ """ show the virsh define command """ - util.print_summary_ok("\nHow to use this on your system") - util.print_ok("\nvirsh define "+filename+"\n") + util.print_summary_ok("How to use this on your system") + util.print_ok("virsh define "+filename+"\n") def find_ext_file(ext): """ @@ -196,23 +196,24 @@ audio = usb = disk = features = clock = network = filename = tpm = iothreads = "" callsign = custom = security = video = controller = hugepages = toreport = "" loader = config = fw_info = vm_config = "" + memory_pin = False # prompt Cmd prompt = 'virt-scenario > ' introl = {} - introl[0] = "\n"+util.esc('32;1;1') +" virt-scenario "+util.esc(0)+ "Interactive Terminal!\n\n" - introl[1] = " Setting the virt-scenario Configuration: "+util.esc('34;1;1')+"conf"+util.esc(0)+"\n" - introl[2] = " Guest/Host/Both mode could be selected using: "+util.esc('34;1;1')+"mode"+util.esc(0)+"\n" - introl[3] = " Force overwrite previous setting: "+util.esc('34;1;1')+"overwrite"+util.esc(0)+"\n" + introl[0] = "\n"+util.esc('green') +" virt-scenario "+util.esc('reset')+ "Interactive Terminal!\n\n" + introl[1] = " Setting the virt-scenario Configuration: "+util.esc('blue')+"conf"+util.esc('reset')+"\n" + introl[2] = " Guest/Host/Both mode could be selected using: "+util.esc('blue')+"mode"+util.esc('reset')+"\n" + introl[3] = " Force overwrite previous setting: "+util.esc('blue')+"overwrite"+util.esc('reset')+"\n" introl[4] = "\n Prepare a Libvirt XML guest config and the host to run a customized guest:\n" - introl[5] = util.esc('34;1;1')+" computation | desktop | securevm"+util.esc(0)+"\n" + introl[5] = util.esc('blue')+" computation | desktop | securevm"+util.esc('reset')+"\n" introl[6] = "\n Possible User Settings For VM are:\n" - introl[7] = util.esc('34;1;1')+" name | vcpu | memory | machine | bootdev | diskpath | cdrom"+util.esc(0)+"\n" + introl[7] = util.esc('blue')+" name | vcpu | memory | machine | bootdev | diskpath | cdrom"+util.esc('reset')+"\n" introl[8] = "\n Hypervisors parameters:\n" - introl[9] = util.esc('34;1;1')+" hconf | hv_select | hvlist"+util.esc(0)+"\n" + introl[9] = util.esc('blue')+" hconf | hv_select | hvlist"+util.esc('reset')+"\n" introl[10] = "\n"+" You can overwrite some recommended VM settings editing: "+conffile+"\n" introl[11] = "\n Please read the manpage and the README.md file:\n" introl[12] = " https://github.com/aginies/virt-scenario/blob/main/README.md\n" - introl[13] = util.esc('31;1;1')+"\n WARNING:"+util.esc(0)+" This is under Devel...\n" + introl[13] = util.esc('red')+"\n WARNING:"+util.esc('reset')+" This is under Devel...\n" introl[14] = " Source code: https://github.com/aginies/virt-scenario\n" introl[15] = " Report bug: https://github.com/aginies/virt-scenario/issues\n" intro = '' @@ -261,12 +262,15 @@ # show which configuration is used by default line1 = line2 = "" if os.path.isfile(conffile): - line1 = util.esc('32;1;1')+'Main Configuration: '+util.esc(0)+conffile+'\n' + line1 = util.esc('green')+'Main Configuration: '+util.esc('reset')+conffile+'\n' if os.path.isfile(hvfile): - line2 = util.esc('32;1;1')+'Hypervisor Configuration: '+util.esc(0)+hvfile+'\n' + line2 = util.esc('green')+'Hypervisor Configuration: '+util.esc('reset')+hvfile+'\n' prompt = promptline+line1+line2+'\n'+'> ' + def set_memory_pin(self, value): + self.memory_pin = value + def check_user_settings(self, virtum): """ Check if the user as set some stuff, if yes use it @@ -296,6 +300,7 @@ 'max_memory': memoryuser, 'current_mem_unit': 'Gib', 'memory': memoryuser, + 'pin': virtum.memory_pin, }) else: self.memory = guest.create_memory(virtum.memory) @@ -308,7 +313,7 @@ self.listosdef.update({'boot_dev': bootdevuser}) self.osdef = guest.create_osdef(self.listosdef) - cdrom = self.dataprompt.get('cdrom') + cdrom = self.dataprompt.get('dvd') if cdrom != None: self.cdrom = guest.create_cdrom({'source_file': cdrom}) @@ -320,83 +325,34 @@ """ update prompt with value set by user """ - line1 = line2 = line3 = line4 = line5 = line6 = line7 = line8 = line9 = line10 = line11 = "" + options = [('Name', 'name'), + ('Vcpu', 'vcpu'), + ('Memory', 'memory'), + ('Machine Type', 'machine'), + ('Boot Device', 'bootdev'), + ('Disk Path', 'path'), + ('Main Configuration', 'mainconf'), + ('Hypervisor Configuration', 'hvconf'), + ('Hypervisor Selected', 'hvselected'), + ('Overwrite', 'overwrite'), + ('CD/DVD File ', 'dvd'), + ] + + lines = [] self.promptline = '---------- User Settings ----------\n' - # update prompt with all values - name = self.dataprompt.get('name') - if name != None: - line1 = util.esc('32;1;1')+'Name: '+util.esc(0)+name+'\n' - - vcpu = self.dataprompt.get('vcpu') - if vcpu != None: - line2 = util.esc('32;1;1')+'Vcpu: '+util.esc(0)+vcpu+'\n' - - memory = self.dataprompt.get('memory') - if memory != None: - line3 = util.esc('32;1;1')+'Memory: '+util.esc(0)+memory+' Gib\n' - - machine = self.dataprompt.get('machine') - if machine != None: - line4 = util.esc('32;1;1')+'Machine Type: '+util.esc(0)+machine+'\n' - - bootdev = self.dataprompt.get('bootdev') - if bootdev != None: - line5 = util.esc('32;1;1')+'Boot Device: '+util.esc(0)+bootdev+'\n' - - diskpath = self.dataprompt.get('path') - if diskpath != None: - line6 = util.esc('32;1;1')+'Disk Path: '+util.esc(0)+diskpath+'\n' - - mainconf = self.dataprompt.get('mainconf') - if mainconf != None: - line7 = util.esc('32;1;1')+'Main Configuration: '+util.esc(0)+mainconf+'\n' - - hvconf = self.dataprompt.get('hvconf') - if hvconf != None: - line8 = util.esc('32;1;1')+'Hypervisor Configuration: '+util.esc(0)+hvconf+'\n' - - hvselected = self.dataprompt.get('hvselected') - if hvselected != None: - line9 = util.esc('32;1;1')+'Hypervisor Selected: '+util.esc(0)+hvselected+'\n' + for option_name, option_key in options: + option_value = self.dataprompt.get(option_key) + if option_value is not None: + line = util.esc('green') + option_name + ': ' + util.esc('reset') + option_value + '\n' + if option_key == 'dvd': + self.dataprompt.update({'bootdev': 'cdrom'}) + # append to the main line + lines.append(line) - overwrite = self.dataprompt.get('overwrite') - if overwrite != None: - line10 = util.esc('32;1;1')+'Overwrite: '+util.esc(0)+overwrite+'\n' + output = ''.join(lines) - cdrom = self.dataprompt.get('cdrom') - if cdrom != None: - line11 = util.esc('32;1;1')+'CD/DVD File: '+util.esc(0)+cdrom+'\n' - # switch to bootdev cdrom if an iso is selected - bootdev = "cdrom" - line5 = util.esc('32;1;1')+'Boot Device: '+util.esc(0)+bootdev+'\n' - self.dataprompt.update({'bootdev': bootdev}) - - if args == 'name': - self.dataprompt.update({'name': name}) - if args == 'vcpu': - self.dataprompt.update({'vcpu': vcpu}) - if args == 'memory': - self.dataprompt.update({'memory': memory}) - if args == 'machine': - self.dataprompt.update({'machine': machine}) - if args == 'bootdev': - self.dataprompt.update({'bootdev': bootdev}) - if args == 'diskpath': - self.dataprompt.update({'path': diskpath}) - if args == 'mainconf': - self.dataprompt.update({'config': mainconf}) - if args == 'hvconf': - self.dataprompt.update({'config': hvconf}) - if args == 'hvselected': - self.dataprompt.update({'config': hvselected}) - if args == 'overwrite': - self.dataprompt.update({'overwrite': overwrite}) - if args == 'cdrom': - self.dataprompt.update({'cdrom': cdrom}) - - self.prompt = self.promptline+line7+line8+line9+line10+line1 - self.prompt += line2+line3+line4+line5+line11+line6+'\n'+'> ' + self.prompt = self.promptline+output+'\n'+'> ' def check_conffile(self): """ @@ -910,6 +866,9 @@ self.callsign = securevm.name['VM_name'] self.name = guest.create_name(securevm.name) + # Configure VM with pinned memory + self.set_memory_pin(True) + # Check user setting self.check_user_settings(securevm) @@ -955,6 +914,7 @@ firmware = fw.find_firmware(self.fw_info, arch=self.listosdef['arch'], features=fw_features, interface='uefi') if firmware: + self.custom = ["loader"] self.loader = firmware # XML File path @@ -1095,11 +1055,11 @@ """ file = args if os.path.isfile(file): - cdrom = { + dvd = { 'source_file': file, } - self.dataprompt.update({'cdrom': cdrom['source_file']}) - self.update_prompt(cdrom['source_file']) + self.dataprompt.update({'dvd': dvd['source_file']}) + self.update_prompt(dvd['source_file']) else: util.print_error("CDROM/DVD ISO source file " +file +" Doesnt exist!") @@ -1236,7 +1196,7 @@ Shorthand: Ctrl-D """ # French Flag :) - print(util.esc('44')+'Bye'+util.esc('107')+'Bye'+util.esc('41')+'Bye'+util.esc(0)) + print(util.esc('blue')+'Bye'+util.esc('white')+'Bye'+util.esc('red')+'Bye'+util.esc('reset')) return True do_EOF = do_quit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/scenario.py new/virt-scenario-0.7.4/src/virtscenario/scenario.py --- old/virt-scenario-0.7.3/src/virtscenario/scenario.py 2023-03-06 17:59:04.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/scenario.py 2023-03-16 16:14:37.000000000 +0100 @@ -149,7 +149,7 @@ self.tpm = c.ComplexConfiguration.tpm_emulated(self, "tpm-crb", "emulator", "2.0") # memory unit = f.MemoryUnit("Gib", "Gib") - self.memory = c.BasicConfiguration.memory(self, unit, "4", "4") + self.memory = c.BasicConfiguration.memory_pinned(self, unit, "4", "4") # vcpu self.vcpu = c.BasicConfiguration.vcpu(self, "2") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/template.py new/virt-scenario-0.7.4/src/virtscenario/template.py --- old/virt-scenario-0.7.3/src/virtscenario/template.py 2023-03-08 11:04:04.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/template.py 2023-03-16 16:14:37.000000000 +0100 @@ -64,6 +64,9 @@ <memory unit='${mem_unit}'>${max_memory}</memory> <currentMemory unit='${current_mem_unit}'>${memory}</currentMemory>""" +MEMTUNE_TEMPLATE = """ + <memtune><hard_limit unit="MiB">${pinned}</hard_limit></memtune>""" + CPU_TEMPLATE = """ <vcpu placement='static'>${vcpu}</vcpu>""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/util.py new/virt-scenario-0.7.4/src/virtscenario/util.py --- old/virt-scenario-0.7.3/src/virtscenario/util.py 2023-03-07 14:44:12.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/util.py 2023-03-16 12:24:50.000000000 +0100 @@ -38,27 +38,49 @@ """ return shutil.which(cmd) is not None -def esc(code): +COLORS = { + 'reset': '\033[0m', + 'black': '\033[30m', + 'red': '\033[31m', + 'green': '\033[32m', + 'yellow': '\033[33m', + 'blue': '\033[34m', + 'purple': '\033[35m', + 'cyan': '\033[36m', + 'white': '\033[37m', + 'bg_black': '\033[40m', + 'bg_red': '\033[41m', + 'bg_green': '\033[42m', + 'bg_yellow': '\033[43m', + 'bg_blue': '\033[44m', + 'bg_purple': '\033[45m', + 'bg_cyan': '\033[46m', + 'bg_white': '\033[47m', +} + +def esc(color): """ - Better layout with some color + Return the ANSI escape code for the given color """ - # foreground: 31:red 32:green 34:blue 36:cyan - # background: 41:red 44:blue 107:white - # 0:reset - return f'\033[{code}m' + return COLORS[color] def print_error(text): """ Print error in red """ - formated_text = esc('31;1;1')+text+esc(0) + color = esc('red') + reset = esc('reset') + #print('{color}{text}{reset}'.format(color=color, text=text, reset=reset)) + prefix = esc('bg_yellow') + ' ERROR ' + reset + " " + formated_text = prefix+color+text+reset print(formated_text) def print_warning(text): """ Print warning in red """ - formated_text = "\n "+esc('31;1;1') +text.upper()+esc(0)+"\n" + prefix = esc('bg_yellow') + ' WARNING ' + reset + " " + formated_text = "\n "+prefix+esc('red') +text.upper()+esc('reset')+"\n" print(formated_text) def print_recommended(toreport): @@ -77,35 +99,35 @@ """ Print ok in green """ - formated_text = esc('32;1;1')+text+esc(0) + formated_text = esc('green')+text+esc('reset') print(formated_text) def print_title(text): """ Print title with blue background """ - formated_text = "\n"+esc('104;1;1')+text+esc(0) + formated_text = "\n"+esc('bg_blue')+text+esc('reset') print(formated_text) def print_summary(text): """ Print title with magenta background """ - formated_text = esc('45;1;1')+text.upper()+esc(0) + formated_text = esc('bg_purple')+text.upper()+esc('reset') print(formated_text) def print_summary_ok(text): """ Print title with green background """ - formated_text = esc('42;1;1')+text+esc(0)+"\n" + formated_text = esc('bg_green')+text+esc('reset')+"\n" print(formated_text) def print_data(data, value): """ Print the data """ - formated_text = "\n"+esc('101;1;1')+data+" "+esc(0)+" "+value.rstrip() + formated_text = "\n"+esc('bg_cyan')+data+" "+esc('reset')+" "+value.rstrip() print(formated_text.strip()) def generate_mac_address() -> str: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario/xmlutil.py new/virt-scenario-0.7.4/src/virtscenario/xmlutil.py --- old/virt-scenario-0.7.3/src/virtscenario/xmlutil.py 2023-03-08 10:22:00.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario/xmlutil.py 2023-03-16 16:15:19.000000000 +0100 @@ -43,6 +43,7 @@ root = tree.getroot() osdef = root.find('os') + # python >= 3.9 #ET.indent(root, space=' ', level=0) # Create a new 'loader' element and set its properties diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario.yaml new/virt-scenario-0.7.4/src/virtscenario.yaml --- old/virt-scenario-0.7.3/src/virtscenario.yaml 2023-03-14 17:49:10.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario.yaml 2023-03-15 11:41:18.000000000 +0100 @@ -3,7 +3,7 @@ # This will overwrite Scenario settings... config: - - path: /etc/virtscenario + - path: /etc/virt-scenario - vm-config-store: ~/.local/virtscenario/ #hypervisors: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario_launch/__init__.py new/virt-scenario-0.7.4/src/virtscenario_launch/__init__.py --- old/virt-scenario-0.7.3/src/virtscenario_launch/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario_launch/__init__.py 2023-03-16 16:14:37.000000000 +0100 @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Authors: Joerg Roedel <[email protected]> + +# This program 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 2 of the License, or +# (at your option) any later version. + +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# vim: ts=4 sw=4 et + +""" +virt_scenario_launch +""" + +__version__ = "0.0.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario_launch/__main__.py new/virt-scenario-0.7.4/src/virtscenario_launch/__main__.py --- old/virt-scenario-0.7.3/src/virtscenario_launch/__main__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario_launch/__main__.py 2023-03-16 16:14:37.000000000 +0100 @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Authors: Joerg Roedel <[email protected]> + +# This program 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 2 of the License, or +# (at your option) any later version. + +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# vim: ts=4 sw=4 et + +""" +Main +""" + +import virtscenario_launch.main as m + +if __name__ == "__main__": + try: + m.main() + except KeyboardInterrupt: + print('Interrupted') + exit(1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-0.7.3/src/virtscenario_launch/main.py new/virt-scenario-0.7.4/src/virtscenario_launch/main.py --- old/virt-scenario-0.7.3/src/virtscenario_launch/main.py 1970-01-01 01:00:00.000000000 +0100 +++ new/virt-scenario-0.7.4/src/virtscenario_launch/main.py 2023-03-16 16:28:10.000000000 +0100 @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# Authors: Joerg Roedel <[email protected]> + +# This program 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 2 of the License, or +# (at your option) any later version. + +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# vim: ts=4 sw=4 et +""" +Main +""" + +import os +import argparse +import yaml +import libvirt +import virtscenario.hypervisors as hv +import virtscenario.configstore as cs +import virtscenario.main as vsmain +import virtscenario.util as util + +def get_arg_parse(): + parser = argparse.ArgumentParser(description='Perform SEV guest attestation and launch guest') + parser.add_argument('--list', help='List domain configurations', action='store_true') + parser.add_argument('--start', help='Start domain') + parser.add_argument('--status', help='Check domain status') + parser.add_argument('--off', help="Shutdown domain") + parser.add_argument('--force', '-f', help="Force domain off", action="store_true") + return parser + +def parse_command_line(): + return get_arg_parse().parse_args() +class VMConfigs: + """ + VM Configurations + """ + conf_file = "" + base_path = "./" + def __init__(self): + self.conf_file = vsmain.find_conffile() + self.get_base_path() + + def get_base_path(self): + with open(self.conf_file) as file: + data = yaml.full_load(file) + for item, value in data.items(): + if item == "config": + for subitem in value: + for k2, v2 in subitem.items(): + if k2 == 'vm-config-store': + self.base_path = os.path.expanduser(v2) + + def list_vms(self): + vm_array = [] + for vmname in os.listdir(self.base_path): + filename = self.base_path + "/" + vmname + "/config.yaml" + if os.path.isfile(filename): + vm_array.append(vmname) + + return vm_array + + def load_vm(self, vmname): + config = cs.ConfigStore(self.base_path) + return config.load_config(vmname) + +def list_vms(): + configs = VMConfigs() + + print("Available VMs:") + for vmname in configs.list_vms(): + print(" {}".format(vmname)) + +def validate_vm(vm): + if not vm.attestation: + return True + + params = vm.sev_validate_params() + # TODO fix --insecure when client/server split is ready + cmd = "virt-qemu-sev-validate --insecure {}".format(params) + + out, errs = util.system_command(cmd) + if errs or not out: + print(errs) + return False + + ret = out.find("OK: Looks good to me") + if ret == -1: + return False + + print("SEV(-ES) attestation passed!") + return True + +def launch_vm(name): + hvfile = vsmain.find_hvfile() + hv.load_hypervisors(hvfile) + + configs = VMConfigs() + vm = configs.load_vm(name) + + if vm is None: + print("Configuration for domain {} not found".format(name)) + return + + hypervisor = hv.get_hypervisor(vm.hypervisor) + if hypervisor is None: + print("Hypervisor {} not found!".format(vm.hypervisor)) + return + + hypervisor.connect() + if not hypervisor.is_connected(): + print("Failed to connect to hypervisor {}".format(vm.hypervisor)) + return + + dom = hypervisor.dominfo(name) + if dom is None: + hypervisor.define_domain(vm.domain_config) + dom = hypervisor.dominfo(name) + + state, _ = dom.state() + if state != libvirt.VIR_DOMAIN_RUNNING and state != libvirt.VIR_DOMAIN_PAUSED: + # Launch domain in paused state + if dom.createWithFlags(libvirt.VIR_DOMAIN_START_PAUSED) < 0: + print("Failed to start domain '{}'".format(name)) + elif state == libvirt.VIR_DOMAIN_RUNNING: + print("Domain {} already running".format(name)) + else: + print("Domain {} in an unsupported state - please shut it down first".format(name)) + return + + state, _ = dom.state() + + if validate_vm(vm) is False: + print("Validation failed for domain {} - shutting down".format(name)) + dom.destroy() + return + + print("Validation successfull for domain {}".format(name)) + + if state == libvirt.VIR_DOMAIN_PAUSED: + dom.resume() + +def status_vm(name): + hvfile = vsmain.find_hvfile() + hv.load_hypervisors(hvfile) + + configs = VMConfigs() + vm = configs.load_vm(name) + + if vm is None: + print("Configuration for domain {} not found".format(name)) + return + + hypervisor = hv.get_hypervisor(vm.hypervisor) + if hypervisor is None: + print("Hypervisor {} not found!".format(vm.hypervisor)) + return + + hypervisor.connect() + if not hypervisor.is_connected(): + print("Failed to connect to hypervisor {}".format(vm.hypervisor)) + return + + dom = hypervisor.dominfo(name) + if dom is None: + print("No such domain {}".format(name)) + return + + state, reason = dom.state() + if state == libvirt.VIR_DOMAIN_NOSTATE: + state_str = "No state" + elif state == libvirt.VIR_DOMAIN_RUNNING: + state_str = "Running" + elif state == libvirt.VIR_DOMAIN_BLOCKED: + state_str = "Blocked" + elif state == libvirt.VIR_DOMAIN_PAUSED: + state_str = "Paused" + elif state == libvirt.VIR_DOMAIN_SHUTDOWN: + state_str = "Shutdown" + elif state == libvirt.VIR_DOMAIN_SHUTOFF: + state_str = "Shutoff" + elif state == libvirt.VIR_DOMAIN_CRASHED: + state_str = "Crashed" + elif state == libvirt.VIR_DOMAIN_PMSUSPENDED: + state_str = "PM suspend" + else: + state_str = "Unknown" + + print("Domain {} state: {}".format(name, state_str)) + + if state == libvirt.VIR_DOMAIN_RUNNING or state == libvirt.VIR_DOMAIN_PAUSED: + if validate_vm(vm) is False: + print("Validation failed for domain {}".format(name)) + return + + print("Validation successfull for domain {}".format(name)) + + return + +def shutdown_vm(name): + global FORCE + + hvfile = vsmain.find_hvfile() + hv.load_hypervisors(hvfile) + + configs = VMConfigs() + vm = configs.load_vm(name) + + if vm is None: + print("Configuration for domain {} not found".format(name)) + return + + hypervisor = hv.get_hypervisor(vm.hypervisor) + if hypervisor is None: + print("Hypervisor {} not found!".format(vm.hypervisor)) + return + + hypervisor.connect() + if not hypervisor.is_connected(): + print("Failed to connect to hypervisor {}".format(vm.hypervisor)) + return + + dom = hypervisor.dominfo(name) + if dom is None: + print("No such domain {}".format(name)) + return + + state, _ = dom.state() + if state == libvirt.VIR_DOMAIN_RUNNING or state == libvirt.VIR_DOMAIN_PAUSED: + # Shutdown domain + if FORCE is True: + print("Forcing domain {} off".format(name)) + dom.destroy() + else: + print("Shutting domain {} down".format(name)) + dom.shutdown() + else: + print("Domain {} in an unsupported state - please use virsh".format(name)) + return + +FORCE = False + +def main(): + """ + Main; use arg to display mathings firmwares + """ + global FORCE + + args = parse_command_line() + if args.force: + FORCE = True + if args.list: + list_vms() + elif args.start: + launch_vm(args.start) + elif args.status: + status_vm(args.status) + elif args.off: + shutdown_vm(args.off) + else: + get_arg_parse().print_help()
