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..418fbe1c0c 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.3 + */ +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..011a849d8b 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 @@ -2310,6 +2311,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, gboolean bootloader_is_atomic = FALSE; SyncStats syncstats = { 0, }; g_autoptr(OstreeBootloader) bootloader = NULL; + g_autofree const char *bootloader_config = NULL; if (!requires_new_bootversion) { if (!create_new_bootlinks (self, self->bootversion, @@ -2342,8 +2344,30 @@ 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; + g_autoptr(OstreeRepo) repo = NULL; + if (!ostree_sysroot_get_repo (self, &repo, cancellable, error)) + { + return glnx_throw (error, "Getting repo config"); + } + + 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; + } + else if (g_strcmp0 (bootloader_config, "none") == 0) + { + /* No bootloader specified; do not query bootloaders to run. */ + } + else + { + return glnx_throw (error, "Invald configured bootloader '%s'", bootloader_config); + } + bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader); /* Note equivalent of try/finally here */ @@ -2375,6 +2399,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_COMPLETE_ID), "MESSAGE=%s", msg, "OSTREE_BOOTLOADER=%s", bootloader ? _ostree_bootloader_get_name (bootloader) : "none", + "OSTREE_BOOTLOADER_CONFIG=%s", bootloader_config, "OSTREE_BOOTLOADER_ATOMIC=%s", bootloader_is_atomic ? "yes" : "no", "OSTREE_DID_BOOTSWAP=%s", requires_new_bootversion ? "yes" : "no", "OSTREE_N_DEPLOYMENTS=%u", new_deployments->len,