From dd38a31f68ff7ac66baa7c1f270324b81342d5f8 Mon Sep 17 00:00:00 2001 From: Robert Fairley Date: Thu, 14 Feb 2019 16:18:01 -0500 Subject: [PATCH] Add sysroot.bootloader repo config key The sysroot.bootloader key is used to configure the bootloader that OSTree uses when deploying a sysroot. Having this key allows specifying behavior not to use the default bootloader backend code, which is preferable when creating a first deployment from the sysroot (#1774). As of now, the key can take the values "auto" or "none". If the key is not given, the value defaults to "auto". "auto" causes _ostree_sysroot_query_bootloader() to be used when writing a new deployment, which is the original behavior that dynamically detects which bootloader to use. "none" avoids querying the bootloader dynamically. The BLS config fragments are still written to sysroot/boot/loader/entries for use by higher-level software. More values can be supported in future to specify a single bootloader, different behavior for the bootloader code, or a list of bootloaders to try. Resolves: #1774 --- src/libostree/ostree-repo-private.h | 1 + src/libostree/ostree-repo.c | 50 +++++++++++++++++++++++++++ src/libostree/ostree-repo.h | 3 ++ src/libostree/ostree-sysroot-deploy.c | 21 +++++++++-- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 40be72633d..6bc74c2d23 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -169,6 +169,7 @@ struct OstreeRepo { guint64 payload_link_threshold; gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */ gchar **repo_finders; + gchar *bootloader; /* Configure which bootloader to use. */ OstreeRepo *parent_repo; }; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 37a6cdf0d2..a4f5961cea 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3113,6 +3113,36 @@ reload_remote_config (OstreeRepo *self, return TRUE; } +static gboolean +reload_sysroot_config (OstreeRepo *self, + GCancellable *cancellable, + GError **error) +{ + { g_autofree char *bootloader = NULL; + + if (!ot_keyfile_get_value_with_default (self->config, "sysroot", + "bootloader", "auto", + &bootloader, error)) + return FALSE; + + if (bootloader == NULL) + return glnx_throw (error, "Invalid empty bootloader configuration"); + + /* Can later add support for specifying a single bootloader e.g. + * "grub", "sd-boot", "rpi" here too. See: + * https://github.com/ostreedev/ostree/issues/1719 + * https://github.com/ostreedev/ostree/issues/1801 + */ + if (strcmp (bootloader, "auto") != 0 && + strcmp (bootloader, "none") != 0) + return glnx_throw (error, "Invalid configured bootloader '%s'", bootloader); + + self->bootloader = g_steal_pointer (&bootloader); + } + + return TRUE; +} + /** * ostree_repo_reload_config: * @self: repo @@ -3131,6 +3161,8 @@ ostree_repo_reload_config (OstreeRepo *self, return FALSE; if (!reload_remote_config (self, cancellable, error)) return FALSE; + if (!reload_sysroot_config (self, cancellable, error)) + return FALSE; return TRUE; } @@ -6060,3 +6092,21 @@ ostree_repo_get_default_repo_finders (OstreeRepo *self) return (const gchar * const *)self->repo_finders; } + +/** + * ostree_repo_get_bootloader: + * @self: an #OstreeRepo + * + * Get the bootloader configured. See the documentation for the + * "sysroot.bootloader" config key. + * + * Returns: bootloader configuration for the sysroot + * Since: 2019.2 + */ +const gchar * +ostree_repo_get_bootloader (OstreeRepo *self) +{ + g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); + + return self->bootloader; +} diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 6e325b8b30..7eb983cfa0 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -115,6 +115,9 @@ gboolean ostree_repo_set_collection_id (OstreeRepo *self, _OSTREE_PUBLIC const gchar * const * ostree_repo_get_default_repo_finders (OstreeRepo *self); +_OSTREE_PUBLIC +const gchar * ostree_repo_get_bootloader (OstreeRepo *self); + _OSTREE_PUBLIC GFile * ostree_repo_get_path (OstreeRepo *self); diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index b16f65b334..40725627c9 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2077,6 +2077,7 @@ write_deployments_bootswap (OstreeSysroot *self, cancellable, error)) return FALSE; + // TODO: move this to ostree_sysroot_write_deployments_with_options? /* Need the repo to try and extract the versions for deployments. * But this is a "nice-to-have" for the bootloader UI, so failure * here is not fatal to the whole operation. We just gracefully @@ -2342,9 +2343,23 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, return glnx_throw_errno_prefix (error, "Remounting /boot read-write"); } - if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error)) - return FALSE; - bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader); + g_autoptr(OstreeRepo) repo = NULL; + if (!ostree_sysroot_get_repo (self, &repo, cancellable, error)) + { + return glnx_throw (error, "Getting repo config"); + } + + g_autofree const char *bootloader_config = + ostree_repo_get_bootloader (repo); + + g_debug ("Using bootloader configuration: %s", bootloader_config); + + if (g_strcmp0 (bootloader_config, "auto") == 0) + { + if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error)) + return FALSE; + bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader); + } /* Note equivalent of try/finally here */ gboolean success = write_deployments_bootswap (self, new_deployments, opts, bootloader,