From adef3f52bf3326ac8f3d14397254d38e95e15ec0 Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Wed, 31 Jul 2024 09:43:29 +0200 Subject: [PATCH 1/8] Include osinfo option in install_vm.py script This option is necessary to virt-install command when a system can't be detected, for example when a not yet released product needs to be provisioned for testing. Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/install_vm.py b/tests/install_vm.py index db460aa2c3f..d2c8cd6df58 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -150,6 +150,12 @@ def parse_args(): action="store_true", help="Set cache unsafe.", ) + parser.add_argument( + "--osinfo", + dest="osinfo", + default=None, + help="Specify OSInfo for virt-install command.", + ) return parser.parse_args() @@ -326,6 +332,9 @@ def get_virt_install_command(data): else: boot_opts.append("loader.secure=no") + if data.osinfo: + command.append("--osinfo={0}".format(data.osinfo)) + command.extend(join_extented_opt("--boot", ",", boot_opts)) command.extend(join_extented_opt("--extra-args", " ", extra_args_opts)) command.extend(join_extented_opt("--features", ",", features_opts)) From 50f1cfee84d4ebe51f11efac49e434814cf8de27 Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Wed, 31 Jul 2024 13:56:50 +0200 Subject: [PATCH 2/8] Remove centos7 and include rhel10 Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index d2c8cd6df58..af03ee10eae 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -10,11 +10,11 @@ KNOWN_DISTROS = [ "fedora", - "centos7", "centos8", "centos9", "rhel8", "rhel9", + "rhel10", ] DISTRO_URL = { From 7f374e960753c8267bbc7dac4824edc7517c6a44 Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Wed, 31 Jul 2024 14:15:57 +0200 Subject: [PATCH 3/8] Simplify handle of urls Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index af03ee10eae..ee2e09ef129 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -186,15 +186,12 @@ def err(rc, msg): sys.exit(rc) -def handle_url(data): - if not data.url: - data.url = DISTRO_URL.get(data.distro, None) - data.extra_repo = DISTRO_EXTRA_REPO.get(data.distro, None) - - if data.url: - return +def try_known_urls(data): + data.url = DISTRO_URL.get(data.distro, None) + data.extra_repo = DISTRO_EXTRA_REPO.get(data.distro, None) - err(1, "For the '{0}' distro the `--url` option needs to be provided.".format(data.distro)) + if not data.url: + err(1, "For the '{0}' distro the `--url` option needs to be provided.".format(data.distro)) def handle_ssh_pubkey(data): @@ -399,7 +396,9 @@ def give_info(data): def main(): data = parse_args() - handle_url(data) + if not data.url or not data.extra_repo: + try_known_urls(data) + handle_ssh_pubkey(data) print("Using SSH public key from file: {0}".format(data.ssh_pubkey)) From f8a171a332a3d5be0025a0f4986fc0e59e90360e Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Wed, 31 Jul 2024 14:54:52 +0200 Subject: [PATCH 4/8] Simplify handle of ssh pub_key Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index ee2e09ef129..7abb3b3eac6 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -197,16 +197,14 @@ def try_known_urls(data): def handle_ssh_pubkey(data): data.ssh_pubkey_used = bool(data.ssh_pubkey) if not data.ssh_pubkey: - username = os.environ.get("SUDO_USER", "") - home_dir = os.path.expanduser("~" + username) - data.ssh_pubkey = home_dir + "/.ssh/id_rsa.pub" - - if not os.path.isfile(data.ssh_pubkey): - err(1, """Error: SSH public key not found at {0} -You can use the `--ssh-pubkey` to specify which key should be used.""".format(data.ssh_pubkey)) - - with open(data.ssh_pubkey) as f: - data.pub_key_content = f.readline().rstrip() + home_dir = os.path.expanduser('~') + user_default_key = f'{home_dir}/.ssh/id_rsa.pub' + if os.path.isfile(user_default_key): + data.ssh_pubkey = user_default_key + with open(data.ssh_pubkey) as f: + data.pub_key_content = f.readline().rstrip() + else: + err(1, "SSH public key was not found or informed by `--ssh-pubkey` option.") def handle_disk(data): @@ -400,13 +398,11 @@ def main(): try_known_urls(data) handle_ssh_pubkey(data) - - print("Using SSH public key from file: {0}".format(data.ssh_pubkey)) - print("Using hypervisor: {0}".format(data.libvirt)) - handle_disk(data) handle_kickstart(data) + print("Using SSH public key from file: {0}".format(data.ssh_pubkey)) + print("Using hypervisor: {0}".format(data.libvirt)) print("Using kickstart file: {0}".format(data.kickstart)) handle_rest(data) From ab2c45cf361ed1ceca92cc3ffaeebb2aa5ca61ec Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Thu, 1 Aug 2024 09:03:13 +0200 Subject: [PATCH 5/8] Optimize script output VMs installed with this script are in general for test. Sometimes they fail and we need to isolate the issue. So now the virt-install command is always shown before starting the installation to make things easier. Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index 7abb3b3eac6..c58ab1219d8 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -338,9 +338,10 @@ def get_virt_install_command(data): def run_virt_install(data, command): + print("\nThis is the resulting for the VM installation:") + print(shlex.join(command)) + if data.dry: - print("\nThe following command would be used for the VM installation:") - print(shlex.join(command)) return subprocess.call(command) @@ -349,6 +350,8 @@ def run_virt_install(data, command): wait_vm_not_running(data.domain) subprocess.call(["virsh", "start", data.domain]) + give_info(data) + def give_info(data): if data.libvirt == "qemu:///system": @@ -408,7 +411,6 @@ def main(): handle_rest(data) command = get_virt_install_command(data) run_virt_install(data, command) - give_info(data) if __name__ == "__main__": From 751284ddda607402173689ed3d0c42a7c3c21dff Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Thu, 1 Aug 2024 09:11:24 +0200 Subject: [PATCH 6/8] Simplify error function Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index c58ab1219d8..4a5764a10fa 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -181,9 +181,9 @@ def wait_vm_not_running(domain): return -def err(rc, msg): +def err(msg): print(msg, file=sys.stderr) - sys.exit(rc) + sys.exit(1) def try_known_urls(data): @@ -191,7 +191,7 @@ def try_known_urls(data): data.extra_repo = DISTRO_EXTRA_REPO.get(data.distro, None) if not data.url: - err(1, "For the '{0}' distro the `--url` option needs to be provided.".format(data.distro)) + err(f'For the "{data.distro}" distro the "--url" option needs to be provided.') def handle_ssh_pubkey(data): @@ -204,7 +204,7 @@ def handle_ssh_pubkey(data): with open(data.ssh_pubkey) as f: data.pub_key_content = f.readline().rstrip() else: - err(1, "SSH public key was not found or informed by `--ssh-pubkey` option.") + err('SSH public key was not found or informed by "--ssh-pubkey" option.') def handle_disk(data): From 840c9e89fadfa36c1fc1cf6a4d95afd862f87e5e Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Thu, 1 Aug 2024 10:30:38 +0200 Subject: [PATCH 7/8] Simplify strings formats Replace the traditional call for format method for its shorter alternative. This makes the lines easier to be read and maintained. Signed-off-by: Marcus Burghardt --- tests/install_vm.py | 95 ++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/tests/install_vm.py b/tests/install_vm.py index 4a5764a10fa..4a010f44f70 100755 --- a/tests/install_vm.py +++ b/tests/install_vm.py @@ -163,7 +163,7 @@ def parse_args(): def wait_vm_not_running(domain): timeout = 300 - print("Waiting for {0} VM to shutdown (max. {1}s)".format(domain, timeout)) + print(f'Waiting for {domain} VM to shutdown (max. {timeout}s)') end_time = time.time() + timeout try: while True: @@ -173,11 +173,10 @@ def wait_vm_not_running(domain): return if time.time() < end_time: continue - print("Timeout reached: {0} VM failed to shutdown, cancelling wait." - .format(domain)) + print(f'Timeout reached: {domain} VM failed to shutdown, cancelling wait.') return except KeyboardInterrupt: - print("Interrupted, cancelling wait.") + print('Interrupted, cancelling wait.') return @@ -209,24 +208,24 @@ def handle_ssh_pubkey(data): def handle_disk(data): disk_spec = [ - "size={0}".format(data.disk_size), - "format=qcow2", + f'size={data.disk_size}', + 'format=qcow2', ] if data.disk: disk_spec.extend(data.disk.split(",")) elif data.disk_dir: disk_path = os.path.join(data.disk_dir, data.domain) + ".qcow2" - print("Location of VM disk: {0}".format(disk_path)) - disk_spec.append("path={0}".format(disk_path)) + print(f'Location of VM disk: {disk_path}') + disk_spec.append(f'path={disk_path}') if data.disk_unsafe: - disk_spec.append("cache=unsafe") - data.disk_spec = ",".join(disk_spec) + disk_spec.append('cache=unsafe') + data.disk_spec = ','.join(disk_spec) def handle_kickstart(data): data.ks_basename = os.path.basename(data.kickstart) - tmp_kickstart = "/tmp/" + data.ks_basename + tmp_kickstart = f'/tmp/{data.ks_basename}' with open(data.kickstart) as infile, open(tmp_kickstart, "w") as outfile: content = infile.read() content = content.replace("&&HOST_PUBLIC_KEY&&", data.pub_key_content) @@ -236,8 +235,7 @@ def handle_kickstart(data): repo_cmd = "" if data.extra_repo: - # extra repository - repo_cmd = "repo --name=extra-repository --baseurl={0}".format(data.extra_repo) + repo_cmd = f'repo --name=extra-repository --baseurl={data.extra_repo}' content = content.replace("&&YUM_EXTRA_REPO_URL&&", data.extra_repo) content = content.replace("&&YUM_EXTRA_REPO&&", repo_cmd) @@ -275,37 +273,37 @@ def handle_rest(data): def join_extented_opt(opt_name, delim, opts): if opts: - return ["{0}={1}".format(opt_name, delim.join(opts))] + return [f'{opt_name}={delim.join(opts)}'] return [] def get_virt_install_command(data): command = [ - "virt-install", - "--connect={0}".format(data.libvirt), - "--name={0}".format(data.domain), - "--memory={0}".format(data.ram), - "--vcpus={0}".format(data.cpu), - "--network={0}".format(data.network), - "--disk={0}".format(data.disk_spec), - "--initrd-inject={0}".format(data.kickstart), - "--serial=pty", - "--noautoconsole", - "--rng=/dev/random", - "--wait={0}".format(data.wait_opt), - "--location={0}".format(data.url), + 'virt-install', + f'--connect={data.libvirt}', + f'--name={data.domain}', + f'--memory={data.ram}', + f'--vcpus={data.cpu}', + f'--network={data.network}', + f'--disk={data.disk_spec}', + f'--initrd-inject={data.kickstart}', + '--serial=pty', + '--noautoconsole', + '--rng=/dev/random', + f'--wait={data.wait_opt}', + f'--location={data.url}', ] boot_opts = [] extra_args_opts = [ - "inst.ks=file:/{0}".format(data.ks_basename), - "inst.ks.device=eth0", - # The kernel option "net.ifnames=0" is used to disable predictable network - # interface names, for more details see: + f'inst.ks=file:/{data.ks_basename}', + 'inst.ks.device=eth0', + # The kernel option "net.ifnames=0" is used to disable predictable network interface + # names. For more details see: # https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/ - "net.ifnames=0", - "console=ttyS0,115200", + 'net.ifnames=0', + 'console=ttyS0,115200', ] features_opts = [] @@ -328,7 +326,7 @@ def get_virt_install_command(data): boot_opts.append("loader.secure=no") if data.osinfo: - command.append("--osinfo={0}".format(data.osinfo)) + command.append(f'--osinfo={data.osinfo}') command.extend(join_extented_opt("--boot", ",", boot_opts)) command.extend(join_extented_opt("--extra-args", " ", extra_args_opts)) @@ -338,7 +336,7 @@ def get_virt_install_command(data): def run_virt_install(data, command): - print("\nThis is the resulting for the VM installation:") + print("\nThis is the resulting command for the VM installation:") print(shlex.join(command)) if data.dry: @@ -355,7 +353,7 @@ def run_virt_install(data, command): def give_info(data): if data.libvirt == "qemu:///system": - ip_cmd = "sudo virsh domifaddr {0}".format(data.domain) + ip_cmd = f'sudo virsh domifaddr {data.domain}' else: # command evaluation in fish shell is simply surrounded by # parenthesis for example: (echo foo). In other shells you @@ -364,28 +362,27 @@ def give_info(data): cmd_eval = "" if environ["SHELL"][-4:] == "fish" else "$" - ip_cmd = "arp -n | grep {0}(virsh -q domiflist {1} | awk '{{print $5}}')".format( - cmd_eval, data.domain) + ip_cmd = f"arp -n | grep {cmd_eval}(virsh -q domiflist {data.domain} | awk '{{print $5}}')" - print(""" -To determine the IP address of the {domain} VM use: + print(f""" +To determine the IP address of the {data.domain} VM use: {ip_cmd} -To connect to the {domain} VM use: +To connect to the {data.domain} VM use: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@IP To connect to the VM serial console, use: - virsh console {domain}""".format(** data.__dict__, ip_cmd=ip_cmd)) + virsh console {data.domain}""") if data.ssh_pubkey_used: - print(""" + print(f""" Add: - -o IdentityFile={ssh_pubkey} + -o IdentityFile={data.ssh_pubkey} option to your ssh command and export the: - export SSH_ADDITIONAL_OPTIONS='-o IdentityFile={ssh_pubkey}' + export SSH_ADDITIONAL_OPTIONS='-o IdentityFile={data.ssh_pubkey}' -before running the Automatus.""".format(** data.__dict__)) +before running the Automatus.""") if data.libvirt == "qemu:///system": print(""" @@ -404,9 +401,9 @@ def main(): handle_disk(data) handle_kickstart(data) - print("Using SSH public key from file: {0}".format(data.ssh_pubkey)) - print("Using hypervisor: {0}".format(data.libvirt)) - print("Using kickstart file: {0}".format(data.kickstart)) + print(f'Using SSH public key from file: {data.ssh_pubkey}') + print(f'Using hypervisor: {data.libvirt}') + print(f'Using kickstart file: {data.kickstart}') handle_rest(data) command = get_virt_install_command(data) From dd705b8e697450fb6a111c75eb83fdbcc0278df4 Mon Sep 17 00:00:00 2001 From: Marcus Burghardt Date: Thu, 1 Aug 2024 11:53:40 +0200 Subject: [PATCH 8/8] Review kickstart file for test_suite Just included RHEL 10 comment. Signed-off-by: Marcus Burghardt --- tests/kickstarts/test_suite.cfg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/kickstarts/test_suite.cfg b/tests/kickstarts/test_suite.cfg index eb91151d5ae..34da5ea1d7a 100644 --- a/tests/kickstarts/test_suite.cfg +++ b/tests/kickstarts/test_suite.cfg @@ -2,6 +2,7 @@ # This kickstart is known to apply for: # - Red Hat Enterprise Linux 8 - when using additional repository AppStream # - Red Hat Enterprise Linux 9 - when using additional repository AppStream +# - Red Hat Enterprise Linux 10 - when using additional repository AppStream # - Fedora # # Based on: @@ -98,11 +99,11 @@ logvol swap --name=swap --vgname=VolGroup --size=2016 # Packages selection (%packages section is required) %packages -openscap-scanner -tar qemu-guest-agent +openscap-scanner openssh-clients openssh-server +tar %end # End of %packages section %post --log /root/post-install.log --interpreter /bin/bash