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-06-14 16:31:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/virt-scenario (Old) and /work/SRC/openSUSE:Factory/.virt-scenario.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "virt-scenario" Wed Jun 14 16:31:46 2023 rev:16 rq:1093133 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/virt-scenario/virt-scenario.changes 2023-06-07 23:08:38.659769216 +0200 +++ /work/SRC/openSUSE:Factory/.virt-scenario.new.15902/virt-scenario.changes 2023-06-14 16:32:49.555754069 +0200 @@ -1,0 +2,14 @@ +Wed Jun 14 12:45:39 UTC 2023 - Antoine Ginies <agin...@suse.com> + +- version 2.1.0: + * various fixes around hypervisor selection + * force hypervisor selection before choosing machine type or virtual net + * use machine list from the hypervisor capabilities (remove hardcoded list) + * check virtual machine name (only alphanumeric) + * various other cosmetics fixes + * GTK: + - only support localhost hypervisor due to limitation in authentication + - add some more tooltips + - improve layout: help on disk cache and some others + +------------------------------------------------------------------- Old: ---- virt-scenario-2.0.8.tar.gz New: ---- virt-scenario-2.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ virt-scenario.spec ++++++ --- /var/tmp/diff_new_pack.574r3s/_old 2023-06-14 16:32:50.079757291 +0200 +++ /var/tmp/diff_new_pack.574r3s/_new 2023-06-14 16:32:50.083757315 +0200 @@ -20,7 +20,7 @@ %define pythons python3 Name: virt-scenario -Version: 2.0.8 +Version: 2.1.0 Release: 0 Summary: Tool to create XML guest configuration and prepare the host for a scenario License: GPL-3.0-or-later ++++++ virt-scenario-2.0.8.tar.gz -> virt-scenario-2.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/ChangeLog new/virt-scenario-2.1.0/ChangeLog --- old/virt-scenario-2.0.8/ChangeLog 2023-06-07 16:50:28.000000000 +0200 +++ new/virt-scenario-2.1.0/ChangeLog 2023-06-14 14:43:03.000000000 +0200 @@ -1,3 +1,238 @@ +2023-06-13 aginies + + point to the right line + + +2023-06-13 aginies + + sync with code + + +2023-06-13 aginies + + force localhost config only for now + + +2023-06-13 aginies + + add inof if not localhost + + +2023-06-13 aginies + + fix vnet + + +2023-06-13 aginies + + use preconfig for hypervisor + + +2023-06-13 aginies + + add connect_hypervisor by name + + +2023-06-13 aginies + + fix testing is_localhost + + +2023-06-13 aginies + + check if we are doing something on the local hypervisor + + +2023-06-13 aginies + + check sevctl in the host module + + +2023-06-13 aginies + + fix url + + +2023-06-12 aginies + + prepare 2.1.0 + + +2023-06-12 aginies + + load hypervisor config + + +2023-06-12 aginies + + default hypervisor is localhost + + +2023-06-12 aginies + + force hv selection before setting machine type + + +2023-06-12 aginies + + add print_info + + +2023-06-12 aginies + + add info while connecting to hypervisor + + +2023-06-12 aginies + + sort machine_list + + +2023-06-12 aginies + + use machine list from the hypervisor capabilities + + +2023-06-12 aginies + + add a todo list + + +2023-06-12 aginies + + avoid confusion between hypervisor and hypervisor name + + +2023-06-12 aginies + + fix checking hypervisor selection adn detection of SEV feature + + +2023-06-12 aginies + + avoid error between hypervisor and hypervisor name + + +2023-06-12 aginies + + adjust doc to markup + + +2023-06-12 aginies + + add a way to get_all_machine_type from an hypervisor + + +2023-06-12 aginies + + sync man page + + +2023-06-12 aginies + + fix name of ALP micro + + +2023-06-12 aginies + + sync manpage + + +2023-06-12 aginies + + sync with code + + +2023-06-12 aginies + + check virtual name input + + +2023-06-12 aginies + + check name input + + +2023-06-12 aginies + + add qcow2 and raw help + + +2023-06-12 aginies + + add a Virtual Name check to avoid libvirt error + + +2023-06-12 aginies + + add list_all_hypervisors + + +2023-06-12 aginies + + be sure to use the right hypervisor + + +2023-06-12 aginies + + Now it possible to select the hypervisor (default will be localhost) + + +2023-06-12 aginies + + take into account hvselected + + +2023-06-12 aginies + + add completion for hvselect + + +2023-06-12 aginies + + add another host for testing + + +2023-06-09 aginies + + function to retrieve machine type + + +2023-06-09 aginies + + add some more tooltips; improve layout (help on disk cache) + + +2023-06-09 aginies + + fix hvselect and hvlist + + +2023-06-08 aginies + + prepare 2.0.9 + + +2023-06-08 aginies + + use find fonction to search for virtscenario and hypervisor conf files + + +2023-06-08 aginies + + fix the way to find the vmconfig dir instead of force one + + +2023-06-08 aginies + + add an image + + +2023-06-08 aginies + + add a link to yt + + 2023-06-07 aginies add more info in overwrite mode @@ -565,11 +800,6 @@ 2023-05-05 aginies - udpate image - - -2023-05-05 aginies - fix call in virtscenario_launch @@ -2550,11 +2780,6 @@ 2023-01-11 aginies - - update the file :) - - -2023-01-11 aginies add some more images diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/DEFAULT_SETTINGS.md new/virt-scenario-2.1.0/DEFAULT_SETTINGS.md --- old/virt-scenario-2.0.8/DEFAULT_SETTINGS.md 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/DEFAULT_SETTINGS.md 2023-06-12 15:37:37.000000000 +0200 @@ -6,7 +6,7 @@ | lazy_refcounts| on | on | off | | format | qcow2 | raw | qcow2 | | disk bus | virtio | virtio | virtio | -| capacity | 20G | 20G | 20G | +| capacity | 8G | 8G | 8G | | cluster_size | 1024k | NA | 1024k | Host Settings | Secure VM | Computation | Desktop | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/PKG-INFO new/virt-scenario-2.1.0/PKG-INFO --- old/virt-scenario-2.0.8/PKG-INFO 2023-06-07 16:50:28.000000000 +0200 +++ new/virt-scenario-2.1.0/PKG-INFO 2023-06-14 14:43:03.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: virt-scenario -Version: 2.0.8 +Version: 2.1.0 Summary: Virt-scenario Home-page: https://github.com/aginies/virt-scenario Author: Antoine Ginies @@ -12,7 +12,7 @@ # Goals - This is an **EXPERIMENTATION** project for [SUSE ALP OS](https://documentation.suse.com/alp/all/) + This is an **EXPERIMENTATION** project for [SUSE ALP MICRO](https://documentation.suse.com/alp/all/) It prepares a libvirt XML guest configuration and the host to run a customized guest. Idea is to use multiple **templates** and concatenate them to create the @@ -27,7 +27,9 @@ prepare a configuration which should improved the usage compared to a basic setting. This will **NOT guarantee** that this is perfect as this higly depends on your current system. -  +  + [](https://www.youtube.com/watch?v=RKoRu2UVEtU) + # User Settings @@ -238,7 +240,7 @@ or request a specific features calling **Features.XXX**. User setting always overwrite any values set automatically by scenario. - [Scenarios()](src/virtscenario/scenarios.py#L24) + [Scenarios()](src/virtscenario/scenario.py#L31) ``` class Scenarios() -> BasicConfiguration.XXX @@ -253,7 +255,7 @@ -> ComplexConfiguration.XXX ``` - [BasicConfiguration()](src/virtscenario/dict.py#L20) + [BasicConfiguration()](src/virtscenario/dict.py#L33) ``` class BasicConfiguration() name(self, name) @@ -275,7 +277,7 @@ video(self, model_type) ``` - [ComplexConfiguration()](src/virtscenario/dict.py#L214) + [ComplexConfiguration()](src/virtscenario/dict.py#L239) ``` ComplexConfiguration() disk(self, disk) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/README.md new/virt-scenario-2.1.0/README.md --- old/virt-scenario-2.0.8/README.md 2023-06-07 15:01:49.000000000 +0200 +++ new/virt-scenario-2.1.0/README.md 2023-06-13 18:06:22.000000000 +0200 @@ -4,7 +4,7 @@ # Goals -This is an **EXPERIMENTATION** project for [SUSE ALP OS](https://documentation.suse.com/alp/all/) +This is an **EXPERIMENTATION** project for [SUSE ALP MICRO](https://documentation.suse.com/alp/all/) It prepares a libvirt XML guest configuration and the host to run a customized guest. Idea is to use multiple **templates** and concatenate them to create the @@ -19,7 +19,9 @@ prepare a configuration which should improved the usage compared to a basic setting. This will **NOT guarantee** that this is perfect as this higly depends on your current system. - + +[](https://www.youtube.com/watch?v=RKoRu2UVEtU) + # User Settings @@ -230,7 +232,7 @@ or request a specific features calling **Features.XXX**. User setting always overwrite any values set automatically by scenario. -[Scenarios()](src/virtscenario/scenarios.py#L24) +[Scenarios()](src/virtscenario/scenario.py#L31) ``` class Scenarios() -> BasicConfiguration.XXX @@ -245,7 +247,7 @@ -> ComplexConfiguration.XXX ``` -[BasicConfiguration()](src/virtscenario/dict.py#L20) +[BasicConfiguration()](src/virtscenario/dict.py#L33) ``` class BasicConfiguration() name(self, name) @@ -267,7 +269,7 @@ video(self, model_type) ``` -[ComplexConfiguration()](src/virtscenario/dict.py#L214) +[ComplexConfiguration()](src/virtscenario/dict.py#L239) ``` ComplexConfiguration() disk(self, disk) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/man/virt-scenario-settings.1 new/virt-scenario-2.1.0/man/virt-scenario-settings.1 --- old/virt-scenario-2.0.8/man/virt-scenario-settings.1 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/man/virt-scenario-settings.1 2023-06-12 15:38:56.000000000 +0200 @@ -89,11 +89,11 @@ T{ capacity T}@T{ -20G +8G T}@T{ -20G +8G T}@T{ -20G +8G T} T{ cluster_size diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/man/virt-scenario.1 new/virt-scenario-2.1.0/man/virt-scenario.1 --- old/virt-scenario-2.0.8/man/virt-scenario.1 2023-06-07 15:01:58.000000000 +0200 +++ new/virt-scenario-2.1.0/man/virt-scenario.1 2023-06-13 18:04:35.000000000 +0200 @@ -23,7 +23,7 @@ .SH Goals .PP This is an \f[B]EXPERIMENTATION\f[R] project for SUSE ALP -OS (https://documentation.suse.com/alp/all/) +MICRO (https://documentation.suse.com/alp/all/) .PP It prepares a libvirt XML guest configuration and the host to run a customized guest. @@ -42,7 +42,8 @@ This will \f[B]NOT guarantee\f[R] that this is perfect as this higly depends on your current system. .PP -[IMAGE: image] +[IMAGE: Interactive (https://i.postimg.cc/rsHLgQMw/vs-interactive.jpg)] +[IMAGE: Gtk (https://img.youtube.com/vi/RKoRu2UVEtU/0.jpg)] (https://www.youtube.com/watch?v=RKoRu2UVEtU) .SH User Settings .PP User can set some parameter in the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/setup.py new/virt-scenario-2.1.0/setup.py --- old/virt-scenario-2.0.8/setup.py 2023-06-07 10:52:15.000000000 +0200 +++ new/virt-scenario-2.1.0/setup.py 2023-06-12 19:52:43.000000000 +0200 @@ -54,6 +54,7 @@ Generate the man page """ # pandoc README.md -f markdown -s -t man -o man/virt-scenario.1 + # pandoc DEFAULT_SETTINGS.md -f markdown -s -t man -o man/virt-scenario-settings.1 #cmd = ["pandoc", "README.md", "-f", "markdown", "-s", "-t", "man", "-o", "man/virt-scenario.1",] cmd = ["echo", "BYPASSING"] if subprocess.call(cmd) != 0: @@ -163,7 +164,7 @@ setuptools.setup( name="virt-scenario", - version="2.0.8", + version="2.1.0", author="Antoine Ginies", author_email="agin...@suse.com", description="Virt-scenario", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virt_scenario.egg-info/PKG-INFO new/virt-scenario-2.1.0/src/virt_scenario.egg-info/PKG-INFO --- old/virt-scenario-2.0.8/src/virt_scenario.egg-info/PKG-INFO 2023-06-07 16:50:28.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virt_scenario.egg-info/PKG-INFO 2023-06-14 14:43:03.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: virt-scenario -Version: 2.0.8 +Version: 2.1.0 Summary: Virt-scenario Home-page: https://github.com/aginies/virt-scenario Author: Antoine Ginies @@ -12,7 +12,7 @@ # Goals - This is an **EXPERIMENTATION** project for [SUSE ALP OS](https://documentation.suse.com/alp/all/) + This is an **EXPERIMENTATION** project for [SUSE ALP MICRO](https://documentation.suse.com/alp/all/) It prepares a libvirt XML guest configuration and the host to run a customized guest. Idea is to use multiple **templates** and concatenate them to create the @@ -27,7 +27,9 @@ prepare a configuration which should improved the usage compared to a basic setting. This will **NOT guarantee** that this is perfect as this higly depends on your current system. -  +  + [](https://www.youtube.com/watch?v=RKoRu2UVEtU) + # User Settings @@ -238,7 +240,7 @@ or request a specific features calling **Features.XXX**. User setting always overwrite any values set automatically by scenario. - [Scenarios()](src/virtscenario/scenarios.py#L24) + [Scenarios()](src/virtscenario/scenario.py#L31) ``` class Scenarios() -> BasicConfiguration.XXX @@ -253,7 +255,7 @@ -> ComplexConfiguration.XXX ``` - [BasicConfiguration()](src/virtscenario/dict.py#L20) + [BasicConfiguration()](src/virtscenario/dict.py#L33) ``` class BasicConfiguration() name(self, name) @@ -275,7 +277,7 @@ video(self, model_type) ``` - [ComplexConfiguration()](src/virtscenario/dict.py#L214) + [ComplexConfiguration()](src/virtscenario/dict.py#L239) ``` ComplexConfiguration() disk(self, disk) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virthosts.yaml new/virt-scenario-2.1.0/src/virthosts.yaml --- old/virt-scenario-2.0.8/src/virthosts.yaml 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virthosts.yaml 2023-06-14 14:42:57.000000000 +0200 @@ -3,3 +3,5 @@ url: qemu:///system # Generate with 'sevctl export --full filename.pdh' on the given host # sev-cert: /path/to/host-cert-chain.pdh +linux-5540: + url: qemu+ssh://linux-5540/system diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/__init__.py new/virt-scenario-2.1.0/src/virtscenario/__init__.py --- old/virt-scenario-2.0.8/src/virtscenario/__init__.py 2023-06-07 10:52:41.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/__init__.py 2023-06-12 19:52:55.000000000 +0200 @@ -29,5 +29,5 @@ import builtins builtins.__dict__["_"] = str -__version__ = "2.0.8" +__version__ = "2.1.0" print(" Version: "+__version__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/cmd.py new/virt-scenario-2.1.0/src/virtscenario/cmd.py --- old/virt-scenario-2.0.8/src/virtscenario/cmd.py 2023-06-07 16:30:45.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/cmd.py 2023-06-13 14:01:10.000000000 +0200 @@ -75,6 +75,9 @@ line2 = util.esc('green')+'Hypervisor Configuration: '+util.esc('reset')+self.conf.hvfile+'\n' self.prompt = self.promptline+line1+line2+'\n'+'> ' + hv.load_hypervisors(self.conf.hvfile) + self.HV_LIST = hv.list_all_hypervisors() + def update_prompt(self): """ update prompt with value set by user @@ -173,34 +176,49 @@ """ if args == "": util.print_error("Please select a correct Virtual Machine name") - else: + return + if util.check_name(args): name = { 'name': args, } self.conf.dataprompt.update({'name': name['name']}) self.update_prompt() + else: + util.print_error("Only AlphaNumeric as Virtual Machine name") def do_machine(self, args): """ Define the machine type """ - if args not in qemulist.LIST_MACHINETYPE: - util.print_error("Please select a correct machine Type:"+str(qemulist.LIST_MACHINETYPE)) + hvselected = self.conf.dataprompt.get('hvselected') + if hvselected != None: + self.hypervisor = hv.select_hypervisor() + self.hypervisor.name = hvselected + if not self.hypervisor.is_connected(): + util.print_error("No connection to LibVirt, I can not list machine type available.") + return + list_m = self.hypervisor.get_all_machine_type() + if args not in list_m: + util.print_error("Please select a correct machine Type:") + print(str(list_m)) + else: + machine = { + 'machine': args, + } + self.conf.dataprompt.update({'machine': machine['machine']}) + self.update_prompt() else: - machine = { - 'machine': args, - } - self.conf.dataprompt.update({'machine': machine['machine']}) - self.update_prompt() + util.print_error("Please select an Hypervisor with 'hvselect'") def complete_machine(self, text, _line, _begidx, _endidx): """ auto completion machine type """ + list_m = self.hypervisor.get_all_machine_type() if not text: - completions = qemulist.LIST_MACHINETYPE[:] + completions = list_m[:] else: - completions = [f for f in qemulist.LIST_MACHINETYPE if f.startswith(text)] + completions = [f for f in list_m if f.startswith(text)] return completions def do_vcpu(self, args): @@ -285,21 +303,26 @@ """ Select the virtual network """ - hypervisor = hv.select_hypervisor() - if not hypervisor.is_connected(): - util.print_error("No connection to LibVirt") - return + hvselected = self.conf.dataprompt.get('hvselected') + if hvselected != None: + self.hypervisor = hv.select_hypervisor() + self.hypervisor.name = hvselected + if not self.hypervisor.is_connected(): + util.print_error("No connection to LibVirt") + return - net_list = hypervisor.network_list() - if args not in net_list: - util.print_error("Please select a Virtual Network name from:") - print(net_list) + net_list = self.hypervisor.network_list() + if args not in net_list: + util.print_error("Please select a Virtual Network name from:") + print(net_list) + else: + config = { + 'vnet': args, + } + self.conf.dataprompt.update({'vnet': config['vnet']}) + self.update_prompt() else: - config = { - 'vnet': args, - } - self.conf.dataprompt.update({'vnet': config['vnet']}) - self.update_prompt() + util.print_error("Please select an Hypervisor with 'hvselect'") def do_memory(self, args): """ @@ -448,15 +471,15 @@ """ List available hypervisor configurations """ - if configuration.check_conffile(self.conf.conffile) is not False: - configuration.Configuration.basic_config(self.conf.conffile) + if configuration.check_conffile(self.conf.hvfile) is not False: + configuration.Configuration.basic_config(self) hv.list_hypervisors() def do_hvselect(self, args): """ Set hypervisor for which VMs are configured """ - if configuration.check_conffile(self) is not False: + if configuration.check_conffile(self.conf.hvfile) is not False: configuration.Configuration.basic_config(self) name = args.strip() config = { @@ -468,6 +491,16 @@ self.conf.dataprompt.update({'hvselected': config['hvselected']}) self.update_prompt() + def complete_hvselect(self, text, _line, _begidx, _endidx): + """ + auto completion list of hypervisor + """ + if not text: + completions = self.HV_LIST + else: + completions = [f for f in self.HV_LIST if f.startswith(text)] + return completions + def do_capacity(self, args): """ Disk Size image in GiB diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/configuration.py new/virt-scenario-2.1.0/src/virtscenario/configuration.py --- old/virt-scenario-2.0.8/src/virtscenario/configuration.py 2023-06-07 16:49:50.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/configuration.py 2023-06-13 12:59:23.000000000 +0200 @@ -27,16 +27,16 @@ import virtscenario.hypervisors as hv conffile_locations = [ + '.', + '~/.local/virt-scenario', '/etc/virt-scenario', '/etc', - '~/.local/etc', - '.' ] conffile_name = 'virtscenario.yaml' hvfile_name = 'virthosts.yaml' -def find_file(name): +def find_file_dir(name, what): """ find file """ @@ -45,22 +45,27 @@ for path in conffile_locations: path = os.path.expanduser(path) - filename = "{}/{}".format(path, name) - if os.path.isfile(filename): - #print("configuration found: "+filename) - return filename + tofind = "{}/{}".format(path, name) + if what == "file": + if os.path.isfile(tofind): + #print("configuration found: "+tofind) + return tofind + elif what == "dir": + if os.path.isdir(tofind): + return tofind return conffile def find_conffile(): global conffile_name - - return find_file(conffile_name) + return find_file_dir(conffile_name, "file") def find_hvfile(): global hvfile_name + return find_file_dir(hvfile_name, "file") - return find_file(hvfile_name) +def find_vmconfig_dir(): + return find_file_dir("vmconfig", "dir") def check_conffile(conf): """ @@ -80,11 +85,8 @@ conffile = find_conffile() hvfile = find_hvfile() - # TOLOOK AFTER MARCH PROTO - if util.check_iam_root(): - vm_config_store = '/etc/virt-scenario/vmconfig' - else: - vm_config_store = '~/.local/virtscenario/' + util.check_iam_root() + vm_config_store = find_vmconfig_dir() emulator = None inputkeyboard = "" inputmouse = "" @@ -93,6 +95,8 @@ audio = usb = disk = features = clock = network = filename = tpm = iothreads = "" callsign = custom = security = video = controller = hugepages = toreport = "" loader = config = fw_info = vm_config = cdrom = vnet = hostfs = vmimage = "" + # default is local + hypervisor_name = "localhost" STORAGE_DATA = STORAGE_DATA_REC = host_filesystem = xmldata = nothing_to_report = "" memory_pin = False @@ -426,6 +430,23 @@ def set_memory_pin(self, value): self.memory_pin = value + def pre_hypervisor_setting(self): + """ + need to check hypervisor value earlier + """ + hypervisor_n = self.conf.dataprompt.get('hvselected') + if hypervisor_n != None: + util.print_ok("Selected Hypervisor: " +hypervisor_n) + self.hypervisor_name = hypervisor_n + else: + self.hypervisor_name = "localhost" + util.print_ok("Selected Hypervisor: localhost") + + self.hypervisor = hv.connect_hypervisor(self.hypervisor_name) + if not self.hypervisor.is_connected(): + util.print_error("No connection to LibVirt: "+self.hypervisor_name) + return + def check_user_settings(self, virtum): """ Check if the user as set some stuff, if yes use it diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/hypervisors.py new/virt-scenario-2.1.0/src/virtscenario/hypervisors.py --- old/virt-scenario-2.0.8/src/virtscenario/hypervisors.py 2023-06-07 16:31:56.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/hypervisors.py 2023-06-13 13:09:08.000000000 +0200 @@ -21,6 +21,7 @@ import sys import yaml import libvirt +import xml.etree.ElementTree as ET import virtscenario.util @@ -49,10 +50,12 @@ def connect(self): if self.conn is None: try: + print("Connecting to libvirt "+self.url+" ...") self.conn = libvirt.open(self.url) ver = self.conn.getVersion() virtscenario.util.print_ok('Connected to libvirtd socket; Version: '+str(ver)) return self.is_connected() + except libvirt.libvirtError as verror: print(repr(verror), file=sys.stderr) return 666 @@ -107,6 +110,20 @@ inactive_networks = self.conn.listDefinedNetworks() return inactive_networks+networks + def get_all_machine_type(self): + """ + get the list of available machine type from the hypervisor + """ + all_machine_type = [] + self.conn = libvirt.open() + host = self.conn.getCapabilities() + root = ET.fromstring(host) + find_machine_type = root.findall('.//guest/arch/machine') + for value in find_machine_type: + all_machine_type.append(value.text) + + return sorted(all_machine_type) + def dominfo(self, name): for dom in self.conn.listDefinedDomains(): if dom == name: @@ -182,6 +199,13 @@ selected = '*' print(" {} {}".format(selected, hyperv.name)) +def list_all_hypervisors(): + global HV_LIST + list = [] + for hyperv in HV_LIST: + list.append(hyperv.name) + return list + def get_hypervisor(name): global HV_LIST @@ -204,3 +228,10 @@ def select_hypervisor(): HV_SELECTED.connect() return HV_SELECTED + +def connect_hypervisor(name): + for hyperv in HV_LIST: + if hyperv.name == name: + HV_SELECTED = hyperv + HV_SELECTED.connect() + return HV_SELECTED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/qemulist.py new/virt-scenario-2.1.0/src/virtscenario/qemulist.py --- old/virt-scenario-2.0.8/src/virtscenario/qemulist.py 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/qemulist.py 2023-06-12 17:06:12.000000000 +0200 @@ -14,7 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """ -Qemu list of options and other VAR +Qemu list of options, other VAR and qemu help """ OVMF_PATH = "/usr/share/qemu" @@ -44,11 +44,11 @@ PRE_ALLOCATION = ['off', 'metadata', 'falloc', 'full'] ## -CLUSTER_SIZE = "cluster_size:\nChanges the qcow2 cluster size (must be between 512 and 2M). Smaller cluster sizes can improve the image file size whereas larger cluster sizes generally provide better performance.\n" +CLUSTER_SIZE = "<b>cluster_size</b>:\nChanges the qcow2 cluster size (must be between 512 and 2M). Smaller cluster sizes can improve the image file size whereas larger cluster sizes generally provide better performance." -PREALLOCATION ="preallocation:\nPreallocation mode (allowed values: off, metadata, falloc, full). An image with preallocated metadata is initially larger but can improve performance when the image needs to grow. falloc and full preallocations are like the same options of raw format, but sets up metadata also.\n" +PREALLOCATION ="<b>preallocation</b>:\nPreallocation mode (allowed values: off, metadata, falloc, full). An image with preallocated metadata is initially larger but can improve performance when the image needs to grow. falloc and full preallocations are like the same options of raw format, but sets up metadata also." -LAZY_REFCOUNTS ="lazy_refcounts:\nIf this option is set to on, reference count updates are postponed with the goal of avoiding metadata I/O and improving performance. This is particularly interesting with cache=writethrough which doesnât batch metadata updates. The tradeoff is that after a host crash, the reference count tables must be rebuilt (qemu-img check -r all is required).\n" +LAZY_REFCOUNTS ="<b>lazy_refcounts</b>:\nIf this option is set to on, reference count updates are postponed with the goal of avoiding metadata I/O and improving performance. This is particularly interesting with cache=writethrough which doesnât batch metadata updates. The tradeoff is that after a host crash, the reference count tables must be rebuilt (qemu-img check -r all is required)." ## https://documentation.suse.com/sles/15-SP4/html/SLES-all/cha-cachemodes.html#cachemodes-descr WRITEBACK = "<b>writeback</b>\nwriteback uses the host page cache. Writes are reported to the guest as completed when they are placed in the host cache. Cache management handles commitment to the storage device. The guest's virtual storage adapter is informed of the writeback cache and therefore expected to send flush commands as needed to manage data integrity.\n\n" @@ -62,3 +62,9 @@ DIRECTSYNC = "<b>directsync</b>\nWrites are reported as completed only when the data has been committed to the storage device and the host cache is bypassed. This mode can be useful for guests that do not send flushes when needed.\n" STORAGE_HELP = "\n<u>Disk Cache Options</u>\n"+WRITEBACK+WRITETHROUGH+NONE+UNSAFE+DIRECTSYNC + +QCOW2 = "<b>Qcow2</b>:\nThe most versatile format. Use it to have smaller images (useful if your filesystem does not supports holes, for example on Windows), optional AES encryption, zlib based compression and support of multiple VM snapshots" + +RAW = "<b>Raw</b>:\nThis format has the advantage of being simple and easily exportable to all other emulators. If your file system supports holes (for example in ext2 or ext3 on Linux or NTFS on Windows), then only the written sectors will reserve space." + +IMAGE_FORMAT=QCOW2+"\n\n"+RAW diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/scenario.py new/virt-scenario-2.1.0/src/virtscenario/scenario.py --- old/virt-scenario-2.0.8/src/virtscenario/scenario.py 2023-06-07 16:24:24.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/scenario.py 2023-06-13 17:27:55.000000000 +0200 @@ -104,10 +104,7 @@ if configuration.check_conffile(self.conf.conffile) is not False: configuration.Configuration.basic_config(self) - hypervisor = hv.select_hypervisor() - if not hypervisor.is_connected(): - util.print_error("No connection to LibVirt") - return + configuration.Configuration.pre_hypervisor_setting(self) name = self.conf.dataprompt.get('name') @@ -152,7 +149,7 @@ # Check user setting configuration.Configuration.check_user_settings(self, computation) - cfg_store = configstore.create_config_store(self, computation, hypervisor, self.conf.overwrite) + cfg_store = configstore.create_config_store(self, computation, self.hypervisor, self.conf.overwrite) if cfg_store is None: util.print_error("No config store found...") return @@ -174,7 +171,7 @@ if self.conf.overwrite == "on": # remove previous domain in the hypervisor - hypervisor.remove_domain(self.callsign) + self.hypervisor.remove_domain(self.callsign) if (self.conf.mode != "guest" or self.conf.mode == "both") and util.check_iam_root() is True: @@ -253,10 +250,7 @@ if configuration.check_conffile(self.conf.conffile) is not False: configuration.Configuration.basic_config(self) - hypervisor = hv.select_hypervisor() - if not hypervisor.is_connected(): - util.print_error("No connection to LibVirt") - return + configuration.Configuration.pre_hypervisor_setting(self) name = self.conf.dataprompt.get('name') @@ -308,7 +302,7 @@ configuration.Configuration.check_user_settings(self, desktop) # config store - cfg_store = configstore.create_config_store(self, desktop, hypervisor, self.conf.overwrite) + cfg_store = configstore.create_config_store(self, desktop, self.hypervisor, self.conf.overwrite) if cfg_store is None: util.print_error("No config store found...") return @@ -332,7 +326,7 @@ if self.conf.overwrite == "on": # remove previous domain in the hypervisor - hypervisor.remove_domain(self.callsign) + self.hypervisor.remove_domain(self.callsign) if (self.conf.mode != "guest" or self.conf.mode == "both") and util.check_iam_root() is True: util.print_title("Host Section") @@ -420,20 +414,13 @@ if configuration.check_conffile(self.conf.conffile) is not False: configuration.Configuration.basic_config(self) - if util.cmd_exists("sevctl") is False: - util.print_error("Please install sevctl tool") - return - - hypervisor = hv.select_hypervisor() - if not hypervisor.is_connected(): - util.print_error("No connection to LibVirt") - return + configuration.Configuration.pre_hypervisor_setting(self) # SEV information - sev_info = host.sev_info(hypervisor) + sev_info = host.sev_info(self.hypervisor) if not sev_info.sev_supported: - util.print_error("Selected hypervisor ({}) does not support SEV".format(hypervisor.name)) + util.print_error("Selected hypervisor ({}) does not support SEV".format(self.hypervisor.name)) return name = self.conf.dataprompt.get('name') @@ -494,7 +481,7 @@ # Check user setting configuration.Configuration.check_user_settings(self, securevm) - cfg_store = configstore.create_config_store(self, securevm, hypervisor, self.conf.overwrite) + cfg_store = configstore.create_config_store(self, securevm, self.hypervisor, self.conf.overwrite) if cfg_store is None: util.print_error("No config store found...") return @@ -522,14 +509,14 @@ dh_params = None # certifate already present - if hypervisor.has_sev_cert(): + if self.hypervisor.has_sev_cert(): util.print_ok("SEV Certificate already present") # A host certificate is configured, try to enable remote attestation - cert_file = hypervisor.sev_cert_file() + cert_file = self.hypervisor.sev_cert_file() else: util.print_ok("SEV Certificate NOT present") # forcing generation of a local PDH is NOT SECURE! - if self.force_sev is True or hypervisor.has_sev_cert() is False: + if self.force_sev is True or self.hypervisor.has_sev_cert() is False: util.print_ok("Force PDH creation") cert_file = "localhost.pdh" sev.sev_extract_pdh(cfg_store, cert_file) @@ -563,7 +550,7 @@ if self.conf.overwrite == "on": # remove previous domain in the hypervisor - hypervisor.remove_domain(self.callsign) + self.hypervisor.remove_domain(self.callsign) if self.conf.mode != "host" or self.conf.mode == "both": util.final_step_guest(cfg_store, self, verbose) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/sev.py new/virt-scenario-2.1.0/src/virtscenario/sev.py --- old/virt-scenario-2.0.8/src/virtscenario/sev.py 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/sev.py 2023-06-13 10:07:42.000000000 +0200 @@ -137,6 +137,10 @@ extract the PDH The PDH is used to negotiate a master secret between the SEV firmware and external entities """ + if util.cmd_exists("sevctl") is False: + util.print_error("Please install sevctl tool") + return + target_path = cfg_store.get_path() cmd = "cd "+target_path+";sevctl export --full "+certfile out, errs = util.system_command(cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/virtscenario/util.py new/virt-scenario-2.1.0/src/virtscenario/util.py --- old/virt-scenario-2.0.8/src/virtscenario/util.py 2023-06-07 16:35:03.000000000 +0200 +++ new/virt-scenario-2.1.0/src/virtscenario/util.py 2023-06-13 16:42:26.000000000 +0200 @@ -24,6 +24,7 @@ import shutil import yaml import json +import socket import virtscenario.qemulist as qemulist import virtscenario.xmlutil as xmlutil import virtscenario.hypervisors as hv @@ -117,11 +118,18 @@ formated_text = esc('green')+text+esc('reset') print(formated_text) +def print_info(text): + """ + Print info in green + """ + formated_text = esc('bg_blue')+text+esc('reset')+"\n" + print(formated_text) + def print_summary(text): """ Print title with blue background """ - formated_text = "\n"+esc('bg_blue')+text+esc('reset') + formated_text = "\n"+esc('bg_blue')+text+esc('reset')+"\n" print(formated_text) def print_title(text): @@ -299,6 +307,10 @@ validate_xml(filename) cfg_store.store_config() print_summary_ok("Guest XML Configuration is done") + if not is_localhost(data.hypervisor_name): + vm_image = data.STORAGE_DATA['path']+"/"+data.STORAGE_DATA['storage_name']+"."+data.STORAGE_DATA['format'] + print("\nYou should copy the XML configuration and the VM image to "+data.hypervisor_name+" host.") + print(filename+"\n"+vm_image+"\n") def find_ext_file(ext): """ @@ -409,3 +421,38 @@ output = subprocess.check_output(command).decode("utf-8") img_info = json.loads(output) return img_info['format-specific']['data']['encrypt']['uuid'] + +def get_machine_type(qemu): + """ + get machine type from qemu + """ + import re + output = subprocess.check_output([qemu, "-machine", "help"]) + + # convert the output to a string and extract the machine types using regular expressions + output_str = output.decode("utf-8") + machine_types = [] + for line in output_str.split("\n"): + if line.startswith("Supported"): + continue + machine_type = re.match(r"^(\S+)", line) + if machine_type: + machine_types.append(machine_type.group(1)) + + return machine_types + +def check_name(name): + """ + check the VM name is a alphnumeric+number only + """ + return all(inputc.isalnum() for inputc in name) + +def is_localhost(to_check): + """ + check if setup is local or not + """ + hostname = socket.gethostname() + if to_check in ["localhost", hostname]: + return True + else: + return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/vsmygtk/__init__.py new/virt-scenario-2.1.0/src/vsmygtk/__init__.py --- old/virt-scenario-2.0.8/src/vsmygtk/__init__.py 2023-06-06 13:53:27.000000000 +0200 +++ new/virt-scenario-2.1.0/src/vsmygtk/__init__.py 2023-06-12 19:53:07.000000000 +0200 @@ -27,4 +27,4 @@ text_mdialog = "No connection to LibVirt, Exiting" gtk.dialog_message("Error!", text_mdialog) -__version__ = "2.0.5" +__version__ = "2.1.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/virt-scenario-2.0.8/src/vsmygtk/main.py new/virt-scenario-2.1.0/src/vsmygtk/main.py --- old/virt-scenario-2.0.8/src/vsmygtk/main.py 2023-06-07 16:31:27.000000000 +0200 +++ new/virt-scenario-2.1.0/src/vsmygtk/main.py 2023-06-13 17:54:51.000000000 +0200 @@ -58,7 +58,7 @@ self.show_storage_window = "off" # default all expert page not displayed self.expert = "off" - self.force_sev = "off" + self.force_sev = False self.howto = self.xml_show_config = "" self.overwrite = "off" self.gtk = True @@ -73,10 +73,12 @@ self.combobox_bootdev = self.combobox_machinet = self.combobox_vnet = "" self.label_spinbutton_capacity = self.spinbutton_capacity = self.filechooser_vmimage = "" self.filechooser_cd = self.textview_cmd = self.textbuffer_cmd = self.button_start = "" - self.textbuffer_xml = "" + self.textbuffer_xml = self.machine_list = "" + # default is local + self.hypervisor_name = "localhost" - self.conffile = conf.conffile #configuration.find_conffile() - self.hvfile = conf.hvfile # configuration.find_hvfile() + self.conffile = configuration.find_conffile() + self.hvfile = configuration.find_hvfile() if configuration.check_conffile(self.conffile) is not False: configuration.Configuration.basic_config(self) @@ -84,16 +86,18 @@ self.dataprompt = conf.dataprompt self.listosdef = conf.listosdef self.mode = conf.mode - #self.conf.STORAGE_DATA = conf.STORAGE_DATA self.vm_config_store = self.conf.vm_config_store self.vm_list = os.listdir(self.vm_config_store) - self.hypervisor = hv.select_hypervisor() + self.hypervisor_name = "localhost" + self.hypervisor = hv.connect_hypervisor(self.hypervisor_name) if not self.hypervisor.is_connected(): print("No connection to LibVirt") return else: self.items_vnet = self.hypervisor.network_list() + self.items_hypervisors_list = ["localhost"] + #self.items_hypervisors_list = hv.list_all_hypervisors() # Connect signals self.connect("cancel", main_quit) @@ -193,7 +197,6 @@ win_launch.add(scrolled_window) win_launch.show_all() - def show_yaml_config(self, _widget, whichfile): """ show the YAML file @@ -262,7 +265,7 @@ vbox.pack_start(grid, False, False, 0) window.show_all() - window.connect("delete_event", on_delete_event) + window.connect("delete-event", on_delete_event) def apply_user_data_on_scenario(self): """ Now use the wizard data to overwrite some vars""" @@ -311,6 +314,10 @@ self.conf.password = self.entry_password.get_text() self.conf.dataprompt.update({'capacity': int(self.spinbutton_capacity.get_value())}) + self.conf.dataprompt.update({'hvselected': self.hypervisor_name}) + if not util.is_localhost(self.hypervisor_name): + self.force_sev = False + #return self #print("DEBUG DEBUG -------------------------------------------------------") #pprint(vars(self.conf)) @@ -513,7 +520,7 @@ label_expert = gtk.create_label("Advanced Mode", Gtk.Align.END) self.switch_expert = Gtk.Switch() gtk.margin_left(self.switch_expert) - self.switch_expert.set_tooltip_text("Add some pages with expert configuration.\n(You can choose configurations files)") + self.switch_expert.set_tooltip_text("You can choose configurations files to use.") self.switch_expert.connect("notify::active", self.on_switch_expert_activated) self.switch_expert.set_active(False) self.switch_expert.set_halign(Gtk.Align.START) @@ -613,11 +620,23 @@ frame_scena.add(grid_scena) self.main_scenario.pack_start(frame_scena, False, False, 0) + label_shv = gtk.create_label("Select Hypervisor", Gtk.Align.END) + gtk.margin_left(label_shv) + self.shv_combobox = Gtk.ComboBoxText() + gtk.margin_right(self.shv_combobox) + self.shv_combobox.set_tooltip_markup("The <b>Virtual Machine</b> will belong to this <b>Hypervisor</b>\n(List from: "+self.conf.hvfile+")\nIt is <b>mandatory</b> to get access to the hypervisor <b>without password</b> auth (ie with ssh-copy-id) as this tool doesn't handle auth part.") + self.shv_combobox.set_entry_text_column(0) + self.shv_combobox.connect("changed", self.on_shv_changed) + + for item in self.items_hypervisors_list: + self.shv_combobox.append_text(item) + self.shv_combobox.set_active(0) + label_scenario = gtk.create_label("Select Scenario", Gtk.Align.END) gtk.margin_left(label_scenario) self.scenario_combobox = Gtk.ComboBoxText() gtk.margin_right(self.scenario_combobox) - self.scenario_combobox.set_tooltip_text("Will preload an optimized VM configration") + self.scenario_combobox.set_tooltip_markup("Will <b>preload</b> an <b>optimized</b> VM configration and <b>host settings</b>.") self.scenario_combobox.set_entry_text_column(0) # Add some items to the combo box @@ -627,8 +646,10 @@ self.scenario_combobox.set_active(-1) grid_scena.attach(urltoinfo, 0, 0, 2, 1) - grid_scena.attach(label_scenario, 0, 2, 1, 1) - grid_scena.attach(self.scenario_combobox, 1, 2, 1, 1) + #grid_scena.attach(label_shv, 0, 2, 1, 1) + #grid_scena.attach(self.shv_combobox, 1, 2, 1, 1) + grid_scena.attach(label_scenario, 0, 3, 1, 1) + grid_scena.attach(self.scenario_combobox, 1, 3, 1, 1) #Create a horizontal box for overwrite config option @@ -638,10 +659,10 @@ gtk.margin_bottom_right(switch_overwrite) switch_overwrite.set_halign(Gtk.Align.START) switch_overwrite.connect("notify::active", self.on_switch_overwrite_activated) - switch_overwrite.set_tooltip_text("This will overwrite any previous VM configuration!\nThis will also undefine any previous VM with the same name on current Hypervisor") + switch_overwrite.set_tooltip_markup("This will <b>overwrite</b> any previous VM configuration.\n\nThis will also <b>undefine</b> any previous VM with the same name on current selected Hypervisor.") switch_overwrite.set_active(False) - grid_scena.attach(label_overwrite, 0, 3, 1, 1) - grid_scena.attach(switch_overwrite, 1, 3, 1, 1) + grid_scena.attach(label_overwrite, 0, 4, 1, 1) + grid_scena.attach(switch_overwrite, 1, 4, 1, 1) # Handle scenario selection self.scenario_combobox.connect("changed", self.on_scenario_changed) @@ -671,15 +692,6 @@ self.main_svbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) frame_scfg = gtk.create_frame("Storage Configuration") - title_frame = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbutton_storage = Gtk.Button.new_from_icon_name("dialog-question", Gtk.IconSize.BUTTON) - hbutton_storage.set_relief(Gtk.ReliefStyle.NONE) - hbutton_storage.set_size_request(16, 16) - hbutton_storage.connect("clicked", lambda widget: show_storage_help(hbutton_storage)) - frame_tittle_label = Gtk.Label("Storage Configuration") - title_frame.pack_start(frame_tittle_label, False, False, 0) - title_frame.pack_start(hbutton_storage, False, False, 0) - frame_scfg.set_label_widget(title_frame) vbox_scfg = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) @@ -689,7 +701,7 @@ label_disk_target = gtk.create_label("Disk Target (Linux)", Gtk.Align.END) gtk.margin_top_left(label_disk_target) self.combobox_disk_target = Gtk.ComboBoxText() - self.combobox_disk_target.set_tooltip_text("Select the disk target name inside the VM") + self.combobox_disk_target.set_tooltip_markup("Select the <b>disk target</b> name inside the VM.") gtk.margin_top_right(self.combobox_disk_target) self.combobox_disk_target.set_margin_top(18) @@ -702,6 +714,7 @@ label_disk_format = gtk.create_label("Disk format", Gtk.Align.END) gtk.margin_left(label_disk_format) self.combobox_disk_format = Gtk.ComboBoxText() + self.combobox_disk_format.set_tooltip_markup(qemulist.IMAGE_FORMAT) gtk.margin_right(self.combobox_disk_format) self.combobox_disk_format.set_entry_text_column(0) @@ -714,13 +727,21 @@ label_spinbutton_cluster = gtk.create_label("Cluster Size (KiB)", Gtk.Align.END) gtk.margin_left(label_spinbutton_cluster) self.spinbutton_cluster = Gtk.SpinButton() - self.spinbutton_cluster.set_tooltip_text(qemulist.CLUSTER_SIZE) + self.spinbutton_cluster.set_tooltip_markup(qemulist.CLUSTER_SIZE) gtk.margin_right(self.spinbutton_cluster) + self.spinbutton_cluster.set_numeric(True) self.spinbutton_cluster.set_range(512, 2048) self.spinbutton_cluster.set_increments(512, 1) label_disk_cache = gtk.create_label("Disk Cache", Gtk.Align.END) gtk.margin_left(label_disk_cache) + # bigger right margin to put the help button + label_disk_cache.set_margin_right(36) + hbutton_storage = Gtk.Button.new_from_icon_name("dialog-question", Gtk.IconSize.BUTTON) + hbutton_storage.set_relief(Gtk.ReliefStyle.NONE) + hbutton_storage.set_size_request(16, 16) + hbutton_storage.set_halign(Gtk.Align.END) + hbutton_storage.connect("clicked", lambda widget: show_storage_help(hbutton_storage)) self.combobox_disk_cache = Gtk.ComboBoxText() gtk.margin_right(self.combobox_disk_cache) self.combobox_disk_cache.set_entry_text_column(0) @@ -734,7 +755,7 @@ label_lazyref = gtk.create_label("Lazy Ref Count", Gtk.Align.END) gtk.margin_left(label_lazyref) self.combobox_lazyref = Gtk.ComboBoxText() - self.combobox_lazyref.set_tooltip_text(qemulist.LAZY_REFCOUNTS) + self.combobox_lazyref.set_tooltip_markup(qemulist.LAZY_REFCOUNTS) gtk.margin_right(self.combobox_lazyref) self.combobox_lazyref.set_entry_text_column(0) @@ -745,7 +766,7 @@ label_prealloc = gtk.create_label("Pre-allocation", Gtk.Align.END) gtk.margin_left(label_prealloc) self.combobox_prealloc = Gtk.ComboBoxText() - self.combobox_prealloc.set_tooltip_text(qemulist.PREALLOCATION) + self.combobox_prealloc.set_tooltip_markup(qemulist.PREALLOCATION) gtk.margin_right(self.combobox_prealloc) self.combobox_prealloc.set_entry_text_column(0) @@ -757,7 +778,7 @@ label_encryption = gtk.create_label("Encryption", Gtk.Align.END) gtk.margin_left(label_encryption) self.combobox_encryption = Gtk.ComboBoxText() - self.combobox_encryption.set_tooltip_text("qcow2 payload will be encrypted using the LUKS format") + self.combobox_encryption.set_tooltip_markup("<b>qcow2</b> payload will be <b>encrypted</b> using the LUKS format.") self.combobox_encryption.connect("changed", self.on_encryption_changed) gtk.margin_right(self.combobox_encryption) self.combobox_encryption.set_entry_text_column(0) @@ -793,6 +814,7 @@ grid_sto.attach(label_spinbutton_cluster, 0, 3, 1, 1) grid_sto.attach(self.spinbutton_cluster, 1, 3, 1, 1) grid_sto.attach(label_disk_cache, 0, 4, 1, 1) + grid_sto.attach(hbutton_storage, 0, 4, 1, 1) grid_sto.attach(self.combobox_disk_cache, 1, 4, 1, 1) grid_sto.attach(label_lazyref, 0, 5, 1, 1) grid_sto.attach(self.combobox_lazyref, 1, 5, 1, 1) @@ -858,11 +880,11 @@ def page_configuration(self): """ PAGE configuration""" print("Load Page configuration") - main_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) - self.append_page(main_vbox) - #self.set_page_title(main_vbox, "Configuration") - self.set_page_type(main_vbox, Gtk.AssistantPageType.CONFIRM) - self.set_page_complete(main_vbox, True) + self.main_conf_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) + self.append_page(self.main_conf_vbox) + #self.set_page_title(self.main_conf_vbox, "Configuration") + self.set_page_type(self.main_conf_vbox, Gtk.AssistantPageType.CONFIRM) + self.set_page_complete(self.main_conf_vbox, True) frame_cfg = gtk.create_frame("Configuration") vbox_cfg = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) @@ -875,24 +897,29 @@ self.entry_name = Gtk.Entry() gtk.margin_top_right(self.entry_name) self.entry_name.set_text("VMname") + self.entry_name.set_tooltip_text("Virtual Machine Name (Only <b>AlphaNumeric</b>).") + self.entry_name.connect("changed", self.on_entry_name_changed) label_spinbutton_vcpu = gtk.create_label("Virtual CPU", Gtk.Align.END) gtk.margin_left(label_spinbutton_vcpu) self.spinbutton_vcpu = Gtk.SpinButton() + self.spinbutton_vcpu.set_numeric(True) gtk.margin_right(self.spinbutton_vcpu) - self.spinbutton_vcpu.set_range(1, 32) + self.spinbutton_vcpu.set_range(1, 64) self.spinbutton_vcpu.set_increments(1, 1) label_spinbutton_mem = gtk.create_label("Memory (GiB)", Gtk.Align.END) gtk.margin_left(label_spinbutton_mem) self.spinbutton_mem = Gtk.SpinButton() + self.spinbutton_mem.set_numeric(True) gtk.margin_right(self.spinbutton_mem) - self.spinbutton_mem.set_range(1, 32) + self.spinbutton_mem.set_range(1, 256) self.spinbutton_mem.set_increments(1, 1) label_bootdev = gtk.create_label("Boot device", Gtk.Align.END) gtk.margin_left(label_bootdev) self.combobox_bootdev = Gtk.ComboBoxText() + self.combobox_bootdev.set_tooltip_markup("Select the <b>boot</b> device") gtk.margin_right(self.combobox_bootdev) self.combobox_bootdev.set_entry_text_column(0) @@ -906,9 +933,10 @@ label_machinet = gtk.create_label("Machine Type", Gtk.Align.END) gtk.margin_left(label_machinet) self.combobox_machinet = Gtk.ComboBoxText() + self.combobox_machinet.set_tooltip_text("Using a recent machine type is higly recommended") gtk.margin_right(self.combobox_machinet) - items_machinet = qemulist.LIST_MACHINETYPE + items_machinet = self.machine_list for item in items_machinet: self.combobox_machinet.append_text(item) # Handle machine type selection @@ -917,6 +945,7 @@ label_vnet = gtk.create_label("Virtual Network", Gtk.Align.END) gtk.margin_bottom_left(label_vnet) self.combobox_vnet = Gtk.ComboBoxText() + self.combobox_vnet.set_tooltip_markup("Select a <b>Virtual Network</b> on current Hypervisor") gtk.margin_bottom_right(self.combobox_vnet) self.combobox_vnet.set_entry_text_column(0) @@ -928,6 +957,7 @@ gtk.margin_left(self.label_spinbutton_capacity) self.spinbutton_capacity = Gtk.SpinButton() gtk.margin_right(self.spinbutton_capacity) + self.spinbutton_capacity.set_numeric(True) self.spinbutton_capacity.set_range(1, 32) self.spinbutton_capacity.set_increments(1, 1) @@ -947,7 +977,7 @@ grid_cfg.attach(self.combobox_vnet, 1, 6, 1, 1) vbox_cfg.pack_start(grid_cfg, False, False, 0) frame_cfg.add(vbox_cfg) - main_vbox.pack_start(frame_cfg, False, False, 0) + self.main_conf_vbox.pack_start(frame_cfg, False, False, 0) #vbox_cfgplus = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) frame_cfgplus = gtk.create_frame("Image / CD / DVD / Storage") @@ -978,7 +1008,7 @@ grid_cfgplus.attach(self.filechooser_cd, 1, 1, 1, 1) grid_cfgplus.attach(button_storage, 0, 2, 2, 1) frame_cfgplus.add(grid_cfgplus) - main_vbox.pack_start(frame_cfgplus, False, False, 0) + self.main_conf_vbox.pack_start(frame_cfgplus, False, False, 0) # Handle vnet selection #self.combobox_vnet.connect("changed", on_vnet_changed) @@ -1096,9 +1126,15 @@ if selected_item == "Secure VM": print("Secure vm selected") - self.force_sev = "on" + self.force_sev = True self.selected_scenario = "securevm" + if not hv.connect_hypervisor(self.hypervisor_name): + util.print_error("Setting hypervisor failed") + return + self.hypervisor = hv.connect_hypervisor(self.hypervisor_name) + self.hypervisor.name = self.hypervisor_name sev_info = scenario.host.sev_info(self.hypervisor) + if not sev_info.sev_supported: util.print_error("Selected hypervisor ({}) does not support SEV".format(self.hypervisor.name)) self.set_page_complete(self.main_scenario, False) @@ -1111,13 +1147,13 @@ self.conf.memory_pin = True elif selected_item == "Desktop": print("Desktop scenario") - self.force_sev = "off" + self.force_sev = False self.selected_scenario = "desktop" self.conf = scenario.Scenarios.pre_desktop(self, "desktop") self.conf.memory_pin = False elif selected_item == "Computation": print("Computation scenario") - self.force_sev = "off" + self.force_sev = False self.selected_scenario = "computation" self.conf = scenario.Scenarios.pre_computation(self, "computation") self.conf.memory_pin = False @@ -1150,6 +1186,25 @@ search_disk_format = self.STORAGE_DATA['format'] search_in_comboboxtext(self.combobox_disk_format, search_disk_format) + def on_entry_name_changed(self, widget): + if util.check_name(widget.get_text()): + self.entry_name.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "emblem-ok-symbolic") + self.set_page_complete(self.main_conf_vbox, True) + else: + self.entry_name.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "emblem-error") + self.set_page_complete(self.main_conf_vbox, False) + + def on_shv_changed(self, combo_box): + """ handle selection of the hypervisor""" + tree_iter = combo_box.get_active_iter() + if tree_iter is not None: + model = combo_box.get_model() + selected_item = model[tree_iter][0] + print("Selected hypervisor: {}".format(selected_item)) + self.hypervisor_name = selected_item + self.machine_list = self.hypervisor.get_all_machine_type() + if not isinstance(self.scenario_combobox, str): + self.scenario_combobox.set_active(-1) def on_switch_expert_activated(self, switch, _gparam): """ display status of the switch """ @@ -1162,9 +1217,9 @@ def on_switch_forcesev_activated(self, switch, _gparam): """ display status of the switch """ if switch.get_active(): - self.force_sev = "on" + self.force_sev = True else: - self.force_sev = "off" + self.force_sev = False #print("Switch Force SEV was turned", self.force_sev) def on_switch_overwrite_activated(self, switch, _gparam): @@ -1247,7 +1302,6 @@ selected_item = gtk.find_value_in_combobox(combo_box) print("Selected Boot device: {}".format(selected_item)) - def on_machinet_changed(combo_box): """ Get the selected item """ selected_item = gtk.find_value_in_combobox(combo_box)