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

prepare-root: Introduce ostree/prepare-root.conf && sysroot.readonly improvements #2930

Merged
merged 3 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 17 additions & 0 deletions man/ostree-prepare-root.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
</para>
</refsect1>

<refsect1>
<title>Configuration</title>

<para>
The <literal>/usr/lib/ostree/prepare-root.conf</literal> (or <literal>/etc/ostree/prepare-root.conf</literal>) config file is parsed by <literal>ostree-prepare-root</literal>. This file must
be present in the initramfs. The default dracut module will copy it from the real root if present.
</para>

<variablelist>
<varlistentry>
<term><varname>sysroot.readonly</varname></term>
<listitem><para>A boolean value; the default is false. If this is set to <literal>true</literal>, then the <literal>/sysroot</literal> mount point is mounted read-only.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>


<refsect1>
<title>systemd</title>

Expand Down
5 changes: 5 additions & 0 deletions src/boot/dracut/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ depends() {

install() {
dracut_install /usr/lib/ostree/ostree-prepare-root
for r in /usr/lib /etc; do
if test -f "$r/ostree/prepare-root.conf"; then
inst_simple "$r/ostree/prepare-root.conf"
fi
done
inst_simple "${systemdsystemunitdir}/ostree-prepare-root.service"
mkdir -p "${initdir}${systemdsystemconfdir}/initrd-root-fs.target.wants"
ln_r "${systemdsystemunitdir}/ostree-prepare-root.service" \
Expand Down
62 changes: 58 additions & 4 deletions src/switchroot/ostree-prepare-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,16 @@
#include <ostree-core.h>
#include <ostree-repo-private.h>

#include "ot-keyfile-utils.h"
#include "otcore.h"

// The path to the config file for this binary
const char *config_roots[] = { "/usr/lib", "/etc" };
#define PREPARE_ROOT_CONFIG_PATH "ostree/prepare-root.conf"

#define SYSROOT_KEY "sysroot"
#define READONLY_KEY "readonly"

// The kernel argument we support to configure composefs.
#define OT_COMPOSEFS_KARG "ot-composefs"

Expand All @@ -91,6 +99,35 @@

#include "ostree-mount-util.h"

// Load our config file; if it doesn't exist, we return an empty configuration.
// NULL will be returned if we caught an error.
static GKeyFile *
load_config (GError **error)
{
g_autoptr (GKeyFile) ret = g_key_file_new ();

for (guint i = 0; i < G_N_ELEMENTS (config_roots); i++)
{
glnx_autofd int fd = -1;
g_autofree char *path = g_build_filename (config_roots[i], PREPARE_ROOT_CONFIG_PATH, NULL);
if (!ot_openat_ignore_enoent (AT_FDCWD, path, &fd, error))
return NULL;
/* If the config file doesn't exist, that's OK */
if (fd == -1)
continue;

g_print ("Loading %s\n", path);

g_autofree char *buf = glnx_fd_readall_utf8 (fd, NULL, NULL, error);
if (!buf)
return NULL;
if (!g_key_file_load_from_data (ret, buf, -1, 0, error))
return NULL;
}

return g_steal_pointer (&ret);
}

static bool
sysroot_is_configured_ro (const char *sysroot)
{
Expand All @@ -103,7 +140,7 @@ sysroot_is_configured_ro (const char *sysroot)
return false;
}

return g_key_file_get_boolean (repo_config, "sysroot", "readonly", NULL);
return g_key_file_get_boolean (repo_config, SYSROOT_KEY, READONLY_KEY, NULL);
}

static inline char *
Expand Down Expand Up @@ -302,6 +339,15 @@ main (int argc, char *argv[])
err (EXIT_FAILURE, "usage: ostree-prepare-root SYSROOT");
root_arg = argv[1];

g_autoptr (GKeyFile) config = load_config (&error);
if (!config)
errx (EXIT_FAILURE, "Failed to parse config: %s", error->message);

gboolean sysroot_readonly = FALSE;
if (!ot_keyfile_get_boolean_with_default (config, SYSROOT_KEY, READONLY_KEY, FALSE,
&sysroot_readonly, &error))
errx (EXIT_FAILURE, "Failed to parse sysroot.readonly value: %s", error->message);

/* This is the final target where we should prepare the rootfs. The usual
* case with systemd in the initramfs is that root_mountpoint = "/sysroot".
* In the fastboot embedded case we're pid1 and will setup / ourself, and
Expand All @@ -317,10 +363,18 @@ main (int argc, char *argv[])
if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE_PRIVATE, 0) < 0)
err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE_PRIVATE);

/* Query the repository configuration - this is an operating system builder
* choice. More info: https://github.com/ostreedev/ostree/pull/1767
/* Fall back to querying the repository configuration in the target disk.
* This is an operating system builder choice. More info:
* https://github.com/ostreedev/ostree/pull/1767
*/
const bool sysroot_readonly = sysroot_is_configured_ro (root_arg);
if (!sysroot_readonly)
{
sysroot_readonly = sysroot_is_configured_ro (root_arg);
// Encourage porting to the new config file
if (sysroot_readonly)
g_print ("Found legacy sysroot.readonly flag, not configured in %s\n",
PREPARE_ROOT_CONFIG_PATH);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: The fedora readonly migration service will enable this and trigger this warning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we will need to have a long period of migrating things to the new API. It doesn't actually contain the string "warning".

}
const bool sysroot_currently_writable = !path_is_on_readonly_fs (root_arg);
g_print ("sysroot.readonly configuration value: %d (fs writable: %d)\n", (int)sysroot_readonly,
(int)sysroot_currently_writable);
Expand Down