From 1b31d5e50b06caf92035094b8ec59b53b43d2943 Mon Sep 17 00:00:00 2001 From: Ian McLeod Date: Aug 11 2016 21:20:06 +0000 Subject: update to enable some upstream aarch64 and ppc64 enabling bits --- diff --git a/oz-secondaryarch.patch b/oz-secondaryarch.patch new file mode 100644 index 0000000..71a518a --- /dev/null +++ b/oz-secondaryarch.patch @@ -0,0 +1,200 @@ +diff --git a/oz.cfg b/oz.cfg +index 5be1cb0..8913f9d 100644 +--- a/oz.cfg ++++ b/oz.cfg +@@ -19,3 +19,9 @@ jeos = no + + [icicle] + safe_generation = no ++ ++[timeouts] ++install = 1200 ++inactivity = 300 ++boot = 300 ++shutdown = 90 +diff --git a/oz/Guest.py b/oz/Guest.py +index 54a0e8c..22c93c4 100644 +--- a/oz/Guest.py ++++ b/oz/Guest.py +@@ -203,6 +203,16 @@ class Guest(object): + 'safe_generation', + False) + ++ # configuration of 'timeouts' section ++ self.default_install_timeout = int(oz.ozutil.config_get_key(config, 'timeouts', ++ 'install', 1200)) ++ self.inactivity_timeout = int(oz.ozutil.config_get_key(config, 'timeouts', ++ 'inactivity', 300)) ++ self.boot_timeout = int(oz.ozutil.config_get_key(config, 'timeouts', ++ 'boot', 300)) ++ self.shutdown_timeout = int(oz.ozutil.config_get_key(config, 'timeouts', ++ 'shutdown', 90)) ++ + # only pull a cached JEOS if it was built with the correct image type + jeos_extension = self.image_type + if self.image_type == 'raw': +@@ -471,6 +481,10 @@ class Guest(object): + if self.tdl.arch == "armv7l": + cmdline += " console=ttyAMA0" + self.lxml_subelement(osNode, "cmdline", cmdline) ++ if self.tdl.arch == "aarch64": ++ loader,nvram = oz.ozutil.find_uefi_firmware(self.tdl.arch) ++ self.lxml_subelement(osNode, "loader", loader, {'readonly': 'yes', 'type': 'pflash'}) ++ self.lxml_subelement(osNode, "nvram", None, {'template': nvram}) + # poweroff, reboot, crash + self.lxml_subelement(domain, "on_poweroff", "destroy") + self.lxml_subelement(domain, "on_reboot", "destroy") +@@ -761,8 +775,7 @@ class Guest(object): + # the passed in exception was None, just raise a generic error + raise oz.OzException.OzException("Unknown libvirt error") + +- def _wait_for_install_finish(self, libvirt_dom, count, +- inactivity_timeout=300): ++ def _wait_for_install_finish(self, libvirt_dom, count): + """ + Method to wait for an installation to finish. This will wait around + until either the VM has gone away (at which point it is assumed the +@@ -774,7 +787,7 @@ class Guest(object): + + last_disk_activity = 0 + last_network_activity = 0 +- inactivity_countdown = inactivity_timeout ++ inactivity_countdown = self.inactivity_timeout + origcount = count + saved_exception = None + while count > 0 and inactivity_countdown > 0: +@@ -809,7 +822,7 @@ class Guest(object): + inactivity_countdown -= 1 + else: + # if we did see some activity, then we can reset the timer +- inactivity_countdown = inactivity_timeout ++ inactivity_countdown = self.inactivity_timeout + + last_disk_activity = total_disk_req + last_network_activity = total_net_bytes +@@ -826,18 +839,19 @@ class Guest(object): + # if we saw no disk or network activity in the countdown window, + # we presume the install has hung. Fail here + screenshot_text = self._capture_screenshot(libvirt_dom) +- raise oz.OzException.OzException("No disk activity in %d seconds, failing. %s" % (inactivity_timeout, screenshot_text)) ++ raise oz.OzException.OzException("No disk activity in %d seconds, failing. %s" % (self.inactivity_timeout, screenshot_text)) + + # We get here only if we got a libvirt exception + self._wait_for_clean_shutdown(libvirt_dom, saved_exception) + + self.log.info("Install of %s succeeded", self.tdl.name) + +- def _wait_for_guest_shutdown(self, libvirt_dom, count=90): ++ def _wait_for_guest_shutdown(self, libvirt_dom): + """ + Method to wait around for orderly shutdown of a running guest. Returns + True if the guest shutdown in the specified time, False otherwise. + """ ++ count = self.shutdown_timeout + origcount = count + saved_exception = None + while count > 0: +@@ -1235,12 +1249,12 @@ class Guest(object): + sock.connect(('127.0.0.1', self.listen_port)) + + addr = None +- count = 300 ++ count = self.boot_timeout + data = '' + while count > 0: + do_sleep = True + if count % 10 == 0: +- self.log.debug("Waiting for guest %s to boot, %d/300", self.tdl.name, count) ++ self.log.debug("Waiting for guest %s to boot, %d/%d", self.tdl.name, count, self.boot_timeout) + try: + # note that we have to build the data up here, since there + # is no guarantee that we will get the whole write in one go +diff --git a/oz/RedHat.py b/oz/RedHat.py +index aaa102c..896edb7 100644 +--- a/oz/RedHat.py ++++ b/oz/RedHat.py +@@ -334,6 +334,11 @@ label customiso + # part 4; make sure the guest announces itself + self.log.debug("Step 4: Guest announcement") + ++ if self.tdl.arch in [ 'ppc64', 'ppc64le' ]: ++ announce_device = '/dev/hvc1' ++ else: ++ announce_device = '/dev/ttyS1' ++ + scriptfile = os.path.join(self.icicle_tmp, "script") + + if g_handle.exists("/etc/NetworkManager/dispatcher.d"): +@@ -342,9 +347,9 @@ label customiso + #!/bin/bash + + if [ "$1" = "eth0" -a "$2" = "up" ]; then +- echo -n "!$DHCP4_IP_ADDRESS,%s!" > /dev/ttyS1 ++ echo -n "!$DHCP4_IP_ADDRESS,%s!" > %s + fi +-""" % (self.uuid)) ++""" % (self.uuid, announce_device)) + + try: + g_handle.upload(scriptfile, +@@ -364,8 +369,8 @@ DEV=$(/bin/awk '{if ($2 == 0) print $1}' /proc/net/route) && + [ -z "$DEV" ] && exit 0 + ADDR=$(/sbin/ip -4 -o addr show dev $DEV | /bin/awk '{print $4}' | /bin/cut -d/ -f1) && + [ -z "$ADDR" ] && exit 0 +-echo -n "!$ADDR,%s!" > /dev/ttyS1 +-""" % (self.uuid)) ++echo -n "!$ADDR,%s!" > %s ++""" % (self.uuid, announce_device)) + + try: + g_handle.upload(scriptfile, '/root/reportip') +diff --git a/oz/ozutil.py b/oz/ozutil.py +index eb4cd6f..775576b 100644 +--- a/oz/ozutil.py ++++ b/oz/ozutil.py +@@ -970,3 +970,45 @@ def recursively_add_write_bit(inputdir): + except OSError as err: + if err.errno != errno.ENOENT: + raise ++ ++def find_uefi_firmware(arch): ++ # Yuck. Finding the UEFI firmware to start certain guests (like aarch64) ++ # is a really nasty process. While slightly out of date, this blog post ++ # describes the mess: http://blog.wikichoon.com/2016/01/uefi-support-in-virt-install-and-virt.html ++ # Here, we replicate what libguestfs is doing here, which is to essentially ++ # hardcode paths where UEFI firmware can be found on popular distributions. ++ # I verified that these files exist on both Fedora/RHEL and Ubuntu. ++ # Hopefully there will be a nicer way to do this in the future. ++ class UEFI(object): ++ def __init__(self, loader, nvram): ++ self.loader = loader ++ self.nvram = nvram ++ ++ def exists(self): ++ if os.path.exists(self.loader) and os.path.exists(self.nvram): ++ return True ++ return False ++ ++ if arch in ['i386', 'i486', 'i586', 'i686']: ++ uefi_list = [UEFI('/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd', ++ '/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd')] ++ elif arch in ['x86_64']: ++ uefi_list = [UEFI('/usr/share/OVMF/OVMF_CODE.fd', ++ '/usr/share/OVMF/OVMF_VARS.fd'), ++ UEFI('/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd', ++ '/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd')] ++ elif arch in ['aarch64']: ++ uefi_list = [UEFI('/usr/share/AAVMF/AAVMF_CODE.fd', ++ '/usr/share/AAVMF/AAVMF_VARS.fd'), ++ UEFI('/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw', ++ '/usr/share/edk2/aarch64/vars-template-pflash.raw'), ++ UEFI('/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw', ++ '/usr/share/edk2.git/aarch64/vars-template-pflash.raw')] ++ else: ++ raise Exception("Invalid arch for UEFI firmware") ++ ++ for uefi in uefi_list: ++ if uefi.exists(): ++ return uefi.loader,uefi.nvram ++ ++ raise Exception("UEFI firmware is not installed!") diff --git a/oz.spec b/oz.spec index 2a82c8d..f2b863d 100644 --- a/oz.spec +++ b/oz.spec @@ -1,11 +1,12 @@ Summary: Library and utilities for automated guest OS installs Name: oz Version: 0.15.0 -Release: 2%{?dist} +Release: 4%{?dist} License: LGPLv2 Group: Development/Libraries URL: http://github.com/clalancette/oz Source0: http://github.com/clalancette/%{name}/files/150178/%{name}-%{version}.tar.gz +Patch0: oz-secondaryarch.patch BuildArch: noarch Requires: python >= 2.5 Requires: python-libguestfs >= 1.18 @@ -33,6 +34,7 @@ installations, with minimal input from the user. %prep %setup -q +%patch0 -p1 %build python setup.py build @@ -80,6 +82,13 @@ fi %{_mandir}/man1/* %changelog +* 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