Add sysroot.bootloader repo config key

The sysroot.bootloader key configures 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

Closes: #1814
Approved by: jlebon
This commit is contained in:
Robert Fairley 2019-02-14 16:18:01 -05:00 committed by Atomic Bot
parent 99cf13b225
commit 21ebc7d21e
8 changed files with 181 additions and 18 deletions

View File

@ -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 \

View File

@ -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>
@ -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>

View File

@ -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;
};

View File

@ -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;
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
@ -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;
}
@ -6064,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;
}

View File

@ -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);

View File

@ -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,
@ -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 */
@ -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,

View File

@ -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
@ -448,6 +453,9 @@ EOF
*grub2*)
setup_os_boot_grub2 "${bootmode}"
;;
sysroot\.bootloader*)
setup_os_boot_configured_bootloader "${bootmode}"
;;
esac
cd ${test_tmpdir}

52
tests/test-admin-deploy-none.sh Executable file
View File

@ -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=1
. $(dirname $0)/admin-test.sh
# Test that the bootloader configuration "none" generates BLS config snippets.
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
# Test grub2 does not get detected with bootloader configuration "none"
# (see https://github.com/ostreedev/ostree/issues/1774)
mkdir -p sysroot/boot/grub2 && touch sysroot/boot/grub2/grub.cfg
${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"
# TODO: add tests to try setting with an unsupported bootloader config,
# once https://github.com/ostreedev/ostree/issues/1827 is solved.
# The tests should check that the following commands fail:
# ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.bootloader unsupported_bootloader
# ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.bootloader ""