Skip to content

Commit

Permalink
Add sysroot.bootloader repo config key
Browse files Browse the repository at this point in the history
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 (ostreedev#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: ostreedev#1774
  • Loading branch information
Robert Fairley committed Feb 25, 2019
1 parent 1f18109 commit a29773b
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 19 deletions.
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
67 changes: 51 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,41 @@ Boston, MA 02111-1307, USA.

</refsect1>

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

<para>
Options for the sysroot, which OSTree deploys the OSTree repository to. 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 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
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
41 changes: 41 additions & 0 deletions src/libostree/ostree-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -3113,6 +3113,27 @@ 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_group_optional (self->config, "sysroot",
"bootloader", "auto",
&bootloader, error))
return FALSE;

if (bootloader == NULL)
return glnx_throw (error, "Invalid empty bootloader configuration");

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

return TRUE;
}

/**
* ostree_repo_reload_config:
* @self: repo
Expand All @@ -3131,6 +3152,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 @@ -6064,3 +6087,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
34 changes: 32 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,36 @@ 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, "Loading repo config");

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. */
}
else
{
/* TODO: later add support for specifying a generic
* bootloader binary here (e.g. bootloader=x means
* run /usr/lib/ostree/bootloaders/x). Override
* with /etc/ostree/bootloaders/x possibly.
* See:
* https://github.com/ostreedev/ostree/issues/1719
* https://github.com/ostreedev/ostree/issues/1801
*/
return glnx_throw (error, "Unsupported bootloader option '%s'", bootloader_config);
}

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

/* Note equivalent of try/finally here */
Expand Down Expand Up @@ -2375,6 +2404,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
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
52 changes: 52 additions & 0 deletions tests/test-admin-deploy-none.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash
#
# Copyright (C) 2019 Robert Fairley <rfairley@redhat.com>
#
# SPDX-License-Identifier: LGPL-2.0+
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

# Exports OSTREE_SYSROOT so --sysroot not needed.
setup_os_repository "archive" "sysroot.bootloader none"

extra_admin_tests=2

. $(dirname $0)/admin-test.sh

# Test that the bootloader configuration "none" on first deployment
# generates BLS config snippets, see https://github.com/ostreedev/ostree/issues/1774.
cd ${test_tmpdir}
rm httpd osdata testos-repo sysroot -rf
setup_os_repository "archive" "sysroot.bootloader none"
${CMD_PREFIX} ostree pull-local --repo=sysroot/ostree/repo --remote testos testos-repo testos/buildmaster/x86_64-runtime
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os testos testos/buildmaster/x86_64-runtime > out.txt
assert_file_has_content out.txt "Bootloader updated.*"
assert_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'options.* root=LABEL=MOO'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0.img 'an initramfs'
echo "ok generate bls config on first deployment"

# Test failure on unsupported bootloader config option.
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.bootloader unsupported_bootloader
if ${CMD_PREFIX} ostree admin deploy --os testos testos/buildmaster/x86_64-runtime 2>err.txt; then
assert_not_reached "unexpectedly succeeded at deploying with unsupported bootloader config"
fi
assert_file_has_content err.txt "Unsupported bootloader.*unsupported_bootloader"
echo "ok fail on unsupported bootloader config"
4 changes: 3 additions & 1 deletion tests/test-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ${CMD_PREFIX} ostree config --repo=repo get --group=core repo_version >> list.tx
${CMD_PREFIX} ostree config --repo=repo get --group='remote "flathub"' 'xa.title' >> list.txt
${CMD_PREFIX} ostree config --repo=repo get --group='remote "flathub"' 'xa.title-is-set' >> list.txt
${CMD_PREFIX} ostree config --repo=repo get --group='remote "org.mozilla.FirefoxRepo"' url >> list.txt
${CMD_PREFIX} cat list.txt
${CMD_PREFIX} cat list.txt

assert_file_has_content list.txt "bare"
assert_file_has_content list.txt "1"
Expand All @@ -44,11 +44,13 @@ assert_file_has_content list.txt "http://example.com/ostree/repo/"
echo "ok config get"

${CMD_PREFIX} ostree config --repo=repo set core.mode bare-user-only
${CMD_PREFIX} ostree config --repo=repo set sysroot.bootloader some_bootloader
${CMD_PREFIX} ostree config --repo=repo set --group='remote "flathub"' 'xa.title' 'Nightly Flathub'
${CMD_PREFIX} ostree config --repo=repo set --group='remote "flathub"' 'xa.title-is-set' 'false'
${CMD_PREFIX} ostree config --repo=repo set --group='remote "org.mozilla.FirefoxRepo"' url http://example.com/ostree/

assert_file_has_content repo/config "bare-user-only"
assert_file_has_content repo/config "some_bootloader"
assert_file_has_content repo/config "Nightly Flathub"
assert_file_has_content repo/config "false"
assert_file_has_content repo/config "http://example.com/ostree/"
Expand Down

0 comments on commit a29773b

Please sign in to comment.