fbcaed
From 273559fae459326ff6fccfe5cc026020daf151f6 Mon Sep 17 00:00:00 2001
fbcaed
From: Colin Walters <walters@verbum.org>
fbcaed
Date: Fri, 17 Oct 2014 00:01:25 -0400
fbcaed
Subject: [PATCH 2/5] rpmostreepayload: Copy all subdirectories of
fbcaed
 /usr/lib/ostree-boot
fbcaed
fbcaed
Previously we were special casing extlinux/ and grub2/, but this
fbcaed
misses out on efi/.  To support rpmostreepayload + GRUB2 + EFI, we
fbcaed
need special handling here.  Any bootloaders installing files in /boot
fbcaed
instead of a subdirectory will then need to be special cased (or
fbcaed
"fixed").
fbcaed
fbcaed
Now in a perfect world, I'd have a time machine and we could go back
fbcaed
and have every bootloader install in a subdirectory /boot/data or
fbcaed
something.  But we basically can't change existing systems, which kind
fbcaed
of traps us into the current RPM-level layout forever, with rpm-ostree
fbcaed
postprocessing it.
fbcaed
fbcaed
(One could argue it's rpm-ostree's job to postprocess this so Anaconda
fbcaed
 wouldn't have to care.  Open to that.)
fbcaed
---
fbcaed
 pyanaconda/packaging/rpmostreepayload.py | 60 +++++++++++++++++++++++---------
fbcaed
 1 file changed, 44 insertions(+), 16 deletions(-)
fbcaed
fbcaed
diff --git a/pyanaconda/packaging/rpmostreepayload.py b/pyanaconda/packaging/rpmostreepayload.py
fbcaed
index dfb0466..bf8d7e1 100644
fbcaed
--- a/pyanaconda/packaging/rpmostreepayload.py
fbcaed
+++ b/pyanaconda/packaging/rpmostreepayload.py
fbcaed
@@ -89,6 +89,41 @@ class RPMOSTreePayload(ArchivePayload):
fbcaed
         else:
fbcaed
             progressQ.send_message("Writing objects")
fbcaed
 
fbcaed
+    def _copyBootloaderData(self):
fbcaed
+        # Copy bootloader data files from the deployment
fbcaed
+        # checkout to the target root.  See
fbcaed
+        # https://bugzilla.gnome.org/show_bug.cgi?id=726757 This
fbcaed
+        # happens once, at installation time.
fbcaed
+        # extlinux ships its modules directly in the RPM in /boot.
fbcaed
+        # For GRUB2, Anaconda installs device.map there.  We may need
fbcaed
+        # to add other bootloaders here though (if they can't easily
fbcaed
+        # be fixed to *copy* data into /boot at install time, instead
fbcaed
+        # of shipping it in the RPM).
fbcaed
+        physboot = iutil.getTargetPhysicalRoot() + '/boot'
fbcaed
+        ostree_boot_source = iutil.getSysroot() + '/usr/lib/ostree-boot'
fbcaed
+        if not os.path.isdir(ostree_boot_source):
fbcaed
+            ostree_boot_source = iutil.getSysroot() + '/boot'
fbcaed
+        for fname in os.listdir(ostree_boot_source):
fbcaed
+            srcpath = os.path.join(ostree_boot_source, fname)
fbcaed
+            destpath = os.path.join(physboot, fname)
fbcaed
+
fbcaed
+            # We're only copying directories
fbcaed
+            if not os.path.isdir(srcpath):
fbcaed
+                continue
fbcaed
+
fbcaed
+            # Special handling for EFI, as it's a mount point that's
fbcaed
+            # expected to already exist (so if we used copytree, we'd
fbcaed
+            # traceback).  If it doesn't, we're not on a UEFI system,
fbcaed
+            # so we don't want to copy the data.
fbcaed
+            if fname == 'efi' and os.path.isdir(destpath):
fbcaed
+                for subname in os.listdir(srcpath):
fbcaed
+                    sub_srcpath = os.path.join(srcpath, subname)
fbcaed
+                    sub_destpath = os.path.join(destpath, subname)
fbcaed
+                    self._safeExecWithRedirect('cp', ['-r', '-p', sub_srcpath, sub_destpath])
fbcaed
+            else:
fbcaed
+                log.info("Copying bootloader data: " + fname)
fbcaed
+                shutil.copytree(srcpath, destpath)
fbcaed
+
fbcaed
     def install(self):
fbcaed
         mainctx = GLib.MainContext.new()
fbcaed
         mainctx.push_thread_default()
fbcaed
@@ -161,22 +196,15 @@ class RPMOSTreePayload(ArchivePayload):
fbcaed
         deployment_path = sysroot.get_deployment_directory(deployment)
fbcaed
         iutil.setSysroot(deployment_path.get_path())
fbcaed
 
fbcaed
-        # Copy specific bootloader data files from the deployment
fbcaed
-        # checkout to the target root.  See
fbcaed
-        # https://bugzilla.gnome.org/show_bug.cgi?id=726757 This
fbcaed
-        # happens once, at installation time.
fbcaed
-        # extlinux ships its modules directly in the RPM in /boot.
fbcaed
-        # For GRUB2, Anaconda installs device.map there.  We may need
fbcaed
-        # to add other bootloaders here though (if they can't easily
fbcaed
-        # be fixed to *copy* data into /boot at install time, instead
fbcaed
-        # of shipping it in the RPM).
fbcaed
-        physboot = iutil.getTargetPhysicalRoot() + '/boot'
fbcaed
-        sysboot = iutil.getSysroot() + '/boot'
fbcaed
-        for fname in ['extlinux', 'grub2']:
fbcaed
-            srcpath = os.path.join(sysboot, fname)
fbcaed
-            if os.path.isdir(srcpath):
fbcaed
-                log.info("Copying bootloader data: " + fname)
fbcaed
-                shutil.copytree(srcpath, os.path.join(physboot, fname))
fbcaed
+        try:
fbcaed
+            self._copyBootloaderData()
fbcaed
+        except (OSError, RuntimeError) as e:
fbcaed
+            exn = PayloadInstallError("Failed to copy bootloader data: %s" % e)
fbcaed
+            log.error(str(exn))
fbcaed
+            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
fbcaed
+                progressQ.send_quit(1)
fbcaed
+                iutil.ipmi_report(constants.IPMI_ABORTED)
fbcaed
+                sys.exit(1)
fbcaed
 
fbcaed
         mainctx.pop_thread_default()
fbcaed
 
fbcaed
-- 
fbcaed
1.8.3.1
fbcaed