From 55ea4ef096543d2bceea9315868d5aca945d7a57 Mon Sep 17 00:00:00 2001 From: Maanya Goenka Date: Tue, 8 Aug 2023 21:57:53 +0000 Subject: [PATCH] allow ExtensionImages= and ExtensionDirectories= settings to support confext images --- src/core/namespace.c | 65 ++++++++++++++++++++++++++++++------- src/shared/extension-util.c | 3 ++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/core/namespace.c b/src/core/namespace.c index 5d353520bea..32f9c45deaa 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -229,6 +229,21 @@ static const char * const mount_mode_table[_MOUNT_MODE_MAX] = { [MQUEUEFS] = "mqueuefs", }; +/* Helper struct for naming simplicity and reusability */ +static const struct { + const char *level_env; + const char *level_env_print; +} image_class_info[_IMAGE_CLASS_MAX] = { + [IMAGE_SYSEXT] = { + .level_env = "SYSEXT_LEVEL", + .level_env_print = " SYSEXT_LEVEL=", + }, + [IMAGE_CONFEXT] = { + .level_env = "CONFEXT_LEVEL", + .level_env_print = " CONFEXT_LEVEL=", + } +}; + DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(mount_mode, MountMode); static const char *mount_entry_path(const MountEntry *p) { @@ -1231,17 +1246,32 @@ static int mount_image( const ImagePolicy *image_policy) { _cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, - *host_os_release_sysext_level = NULL; + *host_os_release_level = NULL, *extension_name = NULL; + _cleanup_strv_free_ char **extension_release = NULL; + ImageClass class = IMAGE_SYSEXT; int r; assert(m); + r = path_extract_filename(mount_entry_source(m), &extension_name); + if (r < 0) + return log_debug_errno(r, "Failed to extract extension name from %s: %m", mount_entry_source(m)); + if (m->mode == EXTENSION_IMAGES) { + r = load_extension_release_pairs(mount_entry_source(m), IMAGE_SYSEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release); + if (r == -ENOENT) { + r = load_extension_release_pairs(mount_entry_source(m), IMAGE_CONFEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release); + if (r >= 0) + class = IMAGE_CONFEXT; + } + if (r == -ENOENT) + return r; + r = parse_os_release( empty_to_root(root_directory), "ID", &host_os_release_id, "VERSION_ID", &host_os_release_version_id, - "SYSEXT_LEVEL", &host_os_release_sysext_level, + image_class_info[class].level_env, &host_os_release_level, NULL); if (r < 0) return log_debug_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(root_directory)); @@ -1257,7 +1287,7 @@ static int mount_image( image_policy, host_os_release_id, host_os_release_version_id, - host_os_release_sysext_level, + host_os_release_level, NULL); if (r == -ENOENT && m->ignore) return 0; @@ -1268,8 +1298,8 @@ static int mount_image( host_os_release_id, host_os_release_version_id ? " VERSION_ID=" : "", strempty(host_os_release_version_id), - host_os_release_sysext_level ? " SYSEXT_LEVEL=" : "", - strempty(host_os_release_sysext_level)); + host_os_release_level ? image_class_info[class].level_env_print : "", + strempty(host_os_release_level)); if (r < 0) return log_debug_errno(r, "Failed to mount image %s on %s: %m", mount_entry_source(m), mount_entry_path(m)); @@ -1402,25 +1432,35 @@ static int apply_one_mount( case EXTENSION_DIRECTORIES: { _cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, - *host_os_release_sysext_level = NULL, *extension_name = NULL; + *host_os_release_level = NULL, *extension_name = NULL; _cleanup_strv_free_ char **extension_release = NULL; + ImageClass class = IMAGE_SYSEXT; r = path_extract_filename(mount_entry_source(m), &extension_name); if (r < 0) return log_debug_errno(r, "Failed to extract extension name from %s: %m", mount_entry_source(m)); + r = load_extension_release_pairs(mount_entry_source(m), IMAGE_SYSEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release); + if (r == -ENOENT) { + r = load_extension_release_pairs(mount_entry_source(m), IMAGE_CONFEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release); + if (r >= 0) + class = IMAGE_CONFEXT; + } + if (r == -ENOENT) + return r; + r = parse_os_release( empty_to_root(root_directory), "ID", &host_os_release_id, "VERSION_ID", &host_os_release_version_id, - "SYSEXT_LEVEL", &host_os_release_sysext_level, + image_class_info[class].level_env, &host_os_release_level, NULL); if (r < 0) return log_debug_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(root_directory)); if (isempty(host_os_release_id)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "'ID' field not found or empty in 'os-release' data of OS tree '%s': %m", empty_to_root(root_directory)); - r = load_extension_release_pairs(mount_entry_source(m), IMAGE_SYSEXT, extension_name, /* relax_extension_release_check= */ false, &extension_release); + r = load_extension_release_pairs(mount_entry_source(m), class, extension_name, /* relax_extension_release_check= */ false, &extension_release); if (r == -ENOENT && m->ignore) return 0; if (r < 0) @@ -1430,10 +1470,10 @@ static int apply_one_mount( extension_name, host_os_release_id, host_os_release_version_id, - host_os_release_sysext_level, - /* host_sysext_scope */ NULL, /* Leave empty, we need to accept both system and portable */ + host_os_release_level, + /* host_extension_scope */ NULL, /* Leave empty, we need to accept both system and portable */ extension_release, - IMAGE_SYSEXT); + class); if (r == 0) return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Directory %s extension-release metadata does not match the root's", extension_name); if (r < 0) @@ -2091,7 +2131,8 @@ int setup_namespace( } if (n_extension_images > 0 || !strv_isempty(extension_directories)) { - r = parse_env_extension_hierarchies(&hierarchies, "SYSTEMD_SYSEXT_HIERARCHIES"); + /* Hierarchy population needs to be done for sysext and confext extension images */ + r = parse_env_extension_hierarchies(&hierarchies, "SYSTEMD_SYSEXT_AND_CONFEXT_HIERARCHIES"); if (r < 0) return r; } diff --git a/src/shared/extension-util.c b/src/shared/extension-util.c index 43a19bf2625..d8b16b94e16 100644 --- a/src/shared/extension-util.c +++ b/src/shared/extension-util.c @@ -136,6 +136,9 @@ int parse_env_extension_hierarchies(char ***ret_hierarchies, const char *hierarc else if (streq(hierarchy_env, "SYSTEMD_SYSEXT_HIERARCHIES")) /* Default for sysext when unset */ l = strv_new("/usr", "/opt"); + else if (streq(hierarchy_env, "SYSTEMD_SYSEXT_AND_CONFEXT_HIERARCHIES")) + /* Combined sysext and confext directories */ + l = strv_new("/usr", "/opt", "/etc"); else return -ENXIO; } else if (r < 0) -- 2.47.3