Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sysroot.bootloader repo config key (fix running bootloader when no deployments exist) #1814

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile-tests.am
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ _installed_or_uninstalled_test_scripts = \
tests/test-admin-deploy-etcmerge-cornercases.sh \
tests/test-admin-deploy-uboot.sh \
tests/test-admin-deploy-grub2.sh \
tests/test-admin-deploy-none.sh \
tests/test-admin-deploy-bootid-gc.sh \
tests/test-admin-instutil-set-kargs.sh \
tests/test-admin-upgrade-not-backwards.sh \
Expand Down
68 changes: 52 additions & 16 deletions man/ostree.repo-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,22 @@ Boston, MA 02111-1307, USA.
ensure files are on stable storage when performing operations
such as commits, pulls, and checkouts. Defaults to
<literal>true</literal>.</para>
<para>
If you disable fsync, OSTree will no longer be robust
against kernel crashes or power loss.
</para>
<para>
You might choose to disable this for local development
repositories, under the assumption they can be recreated from
source. Similarly, you could disable for a mirror where you could
re-pull.
</para>
<para>
For the system repository, you might choose to disable fsync
if you have uninterruptable power supplies and a well tested
kernel.
</para>
</listitem>
<para>
If you disable fsync, OSTree will no longer be robust
against kernel crashes or power loss.
</para>
<para>
You might choose to disable this for local development
repositories, under the assumption they can be recreated from
source. Similarly, you could disable for a mirror where you could
re-pull.
</para>
<para>
For the system repository, you might choose to disable fsync
if you have uninterruptable power supplies and a well tested
kernel.
</para>
</listitem>
</varlistentry>

<varlistentry>
Expand Down Expand Up @@ -333,6 +333,42 @@ Boston, MA 02111-1307, USA.

</refsect1>

<refsect1>
<title>[sysroot] Section Options</title>

<para>
Options for the sysroot, which contains the OSTree repository,
deployments, and stateroots. The following entries are defined:
</para>

<variablelist>

<varlistentry>
<term><varname>bootloader</varname></term>
<listitem><para>Configure the bootloader that OSTree uses when
deploying the sysroot. This may take the values
<literal>bootloader=none</literal> or <literal>bootloader=auto</literal>.
Default is <literal>auto</literal>.
</para>
<para>
If <literal>none</literal>, then OSTree will generate only BLS (Boot
Loader Specification) fragments in <literal>sysroot/boot/loader/entries/</literal>
for the deployment.
</para>
<para>
If <literal>auto</literal>, then in addition to generating BLS
fragments, OSTree will dynamically check for the existence of grub2,
uboot, and syslinux bootloaders. If one of the bootloaders is found,
then OSTree will generate a config for the bootloader found. For
example, <literal>grub2-mkconfig</literal> is run for the grub2 case.
</para>
</listitem>
</varlistentry>

</variablelist>

</refsect1>

<refsect1>
<title>/etc/ostree/remotes.d</title>

Expand Down
2 changes: 1 addition & 1 deletion src/boot/grub2/ostree-grub-generator
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ read_config()

populate_menu()
{
# Default to /boot if OSTREE_BOOT_PARTITION is not set and /boot is on the same device than ostree/repo
# Default to /boot if OSTREE_BOOT_PARTITION is not set and /boot is on the same device as /ostree/repo
if [ -z ${OSTREE_BOOT_PARTITION+x} ] && [ -d /boot/ostree ] && [ -d /ostree/repo ] && [ $(stat -c '%d' /boot/ostree) -eq $(stat -c '%d' /ostree/repo) ]; then
boot_prefix="/boot"
else
Expand Down
1 change: 1 addition & 0 deletions src/libostree/ostree-repo-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
54 changes: 52 additions & 2 deletions src/libostree/ostree-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,32 @@ reload_remote_config (OstreeRepo *self,
return TRUE;
}

static gboolean
reload_sysroot_config (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
{ g_autofree char *bootloader = NULL;
rfairley marked this conversation as resolved.
Show resolved Hide resolved

if (!ot_keyfile_get_value_with_default_group_optional (self->config, "sysroot",
"bootloader", "auto",
&bootloader, error))
return FALSE;

/* TODO: possibly later add support for specifying a generic bootloader
* binary "x" in /usr/lib/ostree/bootloaders/x). See:
* https://github.com/ostreedev/ostree/issues/1719
* https://github.com/ostreedev/ostree/issues/1801
*/
if (!(g_str_equal (bootloader, "auto") || g_str_equal (bootloader, "none")))
return glnx_throw (error, "Invalid bootloader configuration: '%s'", bootloader);

self->bootloader = g_steal_pointer (&bootloader);
}

return TRUE;
}

/**
* ostree_repo_reload_config:
* @self: repo
Expand All @@ -3131,6 +3157,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;
}

Expand Down Expand Up @@ -5186,8 +5214,12 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,

rfairley marked this conversation as resolved.
Show resolved Hide resolved
g_auto(GStrv) gpgkeypath_list = NULL;

if (!ot_keyfile_get_string_as_list (remote->options, remote->group, "gpgkeypath",
";,", &gpgkeypath_list, error))
if (!ot_keyfile_get_string_list_with_separator_choice (remote->options,
remote->group,
"gpgkeypath",
";,",
&gpgkeypath_list,
error))
return NULL;

if (gpgkeypath_list)
Expand Down Expand Up @@ -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;
}
3 changes: 3 additions & 0 deletions src/libostree/ostree-repo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
20 changes: 18 additions & 2 deletions src/libostree/ostree-sysroot-deploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2310,6 +2310,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
gboolean bootloader_is_atomic = FALSE;
SyncStats syncstats = { 0, };
g_autoptr(OstreeBootloader) bootloader = NULL;
const char *bootloader_config = NULL;
if (!requires_new_bootversion)
{
if (!create_new_bootlinks (self, self->bootversion,
Expand Down Expand Up @@ -2342,8 +2343,22 @@ 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;
OstreeRepo *repo = ostree_sysroot_repo (self);

bootloader_config = ostree_repo_get_bootloader (repo);

g_debug ("Using bootloader configuration: %s", bootloader_config);

if (g_str_equal (bootloader_config, "auto"))
{
if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error))
return FALSE;
}
else if (g_str_equal (bootloader_config, "none"))
{
/* No bootloader specified; do not query bootloaders to run. */
}

bootloader_is_atomic = bootloader != NULL && _ostree_bootloader_is_atomic (bootloader);

/* Note equivalent of try/finally here */
Expand Down Expand Up @@ -2375,6 +2390,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,
Expand Down
59 changes: 47 additions & 12 deletions src/libotutil/ot-keyfile-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,55 @@ ot_keyfile_get_value_with_default (GKeyFile *keyfile,
return ret;
}

/* Read the value of key as a string. If the value string contains
* one of the separators and none of the others, read the
* string as a NULL-terminated array out_value. If the value string contains
* none of the separators, read the string as a single entry into a
* NULL-terminated array out_value. If the value string contains multiple of
* the separators, an error is given.
gboolean
ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile,
const char *section,
const char *value,
const char *default_value,
char **out_value,
GError **error)
{
jlebon marked this conversation as resolved.
Show resolved Hide resolved
gboolean ret = FALSE;
GError *local_error = NULL;
g_autofree char *ret_value = NULL;

g_return_val_if_fail (keyfile != NULL, ret);
g_return_val_if_fail (section != NULL, ret);
g_return_val_if_fail (value != NULL, ret);

if (!ot_keyfile_get_value_with_default (keyfile, section, value, default_value, &ret_value, &local_error))
{
if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
{
g_clear_error (&local_error);
ret_value = g_strdup (default_value);
}
else
{
g_propagate_error (error, local_error);
goto out;
}
}

ret = TRUE;
ot_transfer_out_value(out_value, &ret_value);
out:
return ret;
}

/* Read the value of key as a string. If the value string contains
* zero or one of the separators and none of the others, read the
* string as a NULL-terminated array out_value. If the value string
* contains multiple of the separators, give an error.
*
* Returns TRUE on success, FALSE on error. */
gboolean
ot_keyfile_get_string_as_list (GKeyFile *keyfile,
const char *section,
const char *key,
const char *separators,
char ***out_value,
GError **error)
ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile,
const char *section,
const char *key,
const char *separators,
char ***out_value,
GError **error)
{
guint sep_count = 0;
gchar sep = '\0';
Expand Down
20 changes: 14 additions & 6 deletions src/libotutil/ot-keyfile-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,20 @@ ot_keyfile_get_value_with_default (GKeyFile *keyfile,
GError **error);

gboolean
ot_keyfile_get_string_as_list (GKeyFile *keyfile,
const char *section,
const char *key,
const char *separators,
char ***out_value_list,
GError **error);
ot_keyfile_get_value_with_default_group_optional (GKeyFile *keyfile,
const char *section,
const char *value,
const char *default_value,
char **out_value,
GError **error);

gboolean
ot_keyfile_get_string_list_with_separator_choice (GKeyFile *keyfile,
const char *section,
const char *key,
const char *separators,
char ***out_value_list,
GError **error);

gboolean
ot_keyfile_get_string_list_with_default (GKeyFile *keyfile,
Expand Down
8 changes: 8 additions & 0 deletions tests/libtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ setup_os_boot_grub2() {
esac
}

setup_os_boot_configured_bootloader() {
bootloader_keyval=$1
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set ${bootloader_keyval}
}

setup_os_repository () {
mode=$1
shift
Expand Down Expand Up @@ -448,6 +453,9 @@ EOF
*grub2*)
setup_os_boot_grub2 "${bootmode}"
;;
sysroot\.bootloader*)
setup_os_boot_configured_bootloader "${bootmode}"
;;
esac

cd ${test_tmpdir}
Expand Down
Loading