]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
allow ExtensionImages= and ExtensionDirectories= settings to support confext images
authorMaanya Goenka <maanyagoenka@microsoft.com>
Tue, 8 Aug 2023 21:57:53 +0000 (21:57 +0000)
committerMaanya Goenka <maanyagoenka@microsoft.com>
Tue, 15 Aug 2023 18:34:46 +0000 (18:34 +0000)
src/core/namespace.c
src/shared/extension-util.c

index 5d353520bea82603984b3f93ba03c11335b48fe2..32f9c45deaa8d66e604f759b0594bc717e3a5d24 100644 (file)
@@ -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;
         }
index 43a19bf2625d21d6eeb327a6afb4adef61c4a8a1..d8b16b94e168f0276a800c9d0a0abc320ea923e4 100644 (file)
@@ -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)