From a4a0c028241396bd0d9b4427e491a3a9374b0f9b Mon Sep 17 00:00:00 2001 From: Andrew Lukoshko Date: Thu, 30 May 2024 11:00:36 +0000 Subject: [PATCH] import Fedora oz-0.18.1-13.el8 --- .gitignore | 1 + .oz.metadata | 1 + ...oller-and-keyboard-for-aarch64-for-a.patch | 26 + ...rk-functions-so-tests-work-with-no-n.patch | 105 ++++ ...te-kickstart-so-initial-setup-won-t-.patch | 51 ++ ...-the-data-in-_wait_for_install_finis.patch | 32 + ...on-python3-and-building-on-EL8-or-hi.patch | 60 ++ ...es-to-pass-required-useuefi-paramete.patch | 50 ++ .../0006-Use-discard-unmap-for-images.patch | 27 + ...start-so-initial-setup-won-t-think-r.patch | 46 ++ ...ompat-fixes-py.test-and-ConfigParser.patch | 562 ++++++++++++++++++ ...ary-useuefi-arg-on-the-Guest-classes.patch | 205 +++++++ ...llable-is-in-collections.abc-since-P.patch | 39 ++ ...multiple-fixes-to-expected-guest-XML.patch | 102 ++++ ...2-Add-testing-instructions-to-README.patch | 40 ++ .../0013-Add-monotonic-to-requirements.patch | 25 + ...e-oz.spec.in-to-match-current-Fedora.patch | 107 ++++ ...ts-handle-libvirt_type-not-being-kvm.patch | 68 +++ ...uest-image-path-being-the-system-one.patch | 33 + ...lint-and-flake8-commands-in-Makefile.patch | 32 + ...un-the-unit-tests-in-Fedora-and-EL7-.patch | 147 +++++ ...hub-Action-workflow-to-run-CI-checks.patch | 109 ++++ ...me-docker-is-present-always-pass-lin.patch | 84 +++ ...-specification-using-any-SI-or-IEC-u.patch | 347 +++++++++++ SPECS/oz.spec | 385 ++++++++++++ 25 files changed, 2684 insertions(+) create mode 100644 .gitignore create mode 100644 .oz.metadata create mode 100644 SOURCES/0001-Enable-USB-controller-and-keyboard-for-aarch64-for-a.patch create mode 100644 SOURCES/0001-tests-mock-network-functions-so-tests-work-with-no-n.patch create mode 100644 SOURCES/0002-Revert-Don-t-write-kickstart-so-initial-setup-won-t-.patch create mode 100644 SOURCES/0003-Don-t-abort-when-the-data-in-_wait_for_install_finis.patch create mode 100644 SOURCES/0004-Fix-for-running-on-python3-and-building-on-EL8-or-hi.patch create mode 100644 SOURCES/0005-Fix-RHEL-templates-to-pass-required-useuefi-paramete.patch create mode 100644 SOURCES/0006-Use-discard-unmap-for-images.patch create mode 100644 SOURCES/0007-Don-t-write-kickstart-so-initial-setup-won-t-think-r.patch create mode 100644 SOURCES/0008-Python-3-compat-fixes-py.test-and-ConfigParser.patch create mode 100644 SOURCES/0009-Unpick-unnecessary-useuefi-arg-on-the-Guest-classes.patch create mode 100644 SOURCES/0010-Python-compat-Callable-is-in-collections.abc-since-P.patch create mode 100644 SOURCES/0011-Tests-multiple-fixes-to-expected-guest-XML.patch create mode 100644 SOURCES/0012-Add-testing-instructions-to-README.patch create mode 100644 SOURCES/0013-Add-monotonic-to-requirements.patch create mode 100644 SOURCES/0014-Update-oz.spec.in-to-match-current-Fedora.patch create mode 100644 SOURCES/0015-tests-handle-libvirt_type-not-being-kvm.patch create mode 100644 SOURCES/0016-tests-handle-guest-image-path-being-the-system-one.patch create mode 100644 SOURCES/0017-Update-pylint-and-flake8-commands-in-Makefile.patch create mode 100644 SOURCES/0018-Add-ability-to-run-the-unit-tests-in-Fedora-and-EL7-.patch create mode 100644 SOURCES/0019-Add-a-Github-Action-workflow-to-run-CI-checks.patch create mode 100644 SOURCES/0020-CI-use-sudo-assume-docker-is-present-always-pass-lin.patch create mode 100644 SOURCES/0021-Allow-image-size-specification-using-any-SI-or-IEC-u.patch create mode 100644 SPECS/oz.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..717a110 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/oz-0.18.1.tar.gz diff --git a/.oz.metadata b/.oz.metadata new file mode 100644 index 0000000..d6a01fc --- /dev/null +++ b/.oz.metadata @@ -0,0 +1 @@ +ab8bc6670a75e3c5d290cbbcf7f5307034ce04c0 SOURCES/oz-0.18.1.tar.gz diff --git a/SOURCES/0001-Enable-USB-controller-and-keyboard-for-aarch64-for-a.patch b/SOURCES/0001-Enable-USB-controller-and-keyboard-for-aarch64-for-a.patch new file mode 100644 index 0000000..9e596a0 --- /dev/null +++ b/SOURCES/0001-Enable-USB-controller-and-keyboard-for-aarch64-for-a.patch @@ -0,0 +1,26 @@ +From 54789ef242008cf12d651694a2aa8dd29b13ae1f Mon Sep 17 00:00:00 2001 +From: Alex Iribarren +Date: Tue, 22 Feb 2022 16:36:20 +0100 +Subject: [PATCH 01/21] Enable USB controller and keyboard for aarch64 for all + libvirt types + +--- + oz/Guest.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/oz/Guest.py b/oz/Guest.py +index d0e0f06..5197067 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -531,7 +531,7 @@ class Guest(object): + elif self.mousetype == "usb": + mousedict['type'] = 'tablet' + oz.ozutil.lxml_subelement(devices, "input", None, mousedict) +- if self.tdl.arch in ["aarch64", "armv7l"] and self.libvirt_type == "kvm": ++ if self.tdl.arch in ["aarch64", "armv7l"]: + # Other arches add a keyboard by default, for historical reasons ARM doesn't + # so we add it here so graphical works and hence we can get debug screenshots RHBZ 1538637 + oz.ozutil.lxml_subelement(devices, 'controller', None, {'type': 'usb', 'index': '0'}) +-- +2.43.0 + diff --git a/SOURCES/0001-tests-mock-network-functions-so-tests-work-with-no-n.patch b/SOURCES/0001-tests-mock-network-functions-so-tests-work-with-no-n.patch new file mode 100644 index 0000000..f6099a3 --- /dev/null +++ b/SOURCES/0001-tests-mock-network-functions-so-tests-work-with-no-n.patch @@ -0,0 +1,105 @@ +From a3dbafe9294948708da9e5030f044f695a99b999 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Thu, 25 Jan 2024 15:55:03 -0800 +Subject: [PATCH] tests: mock network functions so tests work with no network + +There's a few places where the tests implicitly need a network +connection. Mainly, since the TDL XML test blocks in test_guest +are for a subclass of RedHatLinuxCDYumGuest and specify a URL, +we wind up hitting RedHatLinuxCDYumGuest._check_url which tries +to get the headers for the URL to figure out if the server +supports byte ranges. Let's just mock out the header retrieval +to make that method happy. Secondly, test-53-command-http-url.tdl +specifies an HTTP URL, so we wind up trying to retrieve it; +mock out the actual download, since that's not what this test is +really exercising. + +Signed-off-by: Adam Williamson +--- + Containerfile.tests.el7 | 2 +- + README | 2 +- + tests/guest/test_guest.py | 9 ++++++++- + tests/tdl/test_tdl.py | 7 ++++++- + 4 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/Containerfile.tests.el7 b/Containerfile.tests.el7 +index 06a9b78..406fbb8 100644 +--- a/Containerfile.tests.el7 ++++ b/Containerfile.tests.el7 +@@ -4,7 +4,7 @@ + FROM quay.io/centos/centos:7 + RUN set -exo pipefail \ + && yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ +- && yum install -y python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic libvirt \ ++ && yum install -y python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic python-mock libvirt \ + && yum clean all \ + && rm -rf /var/cache/* /var/log/yum* + +diff --git a/README b/README +index 5f2c983..c53e23d 100644 +--- a/README ++++ b/README +@@ -28,7 +28,7 @@ dnf install python3-requests python3-m2crypto python3-libvirt python3-lxml pytho + + If you wish to test on EL 7, make that: + +-yum install python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic ++yum install python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic python-mock + + then run the tests: + +diff --git a/tests/guest/test_guest.py b/tests/guest/test_guest.py +index 625eb67..880807b 100644 +--- a/tests/guest/test_guest.py ++++ b/tests/guest/test_guest.py +@@ -12,6 +12,10 @@ except: + from io import StringIO + import logging + import os ++try: ++ from unittest import mock ++except ImportError: ++ import mock + + # Find oz library + prefix = '.' +@@ -72,7 +76,10 @@ def setup_guest(xml, macaddress=None): + config = configparser.ConfigParser() + config.read_file(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) + +- guest = oz.GuestFactory.guest_factory(tdl, config, None, macaddress=macaddress) ++ # mock this - it's used in RedHatLinuxCDYumGuest._check_url() - ++ # so the tests can run without a network connection ++ with mock.patch("oz.ozutil.http_get_header", return_value={}): ++ guest = oz.GuestFactory.guest_factory(tdl, config, None, macaddress=macaddress) + return guest + + tdlxml = """ +diff --git a/tests/tdl/test_tdl.py b/tests/tdl/test_tdl.py +index a94b2c1..badee63 100644 +--- a/tests/tdl/test_tdl.py ++++ b/tests/tdl/test_tdl.py +@@ -2,6 +2,10 @@ + + import sys + import os ++try: ++ from unittest import mock ++except ImportError: ++ import mock + + try: + import lxml.etree +@@ -97,7 +101,8 @@ tests = { + } + + # Test that iterates over all .tdl files +-def test_all(): ++@mock.patch("oz.ozutil.http_download_file") ++def test_all(fakedl): + for (tdl, expected_pass) in list(tests.items()): + + # locate full path for tdl file +-- +2.43.0 + diff --git a/SOURCES/0002-Revert-Don-t-write-kickstart-so-initial-setup-won-t-.patch b/SOURCES/0002-Revert-Don-t-write-kickstart-so-initial-setup-won-t-.patch new file mode 100644 index 0000000..a3abe4e --- /dev/null +++ b/SOURCES/0002-Revert-Don-t-write-kickstart-so-initial-setup-won-t-.patch @@ -0,0 +1,51 @@ +From 4477dea908ae3bae117fe3fa65d599f4ea52fd3b Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Thu, 24 Feb 2022 08:06:22 -0800 +Subject: [PATCH 02/21] Revert "Don't write kickstart so initial-setup won't + think root pw is set" + +This reverts commit ef55a6402143f810b7c221c2763b7eb52b4b8261. +It turns out to make things worse: the idea was that by not +writing the kickstart, initial-setup would correctly require +a root password to be set or admin account created, but in fact +it causes initial-setup not to run at all, because it assumes +the kickstart will always be present. See: +https://bugzilla.redhat.com/show_bug.cgi?id=2057600 +--- + oz/Fedora.py | 4 ---- + oz/RedHat.py | 4 ---- + 2 files changed, 8 deletions(-) + +diff --git a/oz/Fedora.py b/oz/Fedora.py +index 7ab800b..58557d7 100644 +--- a/oz/Fedora.py ++++ b/oz/Fedora.py +@@ -293,10 +293,6 @@ class FedoraGuest(oz.RedHat.RedHatLinuxCDYumGuest): + # out the method completely + if not self.config.brokenisomethod: + initrdline += " inst.method=cdrom:/dev/cdrom" +- # don't write the kickstart to the image, or else initial-setup +- # will think a root password has been set: +- # https://bugzilla.redhat.com/show_bug.cgi?id=2015490 +- initrdline += " inst.nosave=output_ks" + self._modify_isolinux(initrdline) + + def generate_diskimage(self, size=10, force=False): +diff --git a/oz/RedHat.py b/oz/RedHat.py +index 868b549..af00c11 100644 +--- a/oz/RedHat.py ++++ b/oz/RedHat.py +@@ -79,10 +79,6 @@ Subsystem sftp /usr/libexec/openssh/sftp-server + self.tdl.distro + self.tdl.update + self.tdl.arch + "-ramdisk") + + self.cmdline = "inst.method=" + self.url + " inst.ks=file:/ks.cfg" +- # don't write the kickstart to the image, or else initial-setup +- # will think a root password has been set: +- # https://bugzilla.redhat.com/show_bug.cgi?id=2015490 +- self.cmdline += " inst.nosave=output_ks" + if self.tdl.kernel_param: + self.cmdline += " " + self.tdl.kernel_param + +-- +2.43.0 + diff --git a/SOURCES/0003-Don-t-abort-when-the-data-in-_wait_for_install_finis.patch b/SOURCES/0003-Don-t-abort-when-the-data-in-_wait_for_install_finis.patch new file mode 100644 index 0000000..60dfa67 --- /dev/null +++ b/SOURCES/0003-Don-t-abort-when-the-data-in-_wait_for_install_finis.patch @@ -0,0 +1,32 @@ +From aac29e679b7c336537e93ce7b07c59e6b1a534ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Sun, 24 Apr 2022 15:47:21 +0200 +Subject: [PATCH 03/21] Don't abort when the data in _wait_for_install_finish + isn't valid utf-8 + +See https://www.scrye.com/wordpress/nirik/2022/04/21/another-tale-of-a-rawhide-compose-bug/ for context + +Decoding arbitrary data that happens to be valid utf-8 almost all the time +for logging purposes sounds like a good idea, until it isn't. +This way, the debug log will contain the data even if it's not valid utf-8, +instead of aborting the process with a UnicodeDecodeError. +--- + oz/Guest.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/oz/Guest.py b/oz/Guest.py +index 9cc80a6..ae954b8 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -848,7 +848,7 @@ class Guest(object): + # is no guarantee that we will get the whole write in one go + data = self.sock.recv(65536) + if data: +- self.log.debug(data.decode('utf-8')) ++ self.log.debug(data.decode('utf-8', errors='surrogateescape')) + except socket.timeout: + # the socket times out after 1 second. We can just fall + # through to the below code because it is a noop. +-- +2.43.0 + diff --git a/SOURCES/0004-Fix-for-running-on-python3-and-building-on-EL8-or-hi.patch b/SOURCES/0004-Fix-for-running-on-python3-and-building-on-EL8-or-hi.patch new file mode 100644 index 0000000..fc1da61 --- /dev/null +++ b/SOURCES/0004-Fix-for-running-on-python3-and-building-on-EL8-or-hi.patch @@ -0,0 +1,60 @@ +From cf560591d75adfbcf6688d11486f60c2d3a15942 Mon Sep 17 00:00:00 2001 +From: Neil Hanlon +Date: Mon, 4 Jul 2022 15:57:15 -0400 +Subject: [PATCH 04/21] Fix for running on python3 and building on EL8 or + higher + +--- + Makefile | 2 +- + oz.spec.in | 2 +- + setup.py | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index c8c5a54..fa81313 100644 +--- a/Makefile ++++ b/Makefile +@@ -2,7 +2,7 @@ VERSION = $(shell egrep "^VERSION" setup.py | awk '{print $$3}') + VENV_DIR = tests/.venv + + sdist: oz.spec.in +- python setup.py sdist ++ python3 setup.py sdist + + oz.spec: sdist + +diff --git a/oz.spec.in b/oz.spec.in +index e738026..37716b1 100644 +--- a/oz.spec.in ++++ b/oz.spec.in +@@ -25,7 +25,7 @@ Requires: libvirt >= 0.9.7 + Requires: python3-requests + Requires: genisoimage + Requires: mtools +-%if 0%{?fedora} < 26 ++%if 0%{?fedora} < 26 or 0%{?rhel} < 8 + Requires: python-uuid + %endif + Requires: openssh-clients +diff --git a/setup.py b/setup.py +index 8ca211f..22ec1fd 100644 +--- a/setup.py ++++ b/setup.py +@@ -23,12 +23,12 @@ class sdist(_sdist): + shell=True, + stdout=subprocess.PIPE).communicate()[0].strip() + date = time.strftime("%Y%m%d%H%M%S", time.gmtime()) +- git_release = "%sgit%s" % (date, git_head) ++ git_release = "%sgit%s" % (date, git_head.decode()) + + # Expand macros in oz.spec.in and create oz.spec + spec_in = open('oz.spec.in', 'r') + spec = open('oz.spec', 'w') +- for line in spec_in.xreadlines(): ++ for line in spec_in.readlines(): + if "@VERSION@" in line: + line = line.replace("@VERSION@", VERSION) + elif "@RELEASE@" in line: +-- +2.43.0 + diff --git a/SOURCES/0005-Fix-RHEL-templates-to-pass-required-useuefi-paramete.patch b/SOURCES/0005-Fix-RHEL-templates-to-pass-required-useuefi-paramete.patch new file mode 100644 index 0000000..7e91829 --- /dev/null +++ b/SOURCES/0005-Fix-RHEL-templates-to-pass-required-useuefi-paramete.patch @@ -0,0 +1,50 @@ +From b1cfd62c4fb90e4ebee218bd4a2e9e8f09d10c2b Mon Sep 17 00:00:00 2001 +From: Neil Hanlon +Date: Mon, 4 Jul 2022 15:57:42 -0400 +Subject: [PATCH 05/21] Fix RHEL templates to pass required useuefi parameter + +--- + oz/RHEL_8.py | 4 ++-- + oz/RHEL_9.py | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/oz/RHEL_8.py b/oz/RHEL_8.py +index 575f50e..49a6cff 100644 +--- a/oz/RHEL_8.py ++++ b/oz/RHEL_8.py +@@ -31,12 +31,12 @@ class RHEL8Guest(oz.RedHat.RedHatLinuxCDYumGuest): + Class for RHEL-8 installation + """ + def __init__(self, tdl, config, auto, output_disk=None, netdev=None, +- diskbus=None, macaddress=None): ++ diskbus=None, macaddress=None, useuefi=True): + # dnf distro + oz.RedHat.RedHatLinuxCDYumGuest.__init__(self, tdl, config, auto, + output_disk, netdev, diskbus, + True, True, "cpio", macaddress, +- False) ++ False, useuefi) + self.virtio_channel_name = 'org.fedoraproject.anaconda.log.0' + + def _modify_iso(self): +diff --git a/oz/RHEL_9.py b/oz/RHEL_9.py +index 7a9c90b..6a548b6 100644 +--- a/oz/RHEL_9.py ++++ b/oz/RHEL_9.py +@@ -31,11 +31,11 @@ class RHEL9Guest(oz.RHEL_8.RHEL8Guest): + Class for RHEL-9 installation + """ + def __init__(self, tdl, config, auto, output_disk=None, netdev=None, +- diskbus=None, macaddress=None): ++ diskbus=None, macaddress=None, useuefi=True): + # dnf distro + oz.RHEL_8.RHEL8Guest.__init__(self, tdl, config, auto, + output_disk, netdev, diskbus, +- macaddress) ++ macaddress, useuefi) + + # method and ks options were dropped + self.cmdline = "inst.repo=" + self.url + " inst.ks=file:/ks.cfg" +-- +2.43.0 + diff --git a/SOURCES/0006-Use-discard-unmap-for-images.patch b/SOURCES/0006-Use-discard-unmap-for-images.patch new file mode 100644 index 0000000..df4baf3 --- /dev/null +++ b/SOURCES/0006-Use-discard-unmap-for-images.patch @@ -0,0 +1,27 @@ +From 7ae8898e4a0264b8eb6ea7b89d3269bf16bc5dce Mon Sep 17 00:00:00 2001 +From: Tomas Kopecek +Date: Mon, 22 Aug 2022 17:50:57 +0200 +Subject: [PATCH 06/21] Use discard=unmap for images + +Related: https://github.com/clalancette/oz/issues/302 +Related: https://pagure.io/koji/issue/3473 +--- + oz/Guest.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/oz/Guest.py b/oz/Guest.py +index ae954b8..f1ca403 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -553,7 +553,7 @@ class Guest(object): + bootDisk = oz.ozutil.lxml_subelement(devices, "disk", None, {'device': 'disk', 'type': 'file'}) + oz.ozutil.lxml_subelement(bootDisk, "target", None, {'dev': self.disk_dev, 'bus': self.disk_bus}) + oz.ozutil.lxml_subelement(bootDisk, "source", None, {'file': self.diskimage}) +- oz.ozutil.lxml_subelement(bootDisk, "driver", None, {'name': 'qemu', 'type': self.image_type}) ++ oz.ozutil.lxml_subelement(bootDisk, "driver", None, {'name': 'qemu', 'type': self.image_type, 'discard': 'unmap'}) + # install disk (if any) + if not installdev: + installdev_list = [] +-- +2.43.0 + diff --git a/SOURCES/0007-Don-t-write-kickstart-so-initial-setup-won-t-think-r.patch b/SOURCES/0007-Don-t-write-kickstart-so-initial-setup-won-t-think-r.patch new file mode 100644 index 0000000..ae5da75 --- /dev/null +++ b/SOURCES/0007-Don-t-write-kickstart-so-initial-setup-won-t-think-r.patch @@ -0,0 +1,46 @@ +From b6f74850e8bca82c5596394e8c3ccfa682c4fe52 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Sat, 5 Feb 2022 13:38:34 +0000 +Subject: [PATCH 07/21] Don't write kickstart so initial-setup won't think root + pw is set + +Signed-off-by: Adam Williamson +Signed-off-by: Peter Robinson +--- + oz/Fedora.py | 4 ++++ + oz/RedHat.py | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/oz/Fedora.py b/oz/Fedora.py +index 58557d7..7ab800b 100644 +--- a/oz/Fedora.py ++++ b/oz/Fedora.py +@@ -293,6 +293,10 @@ class FedoraGuest(oz.RedHat.RedHatLinuxCDYumGuest): + # out the method completely + if not self.config.brokenisomethod: + initrdline += " inst.method=cdrom:/dev/cdrom" ++ # don't write the kickstart to the image, or else initial-setup ++ # will think a root password has been set: ++ # https://bugzilla.redhat.com/show_bug.cgi?id=2015490 ++ initrdline += " inst.nosave=output_ks" + self._modify_isolinux(initrdline) + + def generate_diskimage(self, size=10, force=False): +diff --git a/oz/RedHat.py b/oz/RedHat.py +index af00c11..868b549 100644 +--- a/oz/RedHat.py ++++ b/oz/RedHat.py +@@ -79,6 +79,10 @@ Subsystem sftp /usr/libexec/openssh/sftp-server + self.tdl.distro + self.tdl.update + self.tdl.arch + "-ramdisk") + + self.cmdline = "inst.method=" + self.url + " inst.ks=file:/ks.cfg" ++ # don't write the kickstart to the image, or else initial-setup ++ # will think a root password has been set: ++ # https://bugzilla.redhat.com/show_bug.cgi?id=2015490 ++ self.cmdline += " inst.nosave=output_ks" + if self.tdl.kernel_param: + self.cmdline += " " + self.tdl.kernel_param + +-- +2.43.0 + diff --git a/SOURCES/0008-Python-3-compat-fixes-py.test-and-ConfigParser.patch b/SOURCES/0008-Python-3-compat-fixes-py.test-and-ConfigParser.patch new file mode 100644 index 0000000..9e8d727 --- /dev/null +++ b/SOURCES/0008-Python-3-compat-fixes-py.test-and-ConfigParser.patch @@ -0,0 +1,562 @@ +From 4c894b9ebb23909a54d6a1282eb528bb0917931a Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 14:48:33 -0800 +Subject: [PATCH 08/21] Python 3 compat fixes: py.test and ConfigParser + +Signed-off-by: Adam Williamson +--- + oz/RedHat.py | 10 ++++- + oz/ozutil.py | 12 +++++- + tests/factory/test_factory.py | 14 +++++-- + tests/guest/test_guest.py | 71 +++++++++++++++++++++-------------- + tests/ozutil/test_ozutil.py | 50 ++++++++++++------------ + tests/tdl/test_tdl.py | 4 +- + 6 files changed, 97 insertions(+), 64 deletions(-) + +diff --git a/oz/RedHat.py b/oz/RedHat.py +index 868b549..57e43f4 100644 +--- a/oz/RedHat.py ++++ b/oz/RedHat.py +@@ -507,8 +507,14 @@ echo -n "!$ADDR,%s!" > %s + initrd paths out of it. + """ + self.log.debug("Got treeinfo, parsing") +- config = configparser.SafeConfigParser() +- config.readfp(fp) ++ try: ++ config = configparser.SafeConfigParser() ++ config.readfp(fp) ++ except AttributeError: ++ # SafeConfigParser was deprecated in Python 3.2 and readfp ++ # was renamed to read_file ++ config = configparser.ConfigParser() ++ config.read_file(fp) + section = "images-%s" % (self.tdl.arch) + kernel = oz.ozutil.config_get_key(config, section, "kernel", None) + initrd = oz.ozutil.config_get_key(config, section, "initrd", None) +diff --git a/oz/ozutil.py b/oz/ozutil.py +index 3a861be..5e90797 100644 +--- a/oz/ozutil.py ++++ b/oz/ozutil.py +@@ -724,12 +724,20 @@ def parse_config(config_file): + Function to parse the configuration file. If the passed in config_file is + None, then the default configuration file is used. + """ +- config = configparser.SafeConfigParser() ++ try: ++ config = configparser.SafeConfigParser() ++ except AttributeError: ++ # SafeConfigParser was deprecated in Python 3.2 ++ config = configparser.ConfigParser() + if config_file is not None: + # If the config_file passed in is not None, then we want to try to read + # that config file (after expanding it). If that config file doesn't + # exist, we want to throw an error (which is why we use readfp here). +- config.readfp(open(os.path.expanduser(config_file))) ++ try: ++ config.readfp(open(os.path.expanduser(config_file))) ++ except AttributeError: ++ # readfp was renamed to read_file in Python 3.2 ++ config.read_file(open(os.path.expanduser(config_file))) + else: + # The config file was not passed in, so we want to use one of the + # defaults. First we check to see if a ~/.oz/oz.cfg exists; if it does, +diff --git a/tests/factory/test_factory.py b/tests/factory/test_factory.py +index 8f08b62..1328b9f 100755 +--- a/tests/factory/test_factory.py ++++ b/tests/factory/test_factory.py +@@ -31,9 +31,9 @@ except ImportError as e: + sys.exit(1) + + try: +- import py.test ++ import pytest + except ImportError: +- print('Unable to import py.test. Is py.test installed?') ++ print('Unable to import pytest. Is pytest installed?') + sys.exit(1) + + def default_route(): +@@ -87,8 +87,14 @@ def runtest(**kwargs): + try: + tdl = oz.TDL.TDL(tdlxml) + +- config = configparser.SafeConfigParser() +- config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ try: ++ config = configparser.SafeConfigParser() ++ config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ except AttributeError: ++ # SafeConfigParser was deprecated in Python 3.2 and ++ # readfp was renamed to read_file ++ config = configparser.ConfigParser() ++ config.read_file(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) + + if os.getenv('DEBUG') is not None: + logging.basicConfig(level=logging.DEBUG, format="%(message)s") +diff --git a/tests/guest/test_guest.py b/tests/guest/test_guest.py +index 71e869a..19b0863 100644 +--- a/tests/guest/test_guest.py ++++ b/tests/guest/test_guest.py +@@ -31,9 +31,9 @@ except ImportError as e: + sys.exit(1) + + try: +- import py.test ++ import pytest + except ImportError: +- print('Unable to import py.test. Is py.test installed?') ++ print('Unable to import pytest. Is pytest installed?') + sys.exit(1) + + def default_route(): +@@ -63,8 +63,14 @@ route = default_route() + def setup_guest(xml, macaddress=None): + tdl = oz.TDL.TDL(xml) + +- config = configparser.SafeConfigParser() +- config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ try: ++ config = configparser.SafeConfigParser() ++ config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ except AttributeError: ++ # SafeConfigParser was deprecated in Python 3.2 and readfp ++ # was renamed to read_file ++ config = configparser.ConfigParser() ++ config.read_file(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) + + guest = oz.GuestFactory.guest_factory(tdl, config, None, macaddress=macaddress) + return guest +@@ -104,7 +110,7 @@ tdlxml2 = """ + def test_geteltorito_none_src(): + guest = setup_guest(tdlxml) + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(None, None) + + def test_geteltorito_none_dst(tmpdir): +@@ -113,7 +119,7 @@ def test_geteltorito_none_dst(tmpdir): + src = os.path.join(str(tmpdir), 'src') + open(src, 'w').write('src') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, None) + + def test_geteltorito_short_pvd(tmpdir): +@@ -124,7 +130,7 @@ def test_geteltorito_short_pvd(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_pvd_desc(tmpdir): +@@ -138,7 +144,7 @@ def test_geteltorito_bogus_pvd_desc(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_pvd_ident(tmpdir): +@@ -153,7 +159,7 @@ def test_geteltorito_bogus_pvd_ident(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_pvd_unused(tmpdir): +@@ -170,7 +176,7 @@ def test_geteltorito_bogus_pvd_unused(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_pvd_unused2(tmpdir): +@@ -191,7 +197,7 @@ def test_geteltorito_bogus_pvd_unused2(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_short_boot_sector(tmpdir): +@@ -212,7 +218,7 @@ def test_geteltorito_short_boot_sector(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_boot_sector(tmpdir): +@@ -236,7 +242,7 @@ def test_geteltorito_bogus_boot_sector(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_boot_isoident(tmpdir): +@@ -261,7 +267,7 @@ def test_geteltorito_bogus_boot_isoident(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_boot_version(tmpdir): +@@ -286,7 +292,7 @@ def test_geteltorito_bogus_boot_version(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_boot_torito(tmpdir): +@@ -312,7 +318,7 @@ def test_geteltorito_bogus_boot_torito(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(oz.OzException.OzException): ++ with pytest.raises(oz.OzException.OzException): + guest._geteltorito(src, dst) + + def test_geteltorito_bogus_bootp(tmpdir): +@@ -340,7 +346,7 @@ def test_geteltorito_bogus_bootp(tmpdir): + + dst = os.path.join(str(tmpdir), 'dst') + +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + guest._geteltorito(src, dst) + + def test_init_guest(): +@@ -354,9 +360,16 @@ def test_init_guest(): + def test_init_guest_bad_arch(): + tdl = oz.TDL.TDL(tdlxml) + tdl.arch = 'armhf' # Done here to make sure the TDL class doesn't error +- config = configparser.SafeConfigParser() +- config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) +- with py.test.raises(Exception): ++ try: ++ config = configparser.SafeConfigParser() ++ config.readfp(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ except AttributeError: ++ # SafeConfigParser was deprecated in Python 3.2 and readfp ++ # was renamed to read_file ++ config = configparser.ConfigParser() ++ config.read_file(StringIO("[libvirt]\nuri=qemu:///session\nbridge_name=%s" % route)) ++ ++ with pytest.raises(Exception): + oz.GuestFactory.guest_factory(tdl, config, None) + + def test_icicle_generation(): +@@ -490,7 +503,7 @@ def test_get_disks_and_interfaces_missing_interface_target(): + + # Get the comparision xml + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._get_disks_and_interfaces(test_xml) +@@ -503,7 +516,7 @@ def test_get_disks_and_interfaces_missing_interface_target_device(): + + # Get the comparision xml + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._get_disks_and_interfaces(test_xml) +@@ -516,7 +529,7 @@ def test_get_disks_and_interfaces_missing_disk_target(): + + # Get the comparision xml + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._get_disks_and_interfaces(test_xml) +@@ -528,7 +541,7 @@ def test_get_disks_and_interfaces_missing_disk_target_device(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_get_disks_and_interfaces_missing_disk_target_device.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._get_disks_and_interfaces(test_xml) +@@ -557,7 +570,7 @@ def test_modify_libvirt_xml_for_serial_too_many_targets(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_modify_libvirt_xml_for_serial_too_many_targets.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._modify_libvirt_xml_for_serial(test_xml) +@@ -569,7 +582,7 @@ def test_modify_libvirt_xml_for_serial_missing_devices(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_modify_libvirt_xml_for_serial_missing_devices.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._modify_libvirt_xml_for_serial(test_xml) +@@ -581,7 +594,7 @@ def test_modify_libvirt_xml_for_serial_too_many_devices(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_modify_libvirt_xml_for_serial_too_many_devices.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._modify_libvirt_xml_for_serial(test_xml) +@@ -614,7 +627,7 @@ def test_modify_libvirt_xml_diskimage_missing_disk_source(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_modify_libvirt_xml_diskimage_missing_disk_source.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._modify_libvirt_xml_diskimage(test_xml, guest.diskimage, 'qcow2') +@@ -626,7 +639,7 @@ def test_modify_libvirt_xml_diskimage_too_many_drivers(): + # Get the comparision xml + path = os.path.dirname(__file__) + '/libvirt/test_modify_libvirt_xml_diskimage_too_many_drivers.xml' + with open(path, 'r') as handle: +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + # Replace various smaller items as they are auto generated + test_xml = handle.read() % (guest.uuid, route, guest.listen_port, guest.diskimage) + guest._modify_libvirt_xml_diskimage(test_xml, guest.diskimage, 'qcow2') +diff --git a/tests/ozutil/test_ozutil.py b/tests/ozutil/test_ozutil.py +index dd84f5b..4624251 100644 +--- a/tests/ozutil/test_ozutil.py ++++ b/tests/ozutil/test_ozutil.py +@@ -4,9 +4,9 @@ import sys + import os + + try: +- import py.test ++ import pytest + except ImportError: +- print('Unable to import py.test. Is py.test installed?') ++ print('Unable to import pytest. Is pytest installed?') + sys.exit(1) + + # Find oz +@@ -29,7 +29,7 @@ def test_auto(): + assert(oz.ozutil.generate_full_auto_path('fedora-14-jeos.ks') == os.path.realpath(os.path.join(prefix, 'oz', 'auto', 'fedora-14-jeos.ks'))) + + def test_auto_none(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.generate_full_auto_path(None) + + # test oz.ozutil.executable_exists +@@ -37,33 +37,33 @@ def test_exe_exists_bin_ls(): + assert(oz.ozutil.executable_exists('/bin/ls')) + + def test_exe_exists_foo(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.executable_exists('foo') + + def test_exe_exists_full_foo(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.executable_exists('/bin/foo') + + def test_exe_exists_not_x(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.executable_exists('/etc/hosts') + + def test_exe_exists_relative_false(): + assert(oz.ozutil.executable_exists('false')) + + def test_exe_exists_none(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.executable_exists(None) + + # test oz.ozutil.copyfile_sparse + def test_copy_sparse_none_src(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copyfile_sparse(None, None) + + def test_copy_sparse_none_dst(tmpdir): + fullname = os.path.join(str(tmpdir), 'src') + open(fullname, 'w').write('src') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copyfile_sparse(fullname, None) + + def test_copy_sparse_bad_src_mode(tmpdir): +@@ -75,7 +75,7 @@ def test_copy_sparse_bad_src_mode(tmpdir): + os.chmod(fullname, 0000) + # because copyfile_sparse uses os.open() instead of open(), it throws an + # OSError +- with py.test.raises(OSError): ++ with pytest.raises(OSError): + oz.ozutil.copyfile_sparse(fullname, 'output') + + def test_copy_sparse_bad_dst_mode(tmpdir): +@@ -87,7 +87,7 @@ def test_copy_sparse_bad_dst_mode(tmpdir): + dstname = os.path.join(str(tmpdir), 'dst') + open(dstname, 'w').write('dst') + os.chmod(dstname, 0o444) +- with py.test.raises(OSError): ++ with pytest.raises(OSError): + oz.ozutil.copyfile_sparse(srcname, dstname) + + def test_copy_sparse_zero_size_src(tmpdir): +@@ -151,7 +151,7 @@ def test_copy_sparse_src_not_exists(tmpdir): + srcname = os.path.join(str(tmpdir), 'src') + dstname = os.path.join(str(tmpdir), 'dst') + open(dstname, 'w').write('dst') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copyfile_sparse(srcname, dstname) + + def test_copy_sparse_dest_not_exists(tmpdir): +@@ -164,13 +164,13 @@ def test_copy_sparse_dest_not_exists(tmpdir): + def test_copy_sparse_src_is_dir(tmpdir): + dstname = os.path.join(str(tmpdir), 'dst') + open(dstname, 'w').write('dst') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copyfile_sparse(tmpdir, dstname) + + def test_copy_sparse_dst_is_dir(tmpdir): + srcname = os.path.join(str(tmpdir), 'src') + open(srcname, 'w').write('src') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copyfile_sparse(srcname, tmpdir) + + # test oz.ozutil.string_to_bool +@@ -205,7 +205,7 @@ def test_stb_true(): + assert(oz.ozutil.string_to_bool(curr) == True) + + def test_stb_none(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.string_to_bool(None) + + +@@ -231,11 +231,11 @@ def test_mkdir_p_twice(tmpdir): + def test_mkdir_p_file_exists(tmpdir): + fullname = os.path.join(str(tmpdir), 'file_exists') + open(fullname, 'w').write('file_exists') +- with py.test.raises(OSError): ++ with pytest.raises(OSError): + oz.ozutil.mkdir_p(fullname) + + def test_mkdir_p_none(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.mkdir_p(None) + + def test_mkdir_p_empty_string(): +@@ -243,20 +243,20 @@ def test_mkdir_p_empty_string(): + + # test oz.ozutil.copy_modify_file + def test_copy_modify_none_src(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copy_modify_file(None, None, None) + + def test_copy_modify_none_dst(tmpdir): + fullname = os.path.join(str(tmpdir), 'src') + open(fullname, 'w').write('src') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copy_modify_file(fullname, None, None) + + def test_copy_modify_none_subfunc(tmpdir): + src = os.path.join(str(tmpdir), 'src') + open(src, 'w').write('src') + dst = os.path.join(str(tmpdir), 'dst') +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.copy_modify_file(src, dst, None) + + def test_copy_modify_bad_src_mode(tmpdir): +@@ -269,7 +269,7 @@ def test_copy_modify_bad_src_mode(tmpdir): + open(fullname, 'w').write('writeonly') + os.chmod(fullname, 0000) + dst = os.path.join(str(tmpdir), 'dst') +- with py.test.raises(IOError): ++ with pytest.raises(IOError): + oz.ozutil.copy_modify_file(fullname, dst, sub) + + def test_copy_modify_empty_file(tmpdir): +@@ -295,11 +295,11 @@ def test_copy_modify_file(tmpdir): + + # test oz.ozutil.write_cpio + def test_write_cpio_none_input(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.write_cpio(None, None) + + def test_write_cpio_none_output(): +- with py.test.raises(Exception): ++ with pytest.raises(Exception): + oz.ozutil.write_cpio({}, None) + + def test_write_cpio_empty_dict(tmpdir): +@@ -313,7 +313,7 @@ def test_write_cpio_existing_file(tmpdir): + dst = os.path.join(str(tmpdir), 'dst') + open(dst, 'w').write('hello') + os.chmod(dst, 0000) +- with py.test.raises(IOError): ++ with pytest.raises(IOError): + oz.ozutil.write_cpio({}, dst) + + def test_write_cpio_single_file(tmpdir): +@@ -344,7 +344,7 @@ def test_write_cpio_exception(tmpdir): + open(src, 'w').write('src') + os.chmod(src, 0000) + dst = os.path.join(str(tmpdir), 'dst') +- with py.test.raises(IOError): ++ with pytest.raises(IOError): + oz.ozutil.write_cpio({src: 'src'}, dst) + + def test_md5sum_regular(tmpdir): +diff --git a/tests/tdl/test_tdl.py b/tests/tdl/test_tdl.py +index 6846ef1..a94b2c1 100644 +--- a/tests/tdl/test_tdl.py ++++ b/tests/tdl/test_tdl.py +@@ -10,9 +10,9 @@ except ImportError: + sys.exit(1) + + try: +- import py.test ++ import pytest + except ImportError: +- print('Unable to import py.test. Is py.test installed?') ++ print('Unable to import pytest. Is pytest installed?') + sys.exit(1) + + # Find oz +-- +2.43.0 + diff --git a/SOURCES/0009-Unpick-unnecessary-useuefi-arg-on-the-Guest-classes.patch b/SOURCES/0009-Unpick-unnecessary-useuefi-arg-on-the-Guest-classes.patch new file mode 100644 index 0000000..f7a438c --- /dev/null +++ b/SOURCES/0009-Unpick-unnecessary-useuefi-arg-on-the-Guest-classes.patch @@ -0,0 +1,205 @@ +From ccfcee509da595415582ca168c67e960d77795da Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 14:57:16 -0800 +Subject: [PATCH 09/21] Unpick unnecessary 'useuefi' arg on the Guest classes + +b7728d5 added this new mandatory argument on the Guest class. But +it doesn't use it at all. The only code in the commit that uses +anything called 'useuefi' is the little bit added to +_generate_xml() - but that checks self.config.useuefi, which is +a property of the FedoraConfiguration config class, not anything +to do with the Guest class itself. None of the __init__ methods +on Guest or its subclasses that added this new 'useuefi' arg ever +did anything with it. + +This broke every guest class which didn't have the useless new +argument added to it, which seems to be most of the non-Fedora/ +non-RHEL ones. They're probably broken in other ways anyway, +but this didn't help. It makes a large swathe of the test suite +fail. + +This dumps the useless arg from all Guest classes, and makes the +check in _generate_xml() safe for config classes which do not +have the useuefi property at all, which is all the non-Fedora +ones. + +Signed-off-by: Adam Williamson +--- + oz/Fedora.py | 5 ++--- + oz/Guest.py | 12 ++++++------ + oz/Linux.py | 4 ++-- + oz/RHEL_8.py | 4 ++-- + oz/RHEL_9.py | 4 ++-- + oz/RedHat.py | 12 ++++++------ + 6 files changed, 20 insertions(+), 21 deletions(-) + +diff --git a/oz/Fedora.py b/oz/Fedora.py +index 7ab800b..89ecca8 100644 +--- a/oz/Fedora.py ++++ b/oz/Fedora.py +@@ -248,7 +248,7 @@ class FedoraGuest(oz.RedHat.RedHatLinuxCDYumGuest): + # ignored now; we leave it in place for backwards API compatibility. + def __init__(self, tdl, config, auto, nicmodel, haverepo, diskbus, # pylint: disable=unused-argument + brokenisomethod, output_disk=None, macaddress=None, # pylint: disable=unused-argument +- assumed_update=None, useuefi=False): ++ assumed_update=None): + if int(tdl.update) < 31: + self.config = version_to_config[tdl.update] + else: +@@ -263,8 +263,7 @@ class FedoraGuest(oz.RedHat.RedHatLinuxCDYumGuest): + oz.RedHat.RedHatLinuxCDYumGuest.__init__(self, tdl, config, auto, + output_disk, nicmodel, diskbus, + True, True, self.config.directkernel, +- macaddress, self.config.use_yum, +- self.config.useuefi) ++ macaddress, self.config.use_yum) + + if self.assumed_update is not None: + self.log.warning("==== WARN: TDL contains Fedora update %s, which is newer than Oz knows about; pretending this is Fedora %s, but this may fail ====", tdl.update, assumed_update) +diff --git a/oz/Guest.py b/oz/Guest.py +index f1ca403..249cce0 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -129,7 +129,7 @@ class Guest(object): + self._discover_libvirt_type() + + def __init__(self, tdl, config, auto, output_disk, nicmodel, clockoffset, +- mousetype, diskbus, iso_allowed, url_allowed, macaddress, useuefi): ++ mousetype, diskbus, iso_allowed, url_allowed, macaddress): + self.tdl = tdl + + # for backwards compatibility +@@ -502,7 +502,7 @@ class Guest(object): + oz.ozutil.lxml_subelement(osNode, "loader", loader, {'readonly': 'yes', 'type': 'pflash'}) + oz.ozutil.lxml_subelement(osNode, "nvram", None, {'template': nvram}) + # x86_64 has legacy requirements so we check for defaults as well as for edk2 +- if self.tdl.arch in ["x86_64"] and self.config.useuefi == True: ++ if self.tdl.arch == "x86_64" and hasattr(self.config, "useuefi") and self.config.useuefi is True: + loader, nvram = oz.ozutil.find_uefi_firmware(self.tdl.arch) + oz.ozutil.lxml_subelement(osNode, "loader", loader, {'readonly': 'yes', 'type': 'pflash'}) + oz.ozutil.lxml_subelement(osNode, "nvram", None, {'template': nvram}) +@@ -1333,10 +1333,10 @@ class CDGuest(Guest): + self.seqnum = seqnum + + def __init__(self, tdl, config, auto, output_disk, nicmodel, clockoffset, +- mousetype, diskbus, iso_allowed, url_allowed, macaddress, useuefi): ++ mousetype, diskbus, iso_allowed, url_allowed, macaddress): + Guest.__init__(self, tdl, config, auto, output_disk, nicmodel, + clockoffset, mousetype, diskbus, iso_allowed, +- url_allowed, macaddress, useuefi) ++ url_allowed, macaddress) + + self.orig_iso = os.path.join(self.data_dir, "isos", + self.tdl.distro + self.tdl.update + self.tdl.arch + "-" + self.tdl.installtype + ".iso") +@@ -1801,9 +1801,9 @@ class FDGuest(Guest): + Class for guest installation via floppy disk. + """ + def __init__(self, tdl, config, auto, output_disk, nicmodel, clockoffset, +- mousetype, diskbus, macaddress, useuefi): ++ mousetype, diskbus, macaddress): + Guest.__init__(self, tdl, config, auto, output_disk, nicmodel, +- clockoffset, mousetype, diskbus, False, True, macaddress, useuefi) ++ clockoffset, mousetype, diskbus, False, True, macaddress) + self.orig_floppy = os.path.join(self.data_dir, "floppies", + self.tdl.distro + self.tdl.update + self.tdl.arch + ".img") + self.modified_floppy_cache = os.path.join(self.data_dir, "floppies", +diff --git a/oz/Linux.py b/oz/Linux.py +index aee7abe..f15260a 100644 +--- a/oz/Linux.py ++++ b/oz/Linux.py +@@ -33,10 +33,10 @@ class LinuxCDGuest(oz.Guest.CDGuest): + Class for Linux installation. + """ + def __init__(self, tdl, config, auto, output_disk, nicmodel, diskbus, +- iso_allowed, url_allowed, macaddress, useuefi): ++ iso_allowed, url_allowed, macaddress): + oz.Guest.CDGuest.__init__(self, tdl, config, auto, output_disk, + nicmodel, None, None, diskbus, iso_allowed, +- url_allowed, macaddress, useuefi) ++ url_allowed, macaddress) + + def _test_ssh_connection(self, guestaddr): + """ +diff --git a/oz/RHEL_8.py b/oz/RHEL_8.py +index 49a6cff..575f50e 100644 +--- a/oz/RHEL_8.py ++++ b/oz/RHEL_8.py +@@ -31,12 +31,12 @@ class RHEL8Guest(oz.RedHat.RedHatLinuxCDYumGuest): + Class for RHEL-8 installation + """ + def __init__(self, tdl, config, auto, output_disk=None, netdev=None, +- diskbus=None, macaddress=None, useuefi=True): ++ diskbus=None, macaddress=None): + # dnf distro + oz.RedHat.RedHatLinuxCDYumGuest.__init__(self, tdl, config, auto, + output_disk, netdev, diskbus, + True, True, "cpio", macaddress, +- False, useuefi) ++ False) + self.virtio_channel_name = 'org.fedoraproject.anaconda.log.0' + + def _modify_iso(self): +diff --git a/oz/RHEL_9.py b/oz/RHEL_9.py +index 6a548b6..7a9c90b 100644 +--- a/oz/RHEL_9.py ++++ b/oz/RHEL_9.py +@@ -31,11 +31,11 @@ class RHEL9Guest(oz.RHEL_8.RHEL8Guest): + Class for RHEL-9 installation + """ + def __init__(self, tdl, config, auto, output_disk=None, netdev=None, +- diskbus=None, macaddress=None, useuefi=True): ++ diskbus=None, macaddress=None): + # dnf distro + oz.RHEL_8.RHEL8Guest.__init__(self, tdl, config, auto, + output_disk, netdev, diskbus, +- macaddress, useuefi) ++ macaddress) + + # method and ks options were dropped + self.cmdline = "inst.repo=" + self.url + " inst.ks=file:/ks.cfg" +diff --git a/oz/RedHat.py b/oz/RedHat.py +index 57e43f4..e7c42ba 100644 +--- a/oz/RedHat.py ++++ b/oz/RedHat.py +@@ -40,10 +40,10 @@ class RedHatLinuxCDGuest(oz.Linux.LinuxCDGuest): + Class for RedHat-based CD guests. + """ + def __init__(self, tdl, config, auto, output_disk, nicmodel, diskbus, +- iso_allowed, url_allowed, initrdtype, macaddress, useuefi): ++ iso_allowed, url_allowed, initrdtype, macaddress): + oz.Linux.LinuxCDGuest.__init__(self, tdl, config, auto, output_disk, + nicmodel, diskbus, iso_allowed, +- url_allowed, macaddress, useuefi) ++ url_allowed, macaddress) + self.crond_was_active = False + self.sshd_was_active = False + self.sshd_config = """\ +@@ -732,11 +732,11 @@ class RedHatLinuxCDYumGuest(RedHatLinuxCDGuest): + Class for RedHat-based CD guests with yum support. + """ + def __init__(self, tdl, config, auto, output_disk, nicmodel, diskbus, +- iso_allowed, url_allowed, initrdtype, macaddress, use_yum, useuefi): ++ iso_allowed, url_allowed, initrdtype, macaddress, use_yum): + oz.RedHat.RedHatLinuxCDGuest.__init__(self, tdl, config, auto, + output_disk, nicmodel, diskbus, + iso_allowed, url_allowed, +- initrdtype, macaddress, useuefi) ++ initrdtype, macaddress) + + self.use_yum = use_yum + +@@ -855,9 +855,9 @@ class RedHatFDGuest(oz.Guest.FDGuest): + Class for RedHat-based floppy guests. + """ + def __init__(self, tdl, config, auto, output_disk, nicmodel, diskbus, +- macaddress, useuefi): ++ macaddress): + oz.Guest.FDGuest.__init__(self, tdl, config, auto, output_disk, +- nicmodel, None, None, diskbus, macaddress, useuefi) ++ nicmodel, None, None, diskbus, macaddress) + + if self.tdl.arch != "i386": + raise oz.OzException.OzException("Invalid arch " + self.tdl.arch + "for " + self.tdl.distro + " guest") +-- +2.43.0 + diff --git a/SOURCES/0010-Python-compat-Callable-is-in-collections.abc-since-P.patch b/SOURCES/0010-Python-compat-Callable-is-in-collections.abc-since-P.patch new file mode 100644 index 0000000..1534e41 --- /dev/null +++ b/SOURCES/0010-Python-compat-Callable-is-in-collections.abc-since-P.patch @@ -0,0 +1,39 @@ +From 743dfced8adffbb5103867cd44857bdcbb8eb2a8 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 15:10:02 -0800 +Subject: [PATCH 10/21] Python compat: Callable is in collections.abc since + Python 3.3 + +Signed-off-by: Adam Williamson +--- + oz/ozutil.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/oz/ozutil.py b/oz/ozutil.py +index 5e90797..689559f 100644 +--- a/oz/ozutil.py ++++ b/oz/ozutil.py +@@ -19,7 +19,10 @@ + Miscellaneous utility functions. + """ + +-import collections ++try: ++ from collections.abc import Callable ++except ImportError: ++ from collections import Callable + try: + import configparser + except ImportError: +@@ -536,7 +539,7 @@ def copy_modify_file(inname, outname, subfunc): + raise Exception("output filename is None") + if subfunc is None: + raise Exception("subfunction is None") +- if not isinstance(subfunc, collections.Callable): ++ if not isinstance(subfunc, Callable): + raise Exception("subfunction is not callable") + + infile = open(inname, 'r') +-- +2.43.0 + diff --git a/SOURCES/0011-Tests-multiple-fixes-to-expected-guest-XML.patch b/SOURCES/0011-Tests-multiple-fixes-to-expected-guest-XML.patch new file mode 100644 index 0000000..972dbea --- /dev/null +++ b/SOURCES/0011-Tests-multiple-fixes-to-expected-guest-XML.patch @@ -0,0 +1,102 @@ +From 73b291eb61413348c07736208d44a7e0734a5dc5 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 15:20:53 -0800 +Subject: [PATCH 11/21] Tests: multiple fixes to expected guest XML + +The test_xml_generation_1 and _2 tests failed because multiple +changes were merged which change the generated libvirt guest +XML without the test data being updated: + +f20a5f9b05a05e88a12cff05483649a550e95491 - bumped memory to 2G +f73d7cff45504deb36b502d073157576528a6eb3 - added host-passthrough +e8ae9de009d55d73e68f6d0030e88389825a242a - added rng +7ae8898e4a0264b8eb6ea7b89d3269bf16bc5dce - added discard=unmap + +Apparently not one of the authors or reviewers of any of those +commits ever ran the test suite. + +Signed-off-by: Adam Williamson +--- + tests/guest/libvirt/test_xml_generation_1.xml | 11 ++++++++--- + tests/guest/libvirt/test_xml_generation_2.xml | 11 ++++++++--- + 2 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/tests/guest/libvirt/test_xml_generation_1.xml b/tests/guest/libvirt/test_xml_generation_1.xml +index e976d85..a8ad4d8 100644 +--- a/tests/guest/libvirt/test_xml_generation_1.xml ++++ b/tests/guest/libvirt/test_xml_generation_1.xml +@@ -1,7 +1,7 @@ + + tester +- 1048576 +- 1048576 ++ 2097152 ++ 2097152 + %s + + 1 +@@ -10,6 +10,7 @@ + + + ++ + + hvm + +@@ -33,10 +34,14 @@ + + + ++ ++ ++ /dev/random ++ + + + +- ++ + + + +diff --git a/tests/guest/libvirt/test_xml_generation_2.xml b/tests/guest/libvirt/test_xml_generation_2.xml +index 148c113..cf6feb4 100644 +--- a/tests/guest/libvirt/test_xml_generation_2.xml ++++ b/tests/guest/libvirt/test_xml_generation_2.xml +@@ -1,7 +1,7 @@ + + tester +- 1048576 +- 1048576 ++ 2097152 ++ 2097152 + %s + + 1 +@@ -10,6 +10,7 @@ + + + ++ + + hvm + +@@ -36,10 +37,14 @@ + + + ++ ++ ++ /dev/random ++ + + + +- ++ + + + +-- +2.43.0 + diff --git a/SOURCES/0012-Add-testing-instructions-to-README.patch b/SOURCES/0012-Add-testing-instructions-to-README.patch new file mode 100644 index 0000000..40a08e9 --- /dev/null +++ b/SOURCES/0012-Add-testing-instructions-to-README.patch @@ -0,0 +1,40 @@ +From 3b96485ed42b2e3c048bbb2b05640343e61d50de Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 16:05:24 -0800 +Subject: [PATCH 12/21] Add testing instructions to README + +Signed-off-by: Adam Williamson +--- + README | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/README b/README +index ffcea09..9c78c59 100644 +--- a/README ++++ b/README +@@ -4,7 +4,22 @@ images containing an operating systems and, optionally, programs. + + The best way to install it is to make an RPM out of it by running "make rpm" + or "make srpm", and then installing the resulting RPM on the target machine. ++This will probably only work on Fedora or on RHEL 8 or later. + + Once you have the RPM installed, you will need to build up TDL files to feed + as input into the building process. Please see the examples directory to get + an idea of what a TDL file looks like. ++ ++Running the tests is also most easily done from a Fedora host. oz uses the ++guestfs Python module, which is not available from pypi, and needs a running ++libvirtd for most of the tests to run. Install all the test requirements: ++ ++dnf install python3-requests python3-m2crypto python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic ++ ++If you wish to test on EL 7, make that: ++ ++yum install python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic ++ ++then run the tests: ++ ++py.test tests/ +-- +2.43.0 + diff --git a/SOURCES/0013-Add-monotonic-to-requirements.patch b/SOURCES/0013-Add-monotonic-to-requirements.patch new file mode 100644 index 0000000..788b8cc --- /dev/null +++ b/SOURCES/0013-Add-monotonic-to-requirements.patch @@ -0,0 +1,25 @@ +From 523eb1338e6c2474bd57061e61e5d53056772292 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 16:05:40 -0800 +Subject: [PATCH 13/21] Add monotonic to requirements + +We started using this back in 2017, but it was never added to +requirements.txt. + +Signed-off-by: Adam Williamson +--- + requirements.txt | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/requirements.txt b/requirements.txt +index 2f5b4d6..c0a8d46 100644 +--- a/requirements.txt ++++ b/requirements.txt +@@ -2,3 +2,4 @@ requests + m2crypto + libvirt-python + lxml ++monotonic +-- +2.43.0 + diff --git a/SOURCES/0014-Update-oz.spec.in-to-match-current-Fedora.patch b/SOURCES/0014-Update-oz.spec.in-to-match-current-Fedora.patch new file mode 100644 index 0000000..4702451 --- /dev/null +++ b/SOURCES/0014-Update-oz.spec.in-to-match-current-Fedora.patch @@ -0,0 +1,107 @@ +From 7cf900a047f0e84d9fb01b0bcd756ecbe5925e21 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 16:06:04 -0800 +Subject: [PATCH 14/21] Update oz.spec.in to match current Fedora + +This won't work for EL 7, but should work for anything newer than +that. The current version doesn't work at all. + +Signed-off-by: Adam Williamson +--- + oz.spec.in | 41 +++++++++++++++++++---------------------- + 1 file changed, 19 insertions(+), 22 deletions(-) + +diff --git a/oz.spec.in b/oz.spec.in +index 37716b1..b83ccf1 100644 +--- a/oz.spec.in ++++ b/oz.spec.in +@@ -1,45 +1,41 @@ +-Summary: Library and utilities for automated guest OS installs +-Name: oz ++Name: oz + Version: @VERSION@ + Release: @RELEASE@%{?dist} ++Summary: Library and utilities for automated guest OS installs + License: LGPLv2 +-Group: Development/Libraries +-URL: http://github.com/clalancette/oz +-Source0: http://github.com/clalancette/%{name}/archive/%{name}-%{version}.tar.gz ++URL: http://github.com/clalancette/oz ++ ++Source0: https://github.com/clalancette/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz ++ + BuildArch: noarch ++ ++BuildRequires: python3 ++BuildRequires: python3-devel ++BuildRequires: python3-setuptools + Requires: python3 +-Requires: python3-libguestfs >= 1.18 + Requires: python3-lxml ++Requires: python3-libguestfs >= 1.18 + Requires: python3-libvirt ++Requires: python3-m2crypto ++Requires: python3-monotonic ++Requires: python3-requests + # in theory, oz doesn't really require libvirtd to be local to operate + # properly. However, because of the libguestfs manipulations, in practice + # it really does. Make it depend on libvirt (so we get libvirtd) for now, + # unless/until we are able to make it really be remote. +-%if 0%{?fedora} >= 17 + Requires: libvirt-daemon-kvm + Requires: libvirt-daemon-qemu + Requires: libvirt-daemon-config-network +-%else +-Requires: libvirt >= 0.9.7 +-%endif +-Requires: python3-requests + Requires: genisoimage + Requires: mtools +-%if 0%{?fedora} < 26 or 0%{?rhel} < 8 +-Requires: python-uuid +-%endif + Requires: openssh-clients +-Requires: python3-m2crypto +-Requires: python3-monotonic +- +-BuildRequires: python3 + + %description + Oz is a set of libraries and utilities for doing automated guest OS + installations, with minimal input from the user. + + %prep +-%setup -q ++%autosetup -p1 + + %build + %py3_build +@@ -66,7 +62,8 @@ if [ ! -f %{_sysconfdir}/oz/id_rsa-icicle-gen ]; then + fi + + %files +-%doc README COPYING examples ++%license COPYING ++%doc README examples + %dir %attr(0755, root, root) %{_sysconfdir}/oz/ + %config(noreplace) %{_sysconfdir}/oz/oz.cfg + %dir %attr(0755, root, root) %{_localstatedir}/lib/oz/ +@@ -78,13 +75,13 @@ fi + %dir %attr(0755, root, root) %{_localstatedir}/lib/oz/jeos/ + %dir %attr(0755, root, root) %{_localstatedir}/lib/oz/kernels/ + %dir %attr(0755, root, root) %{_localstatedir}/lib/oz/screenshots/ +-%{python3_sitelib}/oz + %{_bindir}/oz-install + %{_bindir}/oz-generate-icicle + %{_bindir}/oz-customize + %{_bindir}/oz-cleanup-cache +-%{python3_sitelib}/%{name}-%{version}-py%{python3_version}.egg-info + %{_mandir}/man1/* ++%{python3_sitelib}/oz ++%{python3_sitelib}/%{name}*.egg-info + + %changelog + * Sat Feb 5 2022 Peter Robinson - 0.18.0-1 +-- +2.43.0 + diff --git a/SOURCES/0015-tests-handle-libvirt_type-not-being-kvm.patch b/SOURCES/0015-tests-handle-libvirt_type-not-being-kvm.patch new file mode 100644 index 0000000..15faef5 --- /dev/null +++ b/SOURCES/0015-tests-handle-libvirt_type-not-being-kvm.patch @@ -0,0 +1,68 @@ +From cf60791c8fc759f0f1c325db008c86aef25d4842 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 16:58:45 -0800 +Subject: [PATCH 15/21] tests: handle libvirt_type not being kvm + +This seems necessary for testing in a container. I've mostly got +the tests passing in a rootless container, but libvirt_type is +qemu not kvm, and I doubt it's easy to get it to come out as +kvm. It's easier to just make the tests handle it being qemu. + +Signed-off-by: Adam Williamson +--- + tests/guest/libvirt/test_xml_generation_1.xml | 2 +- + tests/guest/libvirt/test_xml_generation_2.xml | 2 +- + tests/guest/test_guest.py | 10 ++++++++-- + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/tests/guest/libvirt/test_xml_generation_1.xml b/tests/guest/libvirt/test_xml_generation_1.xml +index a8ad4d8..1a64f61 100644 +--- a/tests/guest/libvirt/test_xml_generation_1.xml ++++ b/tests/guest/libvirt/test_xml_generation_1.xml +@@ -1,4 +1,4 @@ +- ++ + tester + 2097152 + 2097152 +diff --git a/tests/guest/libvirt/test_xml_generation_2.xml b/tests/guest/libvirt/test_xml_generation_2.xml +index cf6feb4..e46e581 100644 +--- a/tests/guest/libvirt/test_xml_generation_2.xml ++++ b/tests/guest/libvirt/test_xml_generation_2.xml +@@ -1,4 +1,4 @@ +- ++ + tester + 2097152 + 2097152 +diff --git a/tests/guest/test_guest.py b/tests/guest/test_guest.py +index 19b0863..a9383f2 100644 +--- a/tests/guest/test_guest.py ++++ b/tests/guest/test_guest.py +@@ -456,7 +456,10 @@ def test_xml_generation_1(): + test_xml = handle.read() + + # Replace various smaller items as they are auto generated +- test_xml = test_xml % (guest.uuid, route, guest.listen_port, guest.diskimage) ++ test_xml = test_xml % (guest.libvirt_type, guest.uuid, route, guest.listen_port, guest.diskimage) ++ # drop host-passthrough line if libvirt_type is not kvm ++ if guest.libvirt_type != "kvm": ++ test_xml = "\n".join((line for line in test_xml.splitlines() if "host-passthrough" not in line)) + "\n" + + bootdev = 'hd' + installdev = None +@@ -472,7 +475,10 @@ def test_xml_generation_2(): + test_xml = handle.read() + + # Replace various smaller items as they are auto generated +- test_xml = test_xml % (guest.uuid, route, guest.listen_port, guest.diskimage) ++ test_xml = test_xml % (guest.libvirt_type, guest.uuid, route, guest.listen_port, guest.diskimage) ++ # drop host-passthrough line if libvirt_type is not kvm ++ if guest.libvirt_type != "kvm": ++ test_xml = "\n".join((line for line in test_xml.splitlines() if "host-passthrough" not in line)) + "\n" + + bootdev = 'hd' + installdev = guest._InstallDev('blue', '/var/bin/foo', 'muni') +-- +2.43.0 + diff --git a/SOURCES/0016-tests-handle-guest-image-path-being-the-system-one.patch b/SOURCES/0016-tests-handle-guest-image-path-being-the-system-one.patch new file mode 100644 index 0000000..ea65748 --- /dev/null +++ b/SOURCES/0016-tests-handle-guest-image-path-being-the-system-one.patch @@ -0,0 +1,33 @@ +From fb26ca961e48ec4bbfa9377073b97c543e90c134 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 17:26:08 -0800 +Subject: [PATCH 16/21] tests: handle guest image path being the system one + +This seems to happen when testing in a container as root. + +Signed-off-by: Adam Williamson +--- + tests/guest/test_guest.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tests/guest/test_guest.py b/tests/guest/test_guest.py +index a9383f2..625eb67 100644 +--- a/tests/guest/test_guest.py ++++ b/tests/guest/test_guest.py +@@ -354,7 +354,12 @@ def test_init_guest(): + + assert guest.disksize == 20 + assert guest.image_name() == 'tester' +- assert guest.output_image_path() == '%s/.oz/images/tester.dsk' % os.getenv('HOME') ++ assert guest.output_image_path() in ( ++ # user's image storage ++ '%s/.oz/images/tester.dsk' % os.getenv('HOME'), ++ # system image storage (when testing as root, I think) ++ '/var/lib/libvirt/images/tester.dsk' ++ ) + assert guest.default_auto_file() == True + + def test_init_guest_bad_arch(): +-- +2.43.0 + diff --git a/SOURCES/0017-Update-pylint-and-flake8-commands-in-Makefile.patch b/SOURCES/0017-Update-pylint-and-flake8-commands-in-Makefile.patch new file mode 100644 index 0000000..1fa5ffe --- /dev/null +++ b/SOURCES/0017-Update-pylint-and-flake8-commands-in-Makefile.patch @@ -0,0 +1,32 @@ +From 6d2efbcf33e1b6ba64df496b09e4d5820b0320d7 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Wed, 24 Jan 2024 19:07:52 -0800 +Subject: [PATCH 17/21] Update pylint and flake8 commands in Makefile + +These -3 versions haven't existed for years, AFAICT. + +Signed-off-by: Adam Williamson +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index fa81313..c8d94dd 100644 +--- a/Makefile ++++ b/Makefile +@@ -52,10 +52,10 @@ test-coverage: + xdg-open htmlcov/index.html + + pylint: +- pylint-3 --rcfile=pylint.conf oz oz-install oz-customize oz-cleanup-cache oz-generate-icicle ++ pylint --rcfile=pylint.conf oz oz-install oz-customize oz-cleanup-cache oz-generate-icicle + + flake8: +- flake8-3 --ignore=E501 oz ++ flake8 --ignore=E501 oz + + clean: + rm -rf MANIFEST build dist usr *~ oz.spec *.pyc oz/*~ oz/*.pyc examples/*~ oz/auto/*~ man/*~ docs/*~ man/*.html $(VENV_DIR) tests/tdl/*~ tests/factory/*~ tests/results.xml htmlcov +-- +2.43.0 + diff --git a/SOURCES/0018-Add-ability-to-run-the-unit-tests-in-Fedora-and-EL7-.patch b/SOURCES/0018-Add-ability-to-run-the-unit-tests-in-Fedora-and-EL7-.patch new file mode 100644 index 0000000..e8f1ac1 --- /dev/null +++ b/SOURCES/0018-Add-ability-to-run-the-unit-tests-in-Fedora-and-EL7-.patch @@ -0,0 +1,147 @@ +From 2eb842a0b42c1ce5214a9ffd5005391762386161 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Wed, 24 Jan 2024 17:25:41 -0800 +Subject: [PATCH 18/21] Add ability to run the unit tests in Fedora and EL7 + containers + +This adds a convenient way to run the unit tests in containers - +a "latest Fedora" container to check things work with the latest +shiny bits, and an EL 7 (CentOS 7 plus EPEL) container to check +things work with antique bits. This should make it possible to +conveniently set up CI with a github action. It also should +make it easy to run the tests on non-Fedora/RHEL-ish platforms. + +`make container-unittests` will build both containers and run +the tests. `make container-clean` cleans up the containers and +images. + +Signed-off-by: Adam Williamson +--- + Containerfile.tests.el7 | 16 ++++++++++++++++ + Containerfile.tests.fedora | 14 ++++++++++++++ + Makefile | 19 ++++++++++++++++++- + README | 22 ++++++++++++++++++++-- + 4 files changed, 68 insertions(+), 3 deletions(-) + create mode 100644 Containerfile.tests.el7 + create mode 100644 Containerfile.tests.fedora + +diff --git a/Containerfile.tests.el7 b/Containerfile.tests.el7 +new file mode 100644 +index 0000000..06a9b78 +--- /dev/null ++++ b/Containerfile.tests.el7 +@@ -0,0 +1,16 @@ ++# this container definition is intended *only* for running the oz test suite, it is not ++# a general-purpose oz container definition! ++ ++FROM quay.io/centos/centos:7 ++RUN set -exo pipefail \ ++ && yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ ++ && yum install -y python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic libvirt \ ++ && yum clean all \ ++ && rm -rf /var/cache/* /var/log/yum* ++ ++COPY ./ /oz ++# the XML generation tests are inherently unreliable before Python 3.8, ++# as there was no consistent ordering of XML element attributes. See ++# https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostring ++RUN printf "#!/bin/sh\n/usr/sbin/libvirtd -d\ncd /oz\npy.test -vv -k 'not test_xml_generation and not modify_libvirt_xml_for_serial' tests/" > /usr/local/bin/runtests.sh && chmod ugo+x /usr/local/bin/runtests.sh ++CMD /usr/local/bin/runtests.sh +diff --git a/Containerfile.tests.fedora b/Containerfile.tests.fedora +new file mode 100644 +index 0000000..7dd3e41 +--- /dev/null ++++ b/Containerfile.tests.fedora +@@ -0,0 +1,14 @@ ++# this container definition is intended *only* for running the oz test suite, it is not ++# a general-purpose oz container definition! ++ ++FROM quay.io/fedora/fedora:latest ++RUN set -exo pipefail \ ++ && dnf install -y --setopt install_weak_deps=false --nodocs \ ++ python3-requests python3-m2crypto python3-setuptools python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic \ ++ libvirt-daemon libvirt-daemon-kvm libvirt-daemon-qemu libvirt-daemon-config-network systemd \ ++ && dnf clean all \ ++ && rm -rf /var/cache/* /var/log/dnf* ++ ++COPY ./ /oz ++RUN printf "#!/bin/sh\n/usr/sbin/libvirtd -d\ncd /oz\npy.test -vv tests/" > /usr/local/bin/runtests.sh && chmod ugo+x /usr/local/bin/runtests.sh ++CMD /usr/local/bin/runtests.sh +diff --git a/Makefile b/Makefile +index c8d94dd..74d3d99 100644 +--- a/Makefile ++++ b/Makefile +@@ -46,6 +46,18 @@ unittests: + + tests: unittests + ++container-unittests-fedora: ++ docker rm -f oz-tests-fedora ++ docker build -f Containerfile.tests.fedora -t oz-tests-fedora-image . ++ docker run --name oz-tests-fedora oz-tests-fedora-image ++ ++container-unittests-el7: ++ docker rm -f oz-tests-el7 ++ docker build -f Containerfile.tests.el7 -t oz-tests-el7-image . ++ docker run --name oz-tests-el7 oz-tests-el7-image ++ ++container-unittests: container-unittests-fedora container-unittests-el7 ++ + test-coverage: + python-coverage run --source oz /usr/bin/py.test --verbose tests + python-coverage html +@@ -57,7 +69,12 @@ pylint: + flake8: + flake8 --ignore=E501 oz + ++container-clean: ++ docker rm -f oz-tests-fedora ++ docker rm -f oz-tests-el7 ++ docker image rm -f -i oz-tests-fedora-image oz-tests-el7-image ++ + clean: + rm -rf MANIFEST build dist usr *~ oz.spec *.pyc oz/*~ oz/*.pyc examples/*~ oz/auto/*~ man/*~ docs/*~ man/*.html $(VENV_DIR) tests/tdl/*~ tests/factory/*~ tests/results.xml htmlcov + +-.PHONY: sdist oz.spec signed-tarball signed-rpm rpm srpm deb release man2html virtualenv unittests tests test-coverage pylint clean ++.PHONY: sdist oz.spec signed-tarball signed-rpm rpm srpm deb release man2html virtualenv unittests container-unittests-fedora container-unittests-el7 container-unittests tests test-coverage pylint clean container-clean +diff --git a/README b/README +index 9c78c59..5f2c983 100644 +--- a/README ++++ b/README +@@ -10,9 +10,19 @@ Once you have the RPM installed, you will need to build up TDL files to feed + as input into the building process. Please see the examples directory to get + an idea of what a TDL file looks like. + +-Running the tests is also most easily done from a Fedora host. oz uses the ++You can run the oz unit tests in containers by installing make and docker ++(or podman-docker), then running: ++ ++make container-unittests ++ ++You can clean up the containers and images by running: ++ ++make container-clean ++ ++Otherwise, you can try running the tests directly on your host, but oz uses the + guestfs Python module, which is not available from pypi, and needs a running +-libvirtd for most of the tests to run. Install all the test requirements: ++libvirtd for most of the tests to run. To install all the test requirements on ++Fedora: + + dnf install python3-requests python3-m2crypto python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic + +@@ -23,3 +33,11 @@ yum install python-requests m2crypto libvirt-python python-lxml python-libguestf + then run the tests: + + py.test tests/ ++ ++You can try `make virtualenv` then `make unittests` to run the tests in a ++virtualenv if you like, but this still requires at least the libguestfs library ++installed on the host, and a running libvirtd. You may also want to install ++m2crypto and libvirt libraries on the host, as otherwise pip will have to ++compile them, and you'll need their build dependencies. ++ ++You can use `make pylint` and `make flake8` to run lint checks. +-- +2.43.0 + diff --git a/SOURCES/0019-Add-a-Github-Action-workflow-to-run-CI-checks.patch b/SOURCES/0019-Add-a-Github-Action-workflow-to-run-CI-checks.patch new file mode 100644 index 0000000..d5e2938 --- /dev/null +++ b/SOURCES/0019-Add-a-Github-Action-workflow-to-run-CI-checks.patch @@ -0,0 +1,109 @@ +From c59c3417db54c26aac092b1463f130f7540aa33a Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Wed, 24 Jan 2024 17:49:12 -0800 +Subject: [PATCH 19/21] Add a Github Action workflow to run CI checks + +I can't really test this, but I think it ought to work. This +should run the container unit tests, pylint, and flake8 checks +on each pull request. + +This also removes .travis.yml, as we clearly haven't used travis +for about a decade at this point. + +Signed-off-by: Adam Williamson +--- + .github/workflows/ci.yml | 41 ++++++++++++++++++++++++++++++++++++++++ + .travis.yml | 33 -------------------------------- + 2 files changed, 41 insertions(+), 33 deletions(-) + create mode 100644 .github/workflows/ci.yml + delete mode 100644 .travis.yml + +diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml +new file mode 100644 +index 0000000..4fcd212 +--- /dev/null ++++ b/.github/workflows/ci.yml +@@ -0,0 +1,41 @@ ++--- ++name: Run CI checks ++ ++on: [pull_request] ++ ++jobs: ++ unittests-fedora: ++ runs-on: ubuntu-latest ++ steps: ++ - name: Checkout the repo ++ uses: actions/checkout@v4 ++ with: ++ fetch-depth: 0 ++ - name: Install make and docker ++ run: apt-get install make docker docker.io ++ - name: Run the tests ++ run: make container-unittests-fedora ++ unittests-el7: ++ runs-on: ubuntu-latest ++ steps: ++ - name: Checkout the repo ++ uses: actions/checkout@v4 ++ with: ++ fetch-depth: 0 ++ - name: Install make and docker ++ run: apt-get install make docker ++ - name: Run the tests ++ run: make container-unittests-el7 ++ lint: ++ runs-on: ubuntu-latest ++ steps: ++ - name: Checkout the repo ++ uses: actions/checkout@v4 ++ with: ++ fetch-depth: 0 ++ - name: Install make, pylint and flake8 ++ run: apt-get install make pylint flake8 ++ - name: Run pylint ++ run: make pylint ++ - name: Run flake8 ++ run: make flake8 +diff --git a/.travis.yml b/.travis.yml +deleted file mode 100644 +index 2a2b8d6..0000000 +--- a/.travis.yml ++++ /dev/null +@@ -1,33 +0,0 @@ +-language: python +- +-python: +-# - "3.3" +-# - "3.2" +- - "2.7" +- +-before_install: +- - sudo add-apt-repository -y ppa:pdffs/precise-virt +- - sudo apt-get update +- - sudo apt-get install -qq genisoimage libvirt-dev mtools openssh-client python-dev python-guestfs swig libssl1.0.0 python-m2crypto python-libvirt +- +-# Travis uses an isolated virtualenv (see http://about.travis-ci.org/docs/user/languages/python/#Travis-CI-Uses-Isolated-virtualenvs) +-# Install the system python packages to get their deps and then install the pip version to have them locally +-install: +- - pip install -r requirements.txt +- - sudo cp /usr/lib/python2.7/dist-packages/*guestfs* $VIRTUAL_ENV/lib/python$TRAVIS_PYTHON_VERSION/site-packages/ +- - python setup.py install +- - pip install coverage +- - pip install coveralls +- - py.test --genscript=runtests.py +- +-env: +- - TESTFOLDER=tdl +- - TESTFOLDER=guest +- - TESTFOLDER=ozutil +- - TESTFOLDER=factory +- +-script: +- - coverage run -p --source=oz runtests.py --verbose --tb=short tests/$TESTFOLDER +- +-after_success: +- - coveralls +-- +2.43.0 + diff --git a/SOURCES/0020-CI-use-sudo-assume-docker-is-present-always-pass-lin.patch b/SOURCES/0020-CI-use-sudo-assume-docker-is-present-always-pass-lin.patch new file mode 100644 index 0000000..7d37913 --- /dev/null +++ b/SOURCES/0020-CI-use-sudo-assume-docker-is-present-always-pass-lin.patch @@ -0,0 +1,84 @@ +From 7e69bf2647d3450e4b6da9f5caaa65664443745f Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Thu, 25 Jan 2024 08:44:09 -0800 +Subject: [PATCH 20/21] CI: use sudo, assume docker is present, always pass + lint + +Huh. I kinda just assumed we'd be root. Guess not! + +All my attempts to just get a 'docker' binary installed seem +to be failing on conflicts. Maybe it's already there in the +GHA image? Let's try leaving it out. + +pylint and flake8 exit non-zero if a single issue is found, and +right now we have tons of them. For now just to get started, +let's make them only informational. I can send a follow-up PR +to use diff-cover, maybe, to only fail on *new* violations. + +Signed-off-by: Adam Williamson +--- + .github/workflows/ci.yml | 14 +++++++------- + Makefile | 4 ++-- + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml +index 4fcd212..9c8f59a 100644 +--- a/.github/workflows/ci.yml ++++ b/.github/workflows/ci.yml +@@ -11,10 +11,10 @@ jobs: + uses: actions/checkout@v4 + with: + fetch-depth: 0 +- - name: Install make and docker +- run: apt-get install make docker docker.io ++ - name: Install make ++ run: sudo apt-get install make + - name: Run the tests +- run: make container-unittests-fedora ++ run: sudo make container-unittests-fedora + unittests-el7: + runs-on: ubuntu-latest + steps: +@@ -22,10 +22,10 @@ jobs: + uses: actions/checkout@v4 + with: + fetch-depth: 0 +- - name: Install make and docker +- run: apt-get install make docker ++ - name: Install make ++ run: sudo apt-get install make + - name: Run the tests +- run: make container-unittests-el7 ++ run: sudo make container-unittests-el7 + lint: + runs-on: ubuntu-latest + steps: +@@ -34,7 +34,7 @@ jobs: + with: + fetch-depth: 0 + - name: Install make, pylint and flake8 +- run: apt-get install make pylint flake8 ++ run: sudo apt-get install make pylint flake8 + - name: Run pylint + run: make pylint + - name: Run flake8 +diff --git a/Makefile b/Makefile +index 74d3d99..2940289 100644 +--- a/Makefile ++++ b/Makefile +@@ -64,10 +64,10 @@ test-coverage: + xdg-open htmlcov/index.html + + pylint: +- pylint --rcfile=pylint.conf oz oz-install oz-customize oz-cleanup-cache oz-generate-icicle ++ pylint --rcfile=pylint.conf oz oz-install oz-customize oz-cleanup-cache oz-generate-icicle || : + + flake8: +- flake8 --ignore=E501 oz ++ flake8 --ignore=E501 oz || : + + container-clean: + docker rm -f oz-tests-fedora +-- +2.43.0 + diff --git a/SOURCES/0021-Allow-image-size-specification-using-any-SI-or-IEC-u.patch b/SOURCES/0021-Allow-image-size-specification-using-any-SI-or-IEC-u.patch new file mode 100644 index 0000000..56fecc7 --- /dev/null +++ b/SOURCES/0021-Allow-image-size-specification-using-any-SI-or-IEC-u.patch @@ -0,0 +1,347 @@ +From 014411b0984fb85588123912a12f3f1d39215c27 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 23 Jan 2024 11:24:00 -0800 +Subject: [PATCH 21/21] Allow image size specification using any SI or IEC unit + +Currently, oz only allows image sizes to be specified as integer +amounts of gibibytes or tebibytes (that's IEC power-of-two units). +This is unfortunately inflexible. Consider that storage media are +typically specified in SI power-of-ten sizes, so a USB stick may +be 16 gigabytes (SI power-of-ten GB) in size - that's +16,000,000,000 bytes. Let's say we want to build an image that +will fit on such a USB stick. oz will only allow us to build an +image of 15,032,385,536 bytes (14 gibibytes) or 16,106,127,360 +bytes (15 gibibytes). So we're either slightly too big, or leaving +nearly a gigabyte on the table. + +This allows the image size to be specified in the TDL with most +any IEC or SI unit suffix, from B (bytes) all the way up to YiB +(yobibytes). A size with no suffix or the suffix "G" is taken as +gibibytes and a size with the suffix "T" is taken as tebibytes, +as before, but other ambiguous suffixes are not accepted. All +casing is accepted. Behind the scenes, we convert the size to +bytes and specify it that way in the libvirt XML when creating +the image in _internal_generate_diskimage. + +This does change the interface of generate_diskimage(), by making +the unit for the size argument bytes instead of gibibytes. I can't +see a clean way to avoid this while allowing flexibility. I have +checked, and AFAICT, among active projects, only oz itself and +the ImageFactory TinMan plugin call this function. The TinMan +plugin will need a trivial change to its fallback default value. + +Signed-off-by: Adam Williamson +--- + oz/Fedora.py | 6 +-- + oz/Guest.py | 16 +++---- + oz/TDL.py | 47 +++++++++++++------ + oz/Windows.py | 8 ++-- + oz/ozutil.py | 17 +++++++ + oz/tdl.rng | 2 +- + tests/guest/test_guest.py | 3 +- + ... => test-58-disk-size-tebibyte-compat.tdl} | 0 + tests/tdl/test-63-disk-size-exbibyte.tdl | 15 ++++++ + tests/tdl/test-64-disk-size-zettabyte.tdl | 15 ++++++ + tests/tdl/test-65-disk-size-byte.tdl | 15 ++++++ + tests/tdl/test_tdl.py | 5 +- + 12 files changed, 117 insertions(+), 32 deletions(-) + rename tests/tdl/{test-58-disk-size-terabyte.tdl => test-58-disk-size-tebibyte-compat.tdl} (100%) + create mode 100644 tests/tdl/test-63-disk-size-exbibyte.tdl + create mode 100644 tests/tdl/test-64-disk-size-zettabyte.tdl + create mode 100644 tests/tdl/test-65-disk-size-byte.tdl + +diff --git a/oz/Fedora.py b/oz/Fedora.py +index 89ecca8..c6152f1 100644 +--- a/oz/Fedora.py ++++ b/oz/Fedora.py +@@ -298,11 +298,11 @@ class FedoraGuest(oz.RedHat.RedHatLinuxCDYumGuest): + initrdline += " inst.nosave=output_ks" + self._modify_isolinux(initrdline) + +- def generate_diskimage(self, size=10, force=False): ++ def generate_diskimage(self, size=10*1024*1024*1024, force=False): + """ + Method to generate a diskimage. By default, a blank diskimage of +- 10GB will be created; the caller can override this with the size +- parameter, specified in GB. If force is False (the default), then ++ 10 GiB will be created; the caller can override this with the size ++ parameter, specified in bytes. If force is False (the default), then + a diskimage will not be created if a cached JEOS is found. If + force is True, a diskimage will be created regardless of whether a + cached JEOS exists. See the oz-install man page for more +diff --git a/oz/Guest.py b/oz/Guest.py +index 249cce0..8a4e485 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -571,7 +571,7 @@ class Guest(object): + + return xml + +- def _internal_generate_diskimage(self, size=10, force=False, ++ def _internal_generate_diskimage(self, size=10*1024*1024*1024, force=False, + create_partition=False, + image_filename=None, + backing_filename=None): +@@ -587,7 +587,7 @@ class Guest(object): + # we'll copy the JEOS itself later on + return + +- self.log.info("Generating %dGB diskimage for %s", size, self.tdl.name) ++ self.log.info("Generating %s diskimage for %s", oz.ozutil.sizeof_fmt(int(size)), self.tdl.name) + + diskimage = self.diskimage + if image_filename: +@@ -628,17 +628,17 @@ class Guest(object): + # allows creation without an explicit capacity element. + qcow_size = oz.ozutil.check_qcow_size(backing_filename) + if qcow_size: +- capacity = qcow_size / 1024 / 1024 / 1024 ++ capacity = qcow_size + backing_format = 'qcow2' + else: +- capacity = os.path.getsize(backing_filename) / 1024 / 1024 / 1024 ++ capacity = os.path.getsize(backing_filename) + backing_format = 'raw' + backing = oz.ozutil.lxml_subelement(vol, "backingStore") + oz.ozutil.lxml_subelement(backing, "path", backing_filename) + oz.ozutil.lxml_subelement(backing, "format", None, + {"type": backing_format}) + +- oz.ozutil.lxml_subelement(vol, "capacity", str(int(capacity)), {'unit': 'G'}) ++ oz.ozutil.lxml_subelement(vol, "capacity", str(int(capacity)), {'unit': 'B'}) + vol_xml = lxml.etree.tostring(vol, pretty_print=True, encoding="unicode") + + # sigh. Yes, this is racy; if a pool is defined during this loop, we +@@ -718,11 +718,11 @@ class Guest(object): + g_handle.create_msdos_partition_table() + g_handle.cleanup() + +- def generate_diskimage(self, size=10, force=False): ++ def generate_diskimage(self, size=10*1024*1024*1024, force=False): + """ + Method to generate a diskimage. By default, a blank diskimage of +- 10GB will be created; the caller can override this with the size +- parameter, specified in GB. If force is False (the default), then ++ 10 GiB will be created; the caller can override this with the size ++ parameter, specified in bytes. If force is False (the default), then + a diskimage will not be created if a cached JEOS is found. If + force is True, a diskimage will be created regardless of whether a + cached JEOS exists. See the oz-install man page for more +diff --git a/oz/TDL.py b/oz/TDL.py +index cb373cb..aee74a3 100644 +--- a/oz/TDL.py ++++ b/oz/TDL.py +@@ -327,20 +327,39 @@ class TDL(object): + # a sensible default + return None + +- match = re.match(r'([0-9]*) *([GT]?)$', size) +- if not match or len(match.groups()) != 2: +- raise oz.OzException.OzException("Invalid disk size; it must be specified as a size in gigabytes, optionally suffixed with 'G' or 'T'") +- +- number = match.group(1) +- suffix = match.group(2) +- +- if not suffix or suffix == 'G': +- # for backwards compatibility, we assume G when there is no suffix +- size = number +- elif suffix == 'T': +- size = str(int(number) * 1024) +- +- return size ++ # drop spaces and downcase ++ size = size.replace(" ", "").lower() ++ # isolate digits ++ number = "" ++ suffix = "" ++ for (idx, char) in enumerate(size): ++ if char.isdigit(): ++ number += char ++ else: ++ suffix = size[idx:] ++ break ++ ++ if not suffix: ++ # for backwards compatibility, we assume GiB when there is no suffix ++ suffix = "gib" ++ ++ # also for backwards compatibility with an earlier attempt to support ++ # suffixes, treat "T" and "G" as "TiB" and "GiB" ++ units = {"b": 1, "g": 2**30, "t": 2**40} ++ tenscale = 3 ++ twoscale = 10 ++ for (i, pref) in enumerate(("k", "m", "g", "t", "p", "e", "z", "y"), start=1): ++ # this is giving us {"gib": 2 ** 30, "gb": 10 ** 9}, etc ++ units[pref + "b"] = (10 ** (i*tenscale)) ++ units[pref + "ib"] = (2 ** (i*twoscale)) ++ ++ factor = units.get(suffix) ++ if not number or not factor: ++ raise oz.OzException.OzException( ++ "Invalid disk size; it must be specified as an integer size with an optional SI or IEC unit suffix, e.g. '10TB' or '16GiB'" ++ ) ++ ++ return str(int(number) * factor) + + def _parse_commands(self, xpath): + """ +diff --git a/oz/Windows.py b/oz/Windows.py +index 78948ac..777a306 100644 +--- a/oz/Windows.py ++++ b/oz/Windows.py +@@ -78,12 +78,12 @@ class Windows_v5(Windows): + self.iso_contents], + printfn=self.log.debug) + +- def generate_diskimage(self, size=10, force=False): ++ def generate_diskimage(self, size=10*1024*1024*1024, force=False): + """ + Method to generate a diskimage. By default, a blank diskimage of +- 10GB will be created; the caller can override this with the size +- parameter, specified in GB. If force is False (the default), then +- a diskimage will not be created if a cached JEOS is found. If ++ 10 GiB will be created; the caller can override this with the size ++ parameter, specified in bytes. If force is False (the default), ++ then a diskimage will not be created if a cached JEOS is found. If + force is True, a diskimage will be created regardless of whether a + cached JEOS exists. See the oz-install man page for more + information about JEOS caching. +diff --git a/oz/ozutil.py b/oz/ozutil.py +index 689559f..be27d3f 100644 +--- a/oz/ozutil.py ++++ b/oz/ozutil.py +@@ -1178,3 +1178,20 @@ def get_free_port(): + sock.close() + + return listen_port ++ ++ ++def sizeof_fmt(num, suffix="B"): ++ """ ++ Give a convenient human-readable representation of a large size in ++ bytes. Initially by Fred Cirera: ++ https://web.archive.org/web/20111010015624/http://blogmag.net/blog/read/38/Print_human_readable_file_size ++ edited by multiple contributors at: ++ https://stackoverflow.com/questions/1094841 ++ Per Richard Fontana this is too trivial to be copyrightable, so ++ there are no licensing concerns ++ """ ++ for unit in ("", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"): ++ if abs(num) < 1024.0: ++ return "%3.1f%s%s" % (num, unit, suffix) ++ num /= 1024.0 ++ return "%.1f%s%s" % (num, 'Yi', suffix) +diff --git a/oz/tdl.rng b/oz/tdl.rng +index dc29c9a..9ca94cc 100644 +--- a/oz/tdl.rng ++++ b/oz/tdl.rng +@@ -325,7 +325,7 @@ + + + +- ([0-9]*) *([GT]?) ++ ([0-9]*) *([kKmMgGtTpPeEzZyY]?[iI]?[bB]?) + + + +diff --git a/tests/guest/test_guest.py b/tests/guest/test_guest.py +index 625eb67..85f6b03 100644 +--- a/tests/guest/test_guest.py ++++ b/tests/guest/test_guest.py +@@ -352,7 +352,8 @@ def test_geteltorito_bogus_bootp(tmpdir): + def test_init_guest(): + guest = setup_guest(tdlxml2) + +- assert guest.disksize == 20 ++ # size without units is taken to be GiB ++ assert guest.disksize == 20*(2**30) + assert guest.image_name() == 'tester' + assert guest.output_image_path() in ( + # user's image storage +diff --git a/tests/tdl/test-58-disk-size-terabyte.tdl b/tests/tdl/test-58-disk-size-tebibyte-compat.tdl +similarity index 100% +rename from tests/tdl/test-58-disk-size-terabyte.tdl +rename to tests/tdl/test-58-disk-size-tebibyte-compat.tdl +diff --git a/tests/tdl/test-63-disk-size-exbibyte.tdl b/tests/tdl/test-63-disk-size-exbibyte.tdl +new file mode 100644 +index 0000000..e3f6b12 +--- /dev/null ++++ b/tests/tdl/test-63-disk-size-exbibyte.tdl +@@ -0,0 +1,15 @@ ++ +diff --git a/tests/tdl/test-64-disk-size-zettabyte.tdl b/tests/tdl/test-64-disk-size-zettabyte.tdl +new file mode 100644 +index 0000000..26b7105 +--- /dev/null ++++ b/tests/tdl/test-64-disk-size-zettabyte.tdl +@@ -0,0 +1,15 @@ ++ +diff --git a/tests/tdl/test-65-disk-size-byte.tdl b/tests/tdl/test-65-disk-size-byte.tdl +new file mode 100644 +index 0000000..b6e0774 +--- /dev/null ++++ b/tests/tdl/test-65-disk-size-byte.tdl +@@ -0,0 +1,15 @@ ++ +diff --git a/tests/tdl/test_tdl.py b/tests/tdl/test_tdl.py +index a94b2c1..366f1bc 100644 +--- a/tests/tdl/test_tdl.py ++++ b/tests/tdl/test_tdl.py +@@ -92,8 +92,11 @@ tests = { + "test-55-files-http-url.tdl": True, + "test-56-invalid-disk-size.tdl": False, + "test-57-invalid-disk-size.tdl": False, +- "test-58-disk-size-terabyte.tdl": True, ++ "test-58-disk-size-tebibyte-compat.tdl": True, + "test-59-command-sorting.tdl": True, ++ "test-63-disk-size-exbibyte.tdl": True, ++ "test-64-disk-size-zettabyte.tdl": True, ++ "test-65-disk-size-byte.tdl": True, + } + + # Test that iterates over all .tdl files +-- +2.43.0 + diff --git a/SPECS/oz.spec b/SPECS/oz.spec new file mode 100644 index 0000000..cb69757 --- /dev/null +++ b/SPECS/oz.spec @@ -0,0 +1,385 @@ +Name: oz +Version: 0.18.1 +Release: 13%{?dist} +Summary: Library and utilities for automated guest OS installs +License: LGPLv2 +URL: http://github.com/clalancette/oz + +# libguestfs is not built on i686 +ExcludeArch: %{ix86} + +Source0: https://github.com/clalancette/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz + + +# Upstream patch to enable the usb controller for aarch64 +Patch0001: 0001-Enable-USB-controller-and-keyboard-for-aarch64-for-a.patch +# All upstream patches to current master +Patch0002: 0002-Revert-Don-t-write-kickstart-so-initial-setup-won-t-.patch +Patch0003: 0003-Don-t-abort-when-the-data-in-_wait_for_install_finis.patch +Patch0004: 0004-Fix-for-running-on-python3-and-building-on-EL8-or-hi.patch +Patch0005: 0005-Fix-RHEL-templates-to-pass-required-useuefi-paramete.patch +Patch0006: 0006-Use-discard-unmap-for-images.patch +Patch0007: 0007-Don-t-write-kickstart-so-initial-setup-won-t-think-r.patch +Patch0008: 0008-Python-3-compat-fixes-py.test-and-ConfigParser.patch +Patch0009: 0009-Unpick-unnecessary-useuefi-arg-on-the-Guest-classes.patch +Patch0010: 0010-Python-compat-Callable-is-in-collections.abc-since-P.patch +Patch0011: 0011-Tests-multiple-fixes-to-expected-guest-XML.patch +Patch0012: 0012-Add-testing-instructions-to-README.patch +Patch0013: 0013-Add-monotonic-to-requirements.patch +Patch0014: 0014-Update-oz.spec.in-to-match-current-Fedora.patch +Patch0015: 0015-tests-handle-libvirt_type-not-being-kvm.patch +Patch0016: 0016-tests-handle-guest-image-path-being-the-system-one.patch +Patch0017: 0017-Update-pylint-and-flake8-commands-in-Makefile.patch +Patch0018: 0018-Add-ability-to-run-the-unit-tests-in-Fedora-and-EL7-.patch +Patch0019: 0019-Add-a-Github-Action-workflow-to-run-CI-checks.patch +Patch0020: 0020-CI-use-sudo-assume-docker-is-present-always-pass-lin.patch +Patch0021: 0021-Allow-image-size-specification-using-any-SI-or-IEC-u.patch + +# https://github.com/clalancette/oz/pull/312 +Patch: 0001-tests-mock-network-functions-so-tests-work-with-no-n.patch + +BuildArch: noarch + +BuildRequires: python3 +BuildRequires: python3-devel +BuildRequires: python3-setuptools +# test dependencies +BuildRequires: python3-requests +BuildRequires: python3-m2crypto +# currently an undeclared dependency of m2crypto in F39/Rawhide: +# https://bugzilla.redhat.com/show_bug.cgi?id=2259967 +BuildRequires: python3-setuptools +BuildRequires: python3-libvirt +BuildRequires: python3-lxml +BuildRequires: python3-libguestfs +BuildRequires: python3-pytest +BuildRequires: python3-monotonic +BuildRequires: libvirt-daemon +BuildRequires: libvirt-daemon-kvm +# BuildRequires: libvirt-daemon-qemu +BuildRequires: libvirt-daemon-config-network +BuildRequires: python3-pytest +Requires: python3 +Requires: python3-lxml +Requires: python3-libguestfs >= 1.18 +Requires: python3-libvirt +Requires: python3-m2crypto +Requires: python3-monotonic +Requires: python3-requests +# in theory, oz doesn't really require libvirtd to be local to operate +# properly. However, because of the libguestfs manipulations, in practice +# it really does. Make it depend on libvirt (so we get libvirtd) for now, +# unless/until we are able to make it really be remote. +Requires: libvirt-daemon-kvm +# Requires: libvirt-daemon-qemu +Requires: libvirt-daemon-config-network +Requires: genisoimage +Requires: mtools +Requires: openssh-clients + +%description +Oz is a set of libraries and utilities for doing automated guest OS +installations, with minimal input from the user. + +%prep +%autosetup -p1 + +%build +%py3_build + +%install +%py3_install + +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/isocontent/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/isos/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/floppycontent/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/floppies/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/icicletmp/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/jeos/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/kernels/ +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/oz/screenshots/ + +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/oz +cp oz.cfg $RPM_BUILD_ROOT%{_sysconfdir}/oz + +%post +if [ ! -f %{_sysconfdir}/oz/id_rsa-icicle-gen ]; then + ssh-keygen -t rsa -b 2048 -N "" -f %{_sysconfdir}/oz/id_rsa-icicle-gen >& /dev/null +fi + +%check +libvirtd -d +%pytest tests/ + +%files +%license COPYING +%doc README examples +%dir %attr(0755, root, root) %{_sysconfdir}/oz/ +%config(noreplace) %{_sysconfdir}/oz/oz.cfg +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/isocontent/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/isos/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/floppycontent/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/floppies/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/icicletmp/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/jeos/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/kernels/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/oz/screenshots/ +%{_bindir}/oz-install +%{_bindir}/oz-generate-icicle +%{_bindir}/oz-customize +%{_bindir}/oz-cleanup-cache +%{_mandir}/man1/* +%{python3_sitelib}/oz +%{python3_sitelib}/%{name}*.egg-info + +%changelog +* Fri Feb 09 2024 Adam Williamson - 0.18.1-13 +- Bump with no changes to exceed F39 infra repo build NVR + +* Thu Jan 25 2024 Adam Williamson - 0.18.1-12 +- Backport all upstream changes since 0.18.1, plus PR #310 and #312 +- Run the tests during package build + +* Thu Jan 25 2024 Fedora Release Engineering - 0.18.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sun Jan 21 2024 Fedora Release Engineering - 0.18.1-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Wed Sep 27 2023 Adam Williamson - 0.18.1-9 +- Drop the reversion of the kickstart patch, i-s should be fixed (#2015490) + +* Thu Jul 20 2023 Fedora Release Engineering - 0.18.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Tue Jun 13 2023 Python Maint - 0.18.1-7 +- Rebuilt for Python 3.12 + +* Thu Jan 19 2023 Fedora Release Engineering - 0.18.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Oct 03 2022 Stephen Gallagher - 0.18.1-5 +- Backport upstream patch to enable the USB controller on aarch64 + +* Fri Jul 22 2022 Fedora Release Engineering - 0.18.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Mon Jun 13 2022 Python Maint - 0.18.1-3 +- Rebuilt for Python 3.11 + +* Tue Mar 01 2022 Adam Williamson - 0.18.1-2 +- Backport MR#297, revert attempt to fix #2015490, it stopped i-s working (#2057600) + +* Tue Feb 22 2022 Peter Robinson - 0.18.1-1 +- Update to 0.18.1 + +* Sat Feb 05 2022 Peter Robinson - 0.18.0-1 +- Update to 0.18.0 + +* Thu Jan 20 2022 Fedora Release Engineering - 0.17.0-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Oct 27 2021 Adam Williamson - 0.17.0-20 +- Try again to do what -19 probably failed to do (#2015490) + +* Tue Oct 26 2021 Adam Williamson - 0.17.0-19 +- Don't write kickstart so initial-setup won't think root pw is set (#2015490) + +* Thu Jul 22 2021 Fedora Release Engineering - 0.17.0-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Fri Jun 04 2021 Python Maint - 0.17.0-17 +- Rebuilt for Python 3.10 + +* Wed Feb 10 2021 Peter Robinson - 0.17.0-16 +- Fixes for anaconda changes + +* Tue Feb 09 2021 Peter Robinson - 0.17.0-15 +- fix patch for newer Fedora releases + +* Tue Jan 26 2021 Fedora Release Engineering - 0.17.0-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jan 19 2021 Peter Robinson - 0.17.0-13 +- Add upstream PR for libvirt fixes + +* Mon Oct 05 2020 Peter Robinson - 0.17.0-12 +- Futher arm fixes, drop EOL conditionals + +* Sun Oct 04 2020 Peter Robinson - 0.17.0-11 +- Add missing fixes patch + +* Sat Oct 03 2020 Peter Robinson - 0.17.0-10 +- Fix screenshots on armv7/aarch64, ARMv7 fixes, drop old release conditionals + +* Tue Jul 28 2020 Fedora Release Engineering - 0.17.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu Jul 02 2020 Dan Horák - 0.17.0-8 +- fix compatibility with new qemu/libvirt on s390x + +* Tue May 26 2020 Miro Hrončok - 0.17.0-7 +- Rebuilt for Python 3.9 + +* Wed Jan 29 2020 Fedora Release Engineering - 0.17.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Oct 03 2019 Miro Hrončok - 0.17.0-5 +- Rebuilt for Python 3.8.0rc1 (#1748018) + +* Mon Aug 19 2019 Miro Hrončok - 0.17.0-4 +- Rebuilt for Python 3.8 + +* Thu Jul 25 2019 Fedora Release Engineering - 0.17.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Apr 2 2019 Peter Robinson 0.17.0-2 +- Fix m2crypto python2 naming + +* Tue Mar 26 2019 Peter Robinson 0.17.0-1 +- Conditionalise py3 support +- 0.17.0 is releases, minor cleanups + +* Sat Mar 16 2019 Chris Lalancette - 0.17.0-0.3 +- Update to latest upstream changes for Python 3 + +* Wed Mar 13 2019 Peter Robinson 0.17.0-0.2 +- Rebase to latest PR for ARMv7/aarch64 UEFI + +* Thu Feb 28 2019 Peter Robinson 0.17.0-0.1 +- Upstream git 0.17 snapshot +- ARMv7 fixes and support for UEFI +- UEFI fixes for x86_64 and aarch64 + +* Fri Feb 01 2019 Fedora Release Engineering - 0.16.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Dec 10 2018 Kevin Fenzi - 0.16.0-7 +- Drop unneeded sed fix. + +* Mon Dec 10 2018 Kevin Fenzi - 0.16.0-6 +- Add patch to add rnd device to provide faster random on boot. + +* Fri Jul 13 2018 Fedora Release Engineering - 0.16.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Mar 01 2018 Iryna Shcherbina - 0.16.0-4 +- Update Python 2 dependency declarations to new packaging standards + (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) + +* Sun Feb 18 2018 Chris Lalancette - 0.16.0-3 +- Add s390x support patches + +* Thu Feb 08 2018 Fedora Release Engineering - 0.16.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Aug 08 2017 Chris Lalancette - 0.16.0-1 +- Release 0.16.0 + +* Thu Jul 27 2017 Fedora Release Engineering - 0.15.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 0.15.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Sep 22 2016 Chris Lalancette - 0.15.0-5 +- Remove rawhide dependency on python-uuid + +* Wed Aug 10 2016 Ian McLeod - 0.15.0-4 +- Version bump to simplify upgrade for Fedora rel-eng + +* Tue Aug 9 2016 Ian McLeod - 0.15.0-3 +- Backport patches for ppc and aarch64 builds +- Backport patch related to configurable timeouts + +* Tue Jul 19 2016 Fedora Release Engineering - 0.15.0-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Sun Feb 28 2016 Chris Lalancette - 0.15.0-1 +- Release 0.15.0 + +* Thu Feb 04 2016 Fedora Release Engineering - 0.14.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Jun 26 2015 Chris Lalancette - 0.14.0-1 +- Release 0.14.0 + +* Thu Jun 18 2015 Fedora Release Engineering - 0.13.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat Mar 07 2015 Chris Lalancette - 0.13.0-1 +- Update to release 0.13.0 + +* Sat Jun 07 2014 Fedora Release Engineering - 0.12.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Feb 10 2014 Chris Lalancette - 0.12.0-2 +- Add patch to first qcow2 image type + +* Fri Jan 3 2014 Chris Lalancette - 0.12.0-1 +- Update to release 0.12.0 + +* Thu Aug 8 2013 Chris Lalancette - 0.11.0-2 +- Add in the upstream patch that fixes ICICLE generation with extra elements + +* Sun Jul 28 2013 Chris Lalancette - 0.11.0-1 +- Update to release 0.11.0 + +* Sat Mar 09 2013 Chris Lalancette - 0.10.0-1 +- Update to release 0.10.0 + +* Thu Feb 14 2013 Fedora Release Engineering - 0.9.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Sat Aug 18 2012 Chris Lalancette - 0.9.0-1 +- Update to release 0.9.0 + +* Fri Jul 20 2012 Fedora Release Engineering - 0.8.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon May 14 2012 Pádraig Brady - 0.8.0-1 +- Update to release 0.8.0 + +* Fri Jan 13 2012 Fedora Release Engineering - 0.7.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Sep 16 2011 Chris Lalancette - 0.7.0-1 +- Update to release 0.7.0 + +* Fri Aug 12 2011 Chris Lalancette - 0.5.0-4 +- Make oz require openssh-clients to get the ssh binary + +* Wed Jul 27 2011 Chris Lalancette - 0.5.0-3 +- Minor cleanups to the spec file + +* Tue Jul 05 2011 Pádraig Brady - 0.5.0-2 +- Adjust package as per updated Fedora standards + +* Wed Jun 29 2011 Chris Lalancette - 0.5.0-1 +- Release 0.5.0 + +* Mon Jun 20 2011 Pádraig Brady - 0.4.0-4 +- Include examples/. + +* Wed Jun 15 2011 Pádraig Brady - 0.4.0-3 +- Address rpmlint issues. + +* Fri Jun 10 2011 Pádraig Brady - 0.4.0-2 +- Change to noarch. + +* Tue May 24 2011 Chris Lalancette - 0.4.0-1 +- Release 0.4.0. + +* Wed Mar 30 2011 Chris Lalancette - 0.3.0-1 +- Release 0.3.0. + +* Wed Mar 16 2011 Chris Lalancette - 0.2.0-1 +- Release 0.2.0. + +* Thu Feb 3 2011 Chris Lalancette - 0.1.0-1 +- Initial public release of Oz. + +* Wed Nov 3 2010 Chris Lalancette - 0.0.4-1 +- Initial build.