Part of the continuation of unit testing coverage.
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 \
*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);
+}
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"
#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
#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)
{
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);
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)
{
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 ();
}