From: Colin Walters Date: Fri, 25 Aug 2023 19:54:20 +0000 (-0400) Subject: switchroot: Lower config parser to otcore, add unit tests X-Git-Tag: archive/raspbian/2023.7-3+rpi1^2~16^2^2~41^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d36bf35c10a91d75e829f255f75ba16127943bbd;p=ostree.git switchroot: Lower config parser to otcore, add unit tests Part of the continuation of unit testing coverage. --- diff --git a/Makefile-tests.am b/Makefile-tests.am index a8683808..e1cea7fe 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -366,7 +366,7 @@ tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS) tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD) tests_test_otcore_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libotcore -I$(srcdir)/libglnx -tests_test_otcore_LDADD = $(OT_INTERNAL_GIO_UNIX_LIBS) libotcore.la libglnx.la +tests_test_otcore_LDADD = $(OT_INTERNAL_GIO_UNIX_LIBS) libotcore.la libglnx.la libotutil.la tests_test_checksum_SOURCES = \ src/libostree/ostree-core.c \ diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c index f3b1a086..189c2a14 100644 --- a/src/libotcore/otcore-prepare-root.c +++ b/src/libotcore/otcore-prepare-root.c @@ -106,3 +106,34 @@ otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error *out_target = otcore_find_proc_cmdline_key (cmdline, "ostree"); return TRUE; } + +// Load a config file; if it doesn't exist, we return an empty configuration. +// NULL will be returned if we caught an error. +GKeyFile * +otcore_load_config (int rootfs_fd, const char *filename, GError **error) +{ + // The path to the config file for this binary + static const char *const config_roots[] = { "usr/lib", "etc" }; + 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], filename, NULL); + if (!ot_openat_ignore_enoent (rootfs_fd, 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); +} diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h index d41758e1..ba162b8d 100644 --- a/src/libotcore/otcore.h +++ b/src/libotcore/otcore.h @@ -46,6 +46,8 @@ gboolean otcore_validate_ed25519_signature (GBytes *data, GBytes *pubkey, GBytes char *otcore_find_proc_cmdline_key (const char *cmdline, const char *key); gboolean otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error); +GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error); + // Our directory with transient state (eventually /run/ostree-booted should be a link to // /run/ostree/booted) #define OTCORE_RUN_OSTREE "/run/ostree" diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 54a55c1d..05cef492 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -76,8 +76,6 @@ #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" // This key is used by default if present in the initramfs to verify @@ -106,35 +104,6 @@ const char *config_roots[] = { "/usr/lib", "/etc" }; #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) { @@ -350,7 +319,14 @@ main (int argc, char *argv[]) err (EXIT_FAILURE, "usage: ostree-prepare-root SYSROOT"); const char *root_arg = argv[1]; - g_autoptr (GKeyFile) config = load_config (&error); + // Since several APIs want to operate in terms of file descriptors, let's + // open the initramfs now. Currently this is just used for the config parser. + glnx_autofd int initramfs_rootfs_fd = -1; + if (!glnx_opendirat (AT_FDCWD, "/", FALSE, &initramfs_rootfs_fd, &error)) + errx (EXIT_FAILURE, "Failed to open /: %s", error->message); + + g_autoptr (GKeyFile) config + = otcore_load_config (initramfs_rootfs_fd, PREPARE_ROOT_CONFIG_PATH, &error); if (!config) errx (EXIT_FAILURE, "Failed to parse config: %s", error->message); diff --git a/tests/test-otcore.c b/tests/test-otcore.c index 03cfb6c8..4af575bf 100644 --- a/tests/test-otcore.c +++ b/tests/test-otcore.c @@ -81,6 +81,54 @@ test_prepare_root_cmdline (void) free (g_steal_pointer (&target)); } +static void +test_prepare_root_config (void) +{ + g_autoptr (GError) error = NULL; + g_auto (GLnxTmpDir) tmpdir = { + 0, + }; + g_assert (glnx_mkdtempat (AT_FDCWD, "/tmp/test-XXXXXX", 0777, &tmpdir, &error)); + g_assert_no_error (error); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys && *keys == NULL); + } + + g_assert (glnx_shutil_mkdir_p_at (tmpdir.fd, "usr/lib/ostree", 0755, NULL, NULL)); + g_assert (glnx_file_replace_contents_at (tmpdir.fd, "usr/lib/ostree/someconfig.conf", + (guint8 *)"[foo]\nbar=baz", -1, 0, NULL, NULL)); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys); + g_assert_cmpstr (*keys, ==, "foo"); + } + + g_assert (glnx_shutil_mkdir_p_at (tmpdir.fd, "etc/ostree", 0755, NULL, NULL)); + g_assert (glnx_file_replace_contents_at (tmpdir.fd, "usr/lib/ostree/someconfig.conf", + (guint8 *)"[test]\nbar=baz", -1, 0, NULL, NULL)); + + { + g_autoptr (GKeyFile) config = NULL; + g_auto (GStrv) keys = NULL; + config = otcore_load_config (tmpdir.fd, "ostree/someconfig.conf", &error); + g_assert (config); + keys = g_key_file_get_groups (config, NULL); + g_assert (keys); + g_assert_cmpstr (*keys, ==, "test"); + } +} + int main (int argc, char **argv) { @@ -88,5 +136,6 @@ main (int argc, char **argv) otcore_ed25519_init (); g_test_add_func ("/ed25519", test_ed25519); g_test_add_func ("/prepare-root-cmdline", test_prepare_root_cmdline); + g_test_add_func ("/prepare-root-config", test_prepare_root_config); return g_test_run (); }