diff --git a/.gitignore b/.gitignore index 28563be..21c270f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -libostree-2025.2.tar.xz +libostree-2025.6.tar.xz diff --git a/0001-Add-root-transient-ro.patch b/0001-Add-root-transient-ro.patch deleted file mode 100644 index 87985f0..0000000 --- a/0001-Add-root-transient-ro.patch +++ /dev/null @@ -1,712 +0,0 @@ -From 589e0ef3d72cb31d4e6905b464281c8a6139029e Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 16 Jul 2025 12:56:49 -0400 -Subject: [PATCH 1/5] prepare-root: Rename rootfs loading functions - -Prep for moving more functionality there, it's really about -the rootfs, not just composefs. ---- - src/libostree/ostree-sysroot-deploy.c | 4 ++-- - src/libotcore/otcore-prepare-root.c | 12 ++++++------ - src/libotcore/otcore.h | 8 ++++---- - src/switchroot/ostree-prepare-root.c | 4 ++-- - 4 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c -index 5d356d4d..fa2fd8cc 100644 ---- a/src/libostree/ostree-sysroot-deploy.c -+++ b/src/libostree/ostree-sysroot-deploy.c -@@ -653,8 +653,8 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy - // out if it's enabled, but not supported at compile time. - // However, we don't load the keys here, because they may not exist, such - // as in the initial deploy -- g_autoptr (ComposefsConfig) composefs_config -- = otcore_load_composefs_config ("", prepare_root_config, FALSE, error); -+ g_autoptr (RootConfig) composefs_config -+ = otcore_load_rootfs_config ("", prepare_root_config, FALSE, error); - if (!composefs_config) - return glnx_prefix_error (error, "Reading composefs config"); - -diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c -index 18bdf43e..b778ec8d 100644 ---- a/src/libotcore/otcore-prepare-root.c -+++ b/src/libotcore/otcore-prepare-root.c -@@ -154,24 +154,24 @@ otcore_load_config (int rootfs_fd, const char *filename, GError **error) - } - - void --otcore_free_composefs_config (ComposefsConfig *config) -+otcore_free_rootfs_config (RootConfig *config) - { - g_clear_pointer (&config->pubkeys, g_ptr_array_unref); - g_free (config->signature_pubkey); - g_free (config); - } - --// Parse the [composefs] section of the prepare-root.conf. --ComposefsConfig * --otcore_load_composefs_config (const char *cmdline, GKeyFile *config, gboolean load_keys, -+// Parse key bits of prepare-root.conf into a data structure. -+RootConfig * -+otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_keys, - GError **error) - { - g_assert (cmdline); - g_assert (config); - -- GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error); -+ GLNX_AUTO_PREFIX_ERROR ("Parsing rootfs config", error); - -- g_autoptr (ComposefsConfig) ret = g_new0 (ComposefsConfig, 1); -+ g_autoptr (RootConfig) ret = g_new0 (RootConfig, 1); - - g_autofree char *enabled = g_key_file_get_value (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, - OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL); -diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h -index ceeb1a92..3f1b5192 100644 ---- a/src/libotcore/otcore.h -+++ b/src/libotcore/otcore.h -@@ -69,11 +69,11 @@ typedef struct - gboolean is_signed; - char *signature_pubkey; - GPtrArray *pubkeys; --} ComposefsConfig; --void otcore_free_composefs_config (ComposefsConfig *config); --G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, otcore_free_composefs_config) -+} RootConfig; -+void otcore_free_rootfs_config (RootConfig *config); -+G_DEFINE_AUTOPTR_CLEANUP_FUNC (RootConfig, otcore_free_rootfs_config) - --ComposefsConfig *otcore_load_composefs_config (const char *cmdline, GKeyFile *config, -+RootConfig *otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, - gboolean load_keys, GError **error); - - // Our directory with transient state (eventually /run/ostree-booted should be a link to -diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c -index 4bf180c3..5d83a8ca 100644 ---- a/src/switchroot/ostree-prepare-root.c -+++ b/src/switchroot/ostree-prepare-root.c -@@ -289,8 +289,8 @@ main (int argc, char *argv[]) - - // We always parse the composefs config, because we want to detect and error - // out if it's enabled, but not supported at compile time. -- g_autoptr (ComposefsConfig) composefs_config -- = otcore_load_composefs_config (kernel_cmdline, config, TRUE, &error); -+ g_autoptr (RootConfig) composefs_config -+ = otcore_load_rootfs_config (kernel_cmdline, config, TRUE, &error); - if (!composefs_config) - errx (EXIT_FAILURE, "%s", error->message); - --- -2.50.1 - - -From 2e7bca26eb69b1376526ec707cd6a4aa177c5fa3 Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 16 Jul 2025 12:56:49 -0400 -Subject: [PATCH 2/5] prepare-root: Rename rootfs variables - -Prep for moving more functionality there, it's really about -the rootfs, not just composefs. - -Signed-off-by: Colin Walters ---- - src/libostree/ostree-sysroot-deploy.c | 10 +++++----- - src/switchroot/ostree-prepare-root.c | 28 +++++++++++++-------------- - 2 files changed, 19 insertions(+), 19 deletions(-) - -diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c -index fa2fd8cc..6a3f1712 100644 ---- a/src/libostree/ostree-sysroot-deploy.c -+++ b/src/libostree/ostree-sysroot-deploy.c -@@ -653,12 +653,12 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy - // out if it's enabled, but not supported at compile time. - // However, we don't load the keys here, because they may not exist, such - // as in the initial deploy -- g_autoptr (RootConfig) composefs_config -+ g_autoptr (RootConfig) rootfs_config - = otcore_load_rootfs_config ("", prepare_root_config, FALSE, error); -- if (!composefs_config) -- return glnx_prefix_error (error, "Reading composefs config"); -+ if (!rootfs_config) -+ return glnx_prefix_error (error, "Reading rootfs config"); - -- OtTristate composefs_enabled = composefs_config->enabled; -+ OtTristate composefs_enabled = rootfs_config->enabled; - g_debug ("composefs enabled by config: %d repo: %d", composefs_enabled, repo->composefs_wanted); - if (repo->composefs_wanted == OT_TRISTATE_YES) - composefs_enabled = repo->composefs_wanted; -@@ -677,7 +677,7 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy - g_auto (GVariantBuilder) cfs_checkout_opts_builder - = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); - guint32 composefs_requested = 1; -- if (composefs_config->require_verity) -+ if (rootfs_config->require_verity) - composefs_requested = 2; - g_variant_builder_add (&cfs_checkout_opts_builder, "{sv}", "verity", - g_variant_new_uint32 (composefs_requested)); -diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c -index 5d83a8ca..745bd902 100644 ---- a/src/switchroot/ostree-prepare-root.c -+++ b/src/switchroot/ostree-prepare-root.c -@@ -289,14 +289,14 @@ main (int argc, char *argv[]) - - // We always parse the composefs config, because we want to detect and error - // out if it's enabled, but not supported at compile time. -- g_autoptr (RootConfig) composefs_config -+ g_autoptr (RootConfig) rootfs_config - = otcore_load_rootfs_config (kernel_cmdline, config, TRUE, &error); -- if (!composefs_config) -+ if (!rootfs_config) - errx (EXIT_FAILURE, "%s", error->message); - - // If composefs is enabled, that also implies sysroot.readonly=true because it's - // the new default we want to use (not because it's actually required) -- const bool sysroot_readonly_default = composefs_config->enabled == OT_TRISTATE_YES; -+ const bool sysroot_readonly_default = rootfs_config->enabled == OT_TRISTATE_YES; - if (!ot_keyfile_get_boolean_with_default (config, SYSROOT_KEY, READONLY_KEY, - sysroot_readonly_default, &sysroot_readonly, &error)) - errx (EXIT_FAILURE, "Failed to parse sysroot.readonly value: %s", error->message); -@@ -328,7 +328,7 @@ main (int argc, char *argv[]) - * However, we only do this if composefs is not enabled, because we don't - * want to parse the target root filesystem before verifying its integrity. - */ -- if (!sysroot_readonly && composefs_config->enabled != OT_TRISTATE_YES) -+ if (!sysroot_readonly && rootfs_config->enabled != OT_TRISTATE_YES) - { - sysroot_readonly = sysroot_is_configured_ro (root_arg); - // Encourage porting to the new config file -@@ -373,7 +373,7 @@ main (int argc, char *argv[]) - #ifdef HAVE_COMPOSEFS - /* We construct the new sysroot in /sysroot.tmp, which is either the composefs - mount or a bind mount of the deploy-dir */ -- if (composefs_config->enabled != OT_TRISTATE_NO) -+ if (rootfs_config->enabled != OT_TRISTATE_NO) - { - const char *objdirs[] = { "/sysroot/ostree/repo/objects" }; - g_autofree char *cfs_digest = NULL; -@@ -415,9 +415,9 @@ main (int argc, char *argv[]) - cfs_options.flags = LCFS_MOUNT_FLAGS_READONLY; - } - -- if (composefs_config->is_signed) -+ if (rootfs_config->is_signed) - { -- const char *composefs_pubkey = composefs_config->signature_pubkey; -+ const char *composefs_pubkey = rootfs_config->signature_pubkey; - g_autoptr (GError) local_error = NULL; - g_autoptr (GVariant) commit = NULL; - g_autoptr (GVariant) commitmeta = NULL; -@@ -432,7 +432,7 @@ main (int argc, char *argv[]) - errx (EXIT_FAILURE, "Signature validation requested, but no signatures in commit"); - - g_autoptr (GBytes) commit_data = g_variant_get_data_as_bytes (commit); -- if (!validate_signature (commit_data, signatures, composefs_config->pubkeys)) -+ if (!validate_signature (commit_data, signatures, rootfs_config->pubkeys)) - errx (EXIT_FAILURE, "No valid signatures found for public key"); - - g_print ("composefs+ostree: Validated commit signature using '%s'\n", composefs_pubkey); -@@ -452,12 +452,12 @@ main (int argc, char *argv[]) - expected_digest = g_malloc (OSTREE_SHA256_STRING_LEN + 1); - ot_bin2hex (expected_digest, cfs_digest_buf, g_variant_get_size (cfs_digest_v)); - -- g_assert (composefs_config->require_verity); -+ g_assert (rootfs_config->require_verity); - cfs_options.flags |= LCFS_MOUNT_FLAGS_REQUIRE_VERITY; - g_print ("composefs: Verifying digest: %s\n", expected_digest); - cfs_options.expected_fsverity_digest = expected_digest; - } -- else if (composefs_config->require_verity) -+ else if (rootfs_config->require_verity) - { - cfs_options.flags |= LCFS_MOUNT_FLAGS_REQUIRE_VERITY; - } -@@ -476,8 +476,8 @@ main (int argc, char *argv[]) - else - { - int errsv = errno; -- g_assert (composefs_config->enabled != OT_TRISTATE_NO); -- if (composefs_config->enabled == OT_TRISTATE_MAYBE && errsv == ENOENT) -+ g_assert (rootfs_config->enabled != OT_TRISTATE_NO); -+ if (rootfs_config->enabled == OT_TRISTATE_MAYBE && errsv == ENOENT) - { - g_print ("composefs: No image present\n"); - } -@@ -490,7 +490,7 @@ main (int argc, char *argv[]) - } - #else - /* if composefs is configured as "maybe", we should continue */ -- if (composefs_config->enabled == OT_TRISTATE_YES) -+ if (rootfs_config->enabled == OT_TRISTATE_YES) - errx (EXIT_FAILURE, "composefs: enabled at runtime, but support is not compiled in"); - #endif - -@@ -590,7 +590,7 @@ main (int argc, char *argv[]) - * Also, hotfixes are incompatible with signed composefs use for security reasons. - */ - if (lstat (OTCORE_HOTFIX_USR_OVL_WORK, &stbuf) == 0 -- && !(using_composefs && composefs_config->is_signed)) -+ && !(using_composefs && rootfs_config->is_signed)) - { - /* Do we have a persistent overlayfs for /usr? If so, mount it now. */ - const char usr_ovl_options[] --- -2.50.1 - - -From b329c9ea48a6a5633d95309979b9dcae5561d963 Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 16 Jul 2025 12:56:49 -0400 -Subject: [PATCH 3/5] prepare-root: Rename `enabled` -> `composefs_enabled` - -Prep for moving more functionality there, it's really about -the rootfs, not just composefs. - -Signed-off-by: Colin Walters ---- - src/libostree/ostree-sysroot-deploy.c | 2 +- - src/libotcore/otcore-prepare-root.c | 10 +++++----- - src/libotcore/otcore.h | 2 +- - src/switchroot/ostree-prepare-root.c | 12 ++++++------ - 4 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c -index 6a3f1712..7ac25b4d 100644 ---- a/src/libostree/ostree-sysroot-deploy.c -+++ b/src/libostree/ostree-sysroot-deploy.c -@@ -658,7 +658,7 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy - if (!rootfs_config) - return glnx_prefix_error (error, "Reading rootfs config"); - -- OtTristate composefs_enabled = rootfs_config->enabled; -+ OtTristate composefs_enabled = rootfs_config->composefs_enabled; - g_debug ("composefs enabled by config: %d repo: %d", composefs_enabled, repo->composefs_wanted); - if (repo->composefs_wanted == OT_TRISTATE_YES) - composefs_enabled = repo->composefs_wanted; -diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c -index b778ec8d..4ffd63d2 100644 ---- a/src/libotcore/otcore-prepare-root.c -+++ b/src/libotcore/otcore-prepare-root.c -@@ -177,19 +177,19 @@ otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_ - OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL); - if (g_strcmp0 (enabled, "signed") == 0) - { -- ret->enabled = OT_TRISTATE_YES; -+ ret->composefs_enabled = OT_TRISTATE_YES; - ret->require_verity = true; - ret->is_signed = true; - } - else if (g_strcmp0 (enabled, "verity") == 0) - { -- ret->enabled = OT_TRISTATE_YES; -+ ret->composefs_enabled = OT_TRISTATE_YES; - ret->require_verity = true; - ret->is_signed = false; - } - else if (!ot_keyfile_get_tristate_with_default (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, - OTCORE_PREPARE_ROOT_ENABLED_KEY, OT_TRISTATE_NO, -- &ret->enabled, error)) -+ &ret->composefs_enabled, error)) - return NULL; - - // Look for a key - we default to the initramfs binding path. -@@ -232,7 +232,7 @@ otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_ - { - if (g_strcmp0 (ostree_composefs, "signed") == 0) - { -- ret->enabled = OT_TRISTATE_YES; -+ ret->composefs_enabled = OT_TRISTATE_YES; - ret->is_signed = true; - ret->require_verity = true; - } -@@ -240,7 +240,7 @@ otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_ - { - // The other states force off signatures - ret->is_signed = false; -- if (!_ostree_parse_tristate (ostree_composefs, &ret->enabled, error)) -+ if (!_ostree_parse_tristate (ostree_composefs, &ret->composefs_enabled, error)) - return glnx_prefix_error (error, "handling karg " CMDLINE_KEY_COMPOSEFS), NULL; - } - } -diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h -index 3f1b5192..ff4baa94 100644 ---- a/src/libotcore/otcore.h -+++ b/src/libotcore/otcore.h -@@ -64,7 +64,7 @@ GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); - - typedef struct - { -- OtTristate enabled; -+ OtTristate composefs_enabled; - gboolean require_verity; - gboolean is_signed; - char *signature_pubkey; -diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c -index 745bd902..d946bd8a 100644 ---- a/src/switchroot/ostree-prepare-root.c -+++ b/src/switchroot/ostree-prepare-root.c -@@ -296,7 +296,7 @@ main (int argc, char *argv[]) - - // If composefs is enabled, that also implies sysroot.readonly=true because it's - // the new default we want to use (not because it's actually required) -- const bool sysroot_readonly_default = rootfs_config->enabled == OT_TRISTATE_YES; -+ const bool sysroot_readonly_default = rootfs_config->composefs_enabled == OT_TRISTATE_YES; - if (!ot_keyfile_get_boolean_with_default (config, SYSROOT_KEY, READONLY_KEY, - sysroot_readonly_default, &sysroot_readonly, &error)) - errx (EXIT_FAILURE, "Failed to parse sysroot.readonly value: %s", error->message); -@@ -328,7 +328,7 @@ main (int argc, char *argv[]) - * However, we only do this if composefs is not enabled, because we don't - * want to parse the target root filesystem before verifying its integrity. - */ -- if (!sysroot_readonly && rootfs_config->enabled != OT_TRISTATE_YES) -+ if (!sysroot_readonly && rootfs_config->composefs_enabled != OT_TRISTATE_YES) - { - sysroot_readonly = sysroot_is_configured_ro (root_arg); - // Encourage porting to the new config file -@@ -373,7 +373,7 @@ main (int argc, char *argv[]) - #ifdef HAVE_COMPOSEFS - /* We construct the new sysroot in /sysroot.tmp, which is either the composefs - mount or a bind mount of the deploy-dir */ -- if (rootfs_config->enabled != OT_TRISTATE_NO) -+ if (rootfs_config->composefs_enabled != OT_TRISTATE_NO) - { - const char *objdirs[] = { "/sysroot/ostree/repo/objects" }; - g_autofree char *cfs_digest = NULL; -@@ -476,8 +476,8 @@ main (int argc, char *argv[]) - else - { - int errsv = errno; -- g_assert (rootfs_config->enabled != OT_TRISTATE_NO); -- if (rootfs_config->enabled == OT_TRISTATE_MAYBE && errsv == ENOENT) -+ g_assert (rootfs_config->composefs_enabled != OT_TRISTATE_NO); -+ if (rootfs_config->composefs_enabled == OT_TRISTATE_MAYBE && errsv == ENOENT) - { - g_print ("composefs: No image present\n"); - } -@@ -490,7 +490,7 @@ main (int argc, char *argv[]) - } - #else - /* if composefs is configured as "maybe", we should continue */ -- if (rootfs_config->enabled == OT_TRISTATE_YES) -+ if (rootfs_config->composefs_enabled == OT_TRISTATE_YES) - errx (EXIT_FAILURE, "composefs: enabled at runtime, but support is not compiled in"); - #endif - --- -2.50.1 - - -From 8e52cc3f67f62225055ab294adb87728063744df Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 16 Jul 2025 13:18:58 -0400 -Subject: [PATCH 4/5] prepare-root: Move root.transient parsing rootfs parsing - -This deduplicates more code between main boot and soft reboot, -and is prep for supporting `rootfs.transient-ro = true`. ---- - src/libotcore/otcore-prepare-root.c | 6 ++++++ - src/libotcore/otcore.h | 2 ++ - src/switchroot/ostree-prepare-root.c | 19 ++++++------------- - 3 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c -index 4ffd63d2..8a78ce28 100644 ---- a/src/libotcore/otcore-prepare-root.c -+++ b/src/libotcore/otcore-prepare-root.c -@@ -26,6 +26,8 @@ - #define BINDING_KEYPATH "/etc/ostree/initramfs-root-binding.key" - // The kernel argument to configure composefs - #define CMDLINE_KEY_COMPOSEFS "ostree.prepare-root.composefs" -+/* This key configures the / mount in the deployment root */ -+#define ROOT_KEY "root" - - static bool - proc_cmdline_has_key_starting_with (const char *cmdline, const char *key) -@@ -173,6 +175,10 @@ otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_ - - g_autoptr (RootConfig) ret = g_new0 (RootConfig, 1); - -+ if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, OTCORE_PREPARE_ROOT_TRANSIENT_KEY, -+ FALSE, &ret->root_transient, error)) -+ return NULL; -+ - g_autofree char *enabled = g_key_file_get_value (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, - OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL); - if (g_strcmp0 (enabled, "signed") == 0) -diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h -index ff4baa94..e59651b0 100644 ---- a/src/libotcore/otcore.h -+++ b/src/libotcore/otcore.h -@@ -65,6 +65,7 @@ GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); - typedef struct - { - OtTristate composefs_enabled; -+ gboolean root_transient; - gboolean require_verity; - gboolean is_signed; - char *signature_pubkey; -@@ -103,6 +104,7 @@ RootConfig *otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, - #define OTCORE_PREPARE_ROOT_COMPOSEFS_KEY "composefs" - #define OTCORE_PREPARE_ROOT_ENABLED_KEY "enabled" - #define OTCORE_PREPARE_ROOT_KEYPATH_KEY "keypath" -+#define OTCORE_PREPARE_ROOT_TRANSIENT_KEY "transient" - - // The file written in the initramfs which contains an a{sv} of metadata - // from ostree-prepare-root. -diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c -index d946bd8a..c6cf33c4 100644 ---- a/src/switchroot/ostree-prepare-root.c -+++ b/src/switchroot/ostree-prepare-root.c -@@ -79,8 +79,6 @@ - #define SYSROOT_KEY "sysroot" - #define READONLY_KEY "readonly" - --/* This key configures the / mount in the deployment root */ --#define ROOT_KEY "root" - #define ETC_KEY "etc" - #define TRANSIENT_KEY "transient" - -@@ -281,11 +279,6 @@ main (int argc, char *argv[]) - errx (EXIT_FAILURE, "Failed to parse config: %s", error->message); - - gboolean sysroot_readonly = FALSE; -- gboolean root_transient = FALSE; -- -- if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, TRANSIENT_KEY, FALSE, &root_transient, -- &error)) -- return FALSE; - - // We always parse the composefs config, because we want to detect and error - // out if it's enabled, but not supported at compile time. -@@ -394,13 +387,13 @@ main (int argc, char *argv[]) - // https://github.com/systemd/systemd/blob/604b2001081adcbd64ee1fbe7de7a6d77c5209fe/src/basic/mountpoint-util.h#L36 - // which bumps up these defaults for the rootfs a bit. - g_autofree char *root_upperdir -- = root_transient ? g_build_filename (OTCORE_RUN_OSTREE_PRIVATE, "root/upper", NULL) -+ = rootfs_config->root_transient ? g_build_filename (OTCORE_RUN_OSTREE_PRIVATE, "root/upper", NULL) - : NULL; - g_autofree char *root_workdir -- = root_transient ? g_build_filename (OTCORE_RUN_OSTREE_PRIVATE, "root/work", NULL) : NULL; -+ = rootfs_config->root_transient ? g_build_filename (OTCORE_RUN_OSTREE_PRIVATE, "root/work", NULL) : NULL; - - // Propagate these options for transient root, if provided -- if (root_transient) -+ if (rootfs_config->root_transient) - { - if (!glnx_shutil_mkdir_p_at (AT_FDCWD, root_upperdir, 0755, NULL, &error)) - errx (EXIT_FAILURE, "Failed to create %s: %s", root_upperdir, error->message); -@@ -496,7 +489,7 @@ main (int argc, char *argv[]) - - if (!using_composefs) - { -- if (root_transient) -+ if (rootfs_config->root_transient) - { - errx (EXIT_FAILURE, "Must enable composefs with root.transient"); - } -@@ -508,7 +501,7 @@ main (int argc, char *argv[]) - - /* Pass on the state */ - g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT, -- g_variant_new_boolean (root_transient)); -+ g_variant_new_boolean (rootfs_config->root_transient)); - - /* Pass on the state for use by ostree-prepare-root */ - g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_SYSROOT_RO, -@@ -533,7 +526,7 @@ main (int argc, char *argv[]) - /* Prepare /etc. - * No action required if sysroot is writable. Otherwise, a bind-mount for - * the deployment needs to be created and remounted as read/write. */ -- if (sysroot_readonly || using_composefs || root_transient) -+ if (sysroot_readonly || using_composefs || rootfs_config->root_transient) - { - gboolean etc_transient = FALSE; - if (!ot_keyfile_get_boolean_with_default (config, ETC_KEY, TRANSIENT_KEY, FALSE, --- -2.50.1 - - -From c6d138cdf2756753566a26907bffbdb07ce8319b Mon Sep 17 00:00:00 2001 -From: Colin Walters -Date: Wed, 16 Jul 2025 11:08:00 -0400 -Subject: [PATCH 5/5] Add root.transient-ro - -An example use case for this is having privileged code -add dynamic new toplevel mountpoints (that don't persist across -reboots/upgrades), while still keeping the rootfs readonly -for processes by default. - -Closes: https://github.com/ostreedev/ostree/issues/3471 - -Signed-off-by: Colin Walters ---- - man/ostree-prepare-root.xml | 9 ++++ - src/libotcore/otcore-prepare-root.c | 14 ++++++ - src/libotcore/otcore.h | 4 ++ - src/switchroot/ostree-prepare-root.c | 10 +++++ - .../kolainst/destructive/root-transient-ro.sh | 44 +++++++++++++++++++ - 5 files changed, 81 insertions(+) - create mode 100755 tests/kolainst/destructive/root-transient-ro.sh - -diff --git a/man/ostree-prepare-root.xml b/man/ostree-prepare-root.xml -index c1f39a8a..fd46a357 100644 ---- a/man/ostree-prepare-root.xml -+++ b/man/ostree-prepare-root.xml -@@ -140,6 +140,15 @@ License along with this library. If not, see . - - - -+ -+ root.transient-ro -+ A boolean value; the default is false. -+ This is like root.transient, but the overlayfs upper will be mounted -+ read-only by default. Use this when you want specific privileged components to be able to -+ write to the upper by temporarily mounting it writable in a new mount namespace. -+ -+ -+ - - composefs.enabled - This can be yes, no, maybe, -diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c -index 8a78ce28..42611105 100644 ---- a/src/libotcore/otcore-prepare-root.c -+++ b/src/libotcore/otcore-prepare-root.c -@@ -179,6 +179,20 @@ otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gboolean load_ - FALSE, &ret->root_transient, error)) - return NULL; - -+ -+ if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, OTCORE_PREPARE_ROOT_TRANSIENT_RO_KEY, -+ FALSE, &ret->root_transient_ro, error)) -+ return NULL; -+ if (ret->root_transient && ret->root_transient_ro) -+ { -+ return glnx_null_throw (error, "Cannot set both root.transient and root.transient-ro"); -+ } -+ // This way callers can test for just root_transient -+ else if (ret->root_transient_ro) -+ { -+ ret->root_transient = TRUE; -+ } -+ - g_autofree char *enabled = g_key_file_get_value (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, - OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL); - if (g_strcmp0 (enabled, "signed") == 0) -diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h -index e59651b0..33ccd7bb 100644 ---- a/src/libotcore/otcore.h -+++ b/src/libotcore/otcore.h -@@ -66,6 +66,7 @@ typedef struct - { - OtTristate composefs_enabled; - gboolean root_transient; -+ gboolean root_transient_ro; - gboolean require_verity; - gboolean is_signed; - char *signature_pubkey; -@@ -105,6 +106,7 @@ RootConfig *otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, - #define OTCORE_PREPARE_ROOT_ENABLED_KEY "enabled" - #define OTCORE_PREPARE_ROOT_KEYPATH_KEY "keypath" - #define OTCORE_PREPARE_ROOT_TRANSIENT_KEY "transient" -+#define OTCORE_PREPARE_ROOT_TRANSIENT_RO_KEY "transient-ro" - - // The file written in the initramfs which contains an a{sv} of metadata - // from ostree-prepare-root. -@@ -118,6 +120,8 @@ RootConfig *otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, - #define OTCORE_RUN_BOOTED_KEY_COMPOSEFS_SIGNATURE "composefs.signed" - // This key will be present if the root is transient - #define OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT "root.transient" -+// This key will be present if the root is transient readonly -+#define OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT_RO "root.transient-ro" - // This key will be present if the sysroot-ro flag was found - #define OTCORE_RUN_BOOTED_KEY_SYSROOT_RO "sysroot-ro" - // Always holds the (device, inode) pair of the booted deployment -diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c -index c6cf33c4..84c14703 100644 ---- a/src/switchroot/ostree-prepare-root.c -+++ b/src/switchroot/ostree-prepare-root.c -@@ -332,6 +332,11 @@ main (int argc, char *argv[]) - 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); -+ if (rootfs_config->root_transient) -+ { -+ g_print ("root.transient: %d (ro: %d)\n", (int)rootfs_config->root_transient, -+ (int)rootfs_config->root_transient_ro); -+ } - - /* Remount root MS_PRIVATE here to avoid errors due to the kernel-enforced - * constraint that disallows MS_SHARED mounts to be moved. -@@ -402,6 +407,8 @@ main (int argc, char *argv[]) - - cfs_options.workdir = root_workdir; - cfs_options.upperdir = root_upperdir; -+ if (rootfs_config->root_transient_ro) -+ cfs_options.flags = LCFS_MOUNT_FLAGS_READONLY; - } - else - { -@@ -503,6 +510,9 @@ main (int argc, char *argv[]) - g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT, - g_variant_new_boolean (rootfs_config->root_transient)); - -+ g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT_RO, -+ g_variant_new_boolean (rootfs_config->root_transient_ro)); -+ - /* Pass on the state for use by ostree-prepare-root */ - g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_SYSROOT_RO, - g_variant_new_boolean (sysroot_readonly)); -diff --git a/tests/kolainst/destructive/root-transient-ro.sh b/tests/kolainst/destructive/root-transient-ro.sh -new file mode 100755 -index 00000000..7a8ab54a ---- /dev/null -+++ b/tests/kolainst/destructive/root-transient-ro.sh -@@ -0,0 +1,44 @@ -+#!/bin/bash -+set -xeuo pipefail -+ -+. ${KOLA_EXT_DATA}/libinsttest.sh -+ -+prepare_tmpdir -+ -+echo "testing boot=${AUTOPKGTEST_REBOOT_MARK:-}" -+ -+# Print this by default on each boot -+ostree admin status -+ -+case "${AUTOPKGTEST_REBOOT_MARK:-}" in -+ "") -+ # xref https://github.com/coreos/coreos-assembler/pull/2814 -+ systemctl mask --now zincati -+ -+ test '!' -w / -+ -+ cp /usr/lib/ostree/prepare-root.conf /etc/ostree/ -+ cat >> /etc/ostree/prepare-root.conf <<'EOF' -+[root] -+transient-ro = true -+EOF -+ -+ rpm-ostree initramfs-etc --track /etc/ostree/prepare-root.conf -+ -+ /tmp/autopkgtest-reboot "2" -+ ;; -+ "2") -+ -+ test '!' -w '/' -+ -+ unshare -m /bin/sh -c 'env LIBMOUNT_FORCE_MOUNT2=always mount -o remount,rw / && mkdir /new-dir-in-root' -+ test -d /new-dir-in-root -+ -+ test '!' -w '/' -+ -+ echo "ok root transient-ro" -+ ;; -+ *) -+ fatal "Unexpected AUTOPKGTEST_REBOOT_MARK=${AUTOPKGTEST_REBOOT_MARK}" -+ ;; -+esac --- -2.50.1 - diff --git a/ostree.spec b/ostree.spec index 798bb43..64112bb 100644 --- a/ostree.spec +++ b/ostree.spec @@ -17,14 +17,12 @@ Summary: Tool for managing bootable, immutable filesystem trees Name: ostree -Version: 2025.2 +Version: 2025.6 Release: %autorelease Source0: https://github.com/ostreedev/%{name}/releases/download/v%{version}/libostree-%{version}.tar.xz License: LGPL-2.0-or-later URL: https://ostree.readthedocs.io/en/latest/ -Patch0: 0001-Add-root-transient-ro.patch - # Conditional to ELN right now to reduce blast radius; xref # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?rhel} >= 10 @@ -155,9 +153,9 @@ find %{buildroot} -name '*.la' -delete %{_bindir}/rofiles-fuse %{_datadir}/ostree %{_datadir}/bash-completion/completions/* -%dir %{_prefix}/lib/dracut/modules.d/98ostree +%dir %{_prefix}/lib/dracut/modules.d/50ostree %{_prefix}/lib/systemd/system/ostree*.* -%{_prefix}/lib/dracut/modules.d/98ostree/* +%{_prefix}/lib/dracut/modules.d/50ostree/* %{_mandir}/man*/*.gz %{_prefix}/lib/systemd/system-generators/ostree-system-generator %exclude %{_sysconfdir}/grub.d/*ostree @@ -195,10 +193,26 @@ find %{buildroot} -name '*.la' -delete %changelog ## START: Generated by rpmautospec -* Thu Aug 14 2025 Joseph Marrero Corchado - 2025.2-1 -- Rebase to ostree 2025.2 Backport - https://github.com/ostreedev/ostree/pull/3473 Backport - https://github.com/ostreedev/ostree/pull/3472 +* Thu Sep 11 2025 Joseph Marrero Corchado - 2025.6-1 +- Rebase to 2025.6 + +* Mon Aug 25 2025 Colin Walters - 2025.5-1 +- Release v2025.5 + +* Wed Aug 06 2025 Joseph Marrero Corchado - 2025.4-3 +- Backport https://github.com/ostreedev/ostree/pull/3493 + +* Wed Jul 30 2025 Joseph Marrero Corchado - 2025.4-2 +- Backport https://github.com/ostreedev/ostree/pull/3487 + +* Tue Jul 22 2025 Joseph Marrero Corchado - 2025.4-1 +- Release 2025.4 + +* Fri Jul 11 2025 Joseph Marrero Corchado - 2025.3-1 +- Release 2025.3 + +* Mon Mar 24 2025 Joseph Marrero Corchado - 2025.2-1 +- Release 2025.2 * Wed Mar 12 2025 Michael Nguyen - 2025.1-2 - Add tmt smoke test diff --git a/sources b/sources index c051f53..9ebab4c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libostree-2025.2.tar.xz) = 5e732a22da238b378e779c3886445977da49e2f810d18cb3580b030175e5e9db53408bcba245e840cdaea7e193907d284a369c42b3b7104c270e58a8c38f4f6a +SHA512 (libostree-2025.6.tar.xz) = ca321175a9272cc7f6c3d7a3989d90d2cbb53def41ac2984ce6a60a05007b5760960a1bf4e9a5f13adc246c7061214424f21a5a284c201d8c4a4f5c619c6e02d