From 15ecaacd36bfcb91181400a7399461deef57e062 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 15 Oct 2014 22:10:15 -0400 Subject: [PATCH] compose: Support 'boot_location' to facilitate GRUB2 Having content in /boot in OSTree was always ugly, because we ended up mounting over it in the deployment location at boot. This was even worse in the anaconda rpmostreepayload code, because of the juggling of the mount point that needed to take place. Trying to add a GRUB2 backend to OSTree is what finally forced this change. Now, we put kernels (in the tree) by default in *both* /boot and /usr/lib/ostree-boot. OSTree itself knows to look in both locations. Anaconda is going to just hard require trees with the new location though. --- doc/treefile.md | 8 ++++++ src/rpmostree-compose-builtin-tree.c | 30 +++++++++++++++++-- src/rpmostree-postprocess.c | 43 ++++++++++++++++++++++++++-- src/rpmostree-postprocess.h | 7 +++++ 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/doc/treefile.md b/doc/treefile.md index 56d7fe3810..0a18e45e6a 100644 --- a/doc/treefile.md +++ b/doc/treefile.md @@ -14,6 +14,14 @@ Treefile * `selinux`: boolean, optional: Defaults to `true`. If `false`, then no SELinux labeling will be performed on the server side. + * `boot_location`: string, optional: Historically, ostree put bootloader data + in /boot. However, this has a few flaws; it gets shadowed at boot time, + and also makes dealing with Anaconda installation harder. There are 3 + possible values: + * "legacy": the default, data goes in /boot + * "both": Kernel data in /boot and /usr/lib/ostree-boot + * "new": Kernel data in /usr/lib/ostree-boot + * `bootstrap_packages`: Array of strings, mandatory: The `glibc` and `nss-altfiles` packages (and ideally nothing else) must be in this set; rpm-ostree will modify the `/etc/nsswitch.conf` in the target diff --git a/src/rpmostree-compose-builtin-tree.c b/src/rpmostree-compose-builtin-tree.c index 5287055917..23865e8174 100644 --- a/src/rpmostree-compose-builtin-tree.c +++ b/src/rpmostree-compose-builtin-tree.c @@ -945,8 +945,34 @@ rpmostree_compose_builtin_tree (int argc, if (g_strcmp0 (g_getenv ("RPM_OSTREE_BREAK"), "post-yum") == 0) goto out; - if (!rpmostree_postprocess (yumroot, cancellable, error)) - goto out; + { + const char *boot_location_str = NULL; + RpmOstreePostprocessBootLocation boot_location = + RPMOSTREE_POSTPROCESS_BOOT_LOCATION_BOTH; + + if (!object_get_optional_string_member (treefile, "boot_location", + &boot_location_str, error)) + goto out; + + if (boot_location_str != NULL) + { + if (strcmp (boot_location_str, "legacy") == 0) + boot_location = RPMOSTREE_POSTPROCESS_BOOT_LOCATION_LEGACY; + else if (strcmp (boot_location_str, "both") == 0) + boot_location = RPMOSTREE_POSTPROCESS_BOOT_LOCATION_BOTH; + else if (strcmp (boot_location_str, "new") == 0) + boot_location = RPMOSTREE_POSTPROCESS_BOOT_LOCATION_NEW; + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid boot location '%s'", boot_location_str); + goto out; + } + } + + if (!rpmostree_postprocess (yumroot, boot_location, cancellable, error)) + goto out; + } if (json_object_has_member (treefile, "units")) units = json_object_get_array_member (treefile, "units"); diff --git a/src/rpmostree-postprocess.c b/src/rpmostree-postprocess.c index 3c65126540..7d5d04df38 100644 --- a/src/rpmostree-postprocess.c +++ b/src/rpmostree-postprocess.c @@ -725,6 +725,7 @@ replace_nsswitch (GFile *target_usretc, /* Prepare a root filesystem, taking mainly the contents of /usr from yumroot */ static gboolean create_rootfs_from_yumroot_content (GFile *targetroot, + RpmOstreePostprocessBootLocation boot_location, GFile *yumroot, GCancellable *cancellable, GError **error) @@ -862,9 +863,44 @@ create_rootfs_from_yumroot_content (GFile *targetroot, { gs_unref_object GFile *yumroot_boot = g_file_get_child (yumroot, "boot"); - - if (!move_to_dir (yumroot_boot, targetroot, cancellable, error)) + gs_unref_object GFile *target_boot = + g_file_get_child (targetroot, "boot"); + gs_unref_object GFile *target_usrlib = + g_file_resolve_relative_path (targetroot, "usr/lib"); + gs_unref_object GFile *target_usrlib_ostree_boot = + g_file_resolve_relative_path (target_usrlib, "ostree-boot"); + + if (!gs_file_ensure_directory (target_usrlib, TRUE, cancellable, error)) goto out; + + switch (boot_location) + { + case RPMOSTREE_POSTPROCESS_BOOT_LOCATION_LEGACY: + { + g_print ("Using boot location: legacy\n"); + if (!gs_file_rename (yumroot_boot, target_boot, cancellable, error)) + goto out; + } + break; + case RPMOSTREE_POSTPROCESS_BOOT_LOCATION_BOTH: + { + g_print ("Using boot location: both\n"); + if (!gs_file_rename (yumroot_boot, target_boot, cancellable, error)) + goto out; + /* Hardlink the existing content, only a little ugly as + * we'll end up sha256'ing it twice, but oh well. */ + if (!gs_shutil_cp_al_or_fallback (target_boot, target_usrlib_ostree_boot, cancellable, error)) + goto out; + } + break; + case RPMOSTREE_POSTPROCESS_BOOT_LOCATION_NEW: + { + g_print ("Using boot location: new\n"); + if (!gs_file_rename (yumroot_boot, target_usrlib_ostree_boot, cancellable, error)) + goto out; + } + break; + } } /* Also carry along toplevel compat links */ @@ -910,6 +946,7 @@ create_rootfs_from_yumroot_content (GFile *targetroot, gboolean rpmostree_postprocess (GFile *rootfs, + RpmOstreePostprocessBootLocation boot_location, GCancellable *cancellable, GError **error) { @@ -923,7 +960,7 @@ rpmostree_postprocess (GFile *rootfs, if (!gs_shutil_rm_rf (rootfs_tmp, cancellable, error)) goto out; - if (!create_rootfs_from_yumroot_content (rootfs_tmp, rootfs, cancellable, error)) + if (!create_rootfs_from_yumroot_content (rootfs_tmp, boot_location, rootfs, cancellable, error)) goto out; if (!gs_shutil_rm_rf (rootfs, cancellable, error)) diff --git a/src/rpmostree-postprocess.h b/src/rpmostree-postprocess.h index f96516e689..0d3afac81c 100644 --- a/src/rpmostree-postprocess.h +++ b/src/rpmostree-postprocess.h @@ -22,8 +22,15 @@ #include +typedef enum { + RPMOSTREE_POSTPROCESS_BOOT_LOCATION_LEGACY, + RPMOSTREE_POSTPROCESS_BOOT_LOCATION_BOTH, + RPMOSTREE_POSTPROCESS_BOOT_LOCATION_NEW +} RpmOstreePostprocessBootLocation; + gboolean rpmostree_postprocess (GFile *rootfs, + RpmOstreePostprocessBootLocation boot_style, GCancellable *cancellable, GError **error);