deploy: Honor prepare-root.conf at deploy time
authorColin Walters <walters@verbum.org>
Fri, 9 Feb 2024 00:35:37 +0000 (19:35 -0500)
committerColin Walters <walters@verbum.org>
Fri, 9 Feb 2024 00:53:23 +0000 (19:53 -0500)
I want to try to get away from the "repository global" configuration
in the repo config.

A major problem is that there's not an obvious way to configure
it as part of an ostree commit/container build - it needs
to be managed "out of band".

With this change, we parse the `usr/lib/ostree/prepare-root.conf`
in the deployment root, and if composefs is enabled there,
then we honor it.

We do still honor `ex-integrity.composefs` but that I think
we can schedule to remove.

Makefile-tests.am
src/libostree/ostree-sysroot-deploy.c
tests/admin-test.sh
tests/test-admin-deploy-composefs.sh [new file with mode: 0755]

index e1cea7fe08fd892fcfc9a64c02cb06c98457d202..eae9f3182c2c36f89c85211c54e93e1ae88aacc2 100644 (file)
@@ -104,6 +104,7 @@ _installed_or_uninstalled_test_scripts = \
        tests/test-admin-upgrade-systemd-update.sh \
        tests/test-admin-deploy-syslinux.sh \
        tests/test-admin-deploy-bootprefix.sh \
+       tests/test-admin-deploy-composefs.sh \
        tests/test-admin-deploy-2.sh \
        tests/test-admin-deploy-karg.sh \
        tests/test-admin-deploy-switch.sh \
index 3a537fcb584271b6d41df4e003bb51d68ea5d51f..49c3a6abbd5058c3495e877fa61b43759b8e13a8 100644 (file)
@@ -661,8 +661,34 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy
                                 cancellable, error))
     return FALSE;
 
+  glnx_autofd int ret_deployment_dfd = -1;
+  if (!glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, &ret_deployment_dfd, error))
+    return FALSE;
+
 #ifdef HAVE_COMPOSEFS
-  if (repo->composefs_wanted != OT_TRISTATE_NO)
+  /* TODO: Consider changing things in the future to parse the deployment config from memory, and
+   * if composefs is enabled, then we can check out in "user mode" (i.e. only have suid binaries
+   * enabled in composefs, etc.)
+   *
+   * However in practice we should get this for free by going to composefs-native backing
+   * storage.
+   */
+  g_autoptr (GKeyFile) prepare_root_config
+      = otcore_load_config (ret_deployment_dfd, PREPARE_ROOT_CONFIG_PATH, error);
+  if (!prepare_root_config)
+    return glnx_prefix_error (error, "Parsing prepare-root config");
+  // 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 (prepare_root_config, error);
+  if (!composefs_config)
+    return glnx_prefix_error (error, "Reading composefs config");
+
+  OtTristate composefs_enabled = composefs_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;
+  if (composefs_enabled == OT_TRISTATE_YES)
     {
       g_autofree guchar *fsverity_digest = NULL;
       g_auto (GLnxTmpfile) tmpf = {
@@ -691,6 +717,8 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy
       g_autofree char *composefs_cfs_path
           = g_strdup_printf ("%s/" OSTREE_COMPOSEFS_NAME, checkout_target_name);
 
+      g_debug ("writing %s", composefs_cfs_path);
+
       if (!glnx_open_tmpfile_linkable_at (osdeploy_dfd, checkout_target_name, O_WRONLY | O_CLOEXEC,
                                           &tmpf, error))
         return FALSE;
@@ -712,9 +740,13 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy
                                  error))
         return FALSE;
     }
+  else
+    g_debug ("not using composefs");
 #endif
 
-  return glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, out_deployment_dfd, error);
+  if (out_deployment_dfd)
+    *out_deployment_dfd = glnx_steal_fd (&ret_deployment_dfd);
+  return TRUE;
 }
 
 static char *
index 17dbc6111c2cfedfb5ced4fac7b2a483cabb2f61..01790675933e9d7924b87109f1661a9e3656df02 100644 (file)
@@ -63,6 +63,11 @@ assert_not_file_has_content status.txt "pending"
 assert_not_file_has_content status.txt "rollback"
 validate_bootloader
 
+# Someday probably soon we'll turn this on by default, but for now
+if test -f sysroot/ostree/deploy/testos/deploy/*.0/.ostree.cfs; then
+    fatal "found composefs unexpectedly"
+fi
+
 # Test the bootable and linux keys
 ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo --print-metadata-key=ostree.linux show testos:testos/buildmain/x86_64-runtime >out.txt
 assert_file_has_content_literal out.txt 3.6.0
diff --git a/tests/test-admin-deploy-composefs.sh b/tests/test-admin-deploy-composefs.sh
new file mode 100755 (executable)
index 0000000..a4565a7
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Copyright (C) 2024 Red Hat, Inc.
+#
+# 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, see <https://www.gnu.org/licenses/>.
+
+set -euox pipefail
+
+. $(dirname $0)/libtest.sh
+
+# Exports OSTREE_SYSROOT so --sysroot not needed.
+setup_os_repository "archive" "syslinux"
+
+cd osdata
+mkdir -p usr/lib/ostree
+cat > usr/lib/ostree/prepare-root.conf << 'EOF'
+[composefs]
+enabled=true
+EOF
+${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.composefs -b testos/buildmain/x86_64-runtime
+cd -
+${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime
+
+${CMD_PREFIX} ostree admin deploy --os=testos --karg=root=LABEL=foo --karg=testkarg=1 testos:testos/buildmain/x86_64-runtime
+ls sysroot/ostree/deploy/testos/deploy/*.0/.ostree.cfs
+
+tap_ok composefs
+
+tap_end