allow ExtensionImages= and ExtensionDirectories= settings to support confext images
This commit is contained in:
+53
-12
@@ -229,6 +229,21 @@ static const char * const mount_mode_table[_MOUNT_MODE_MAX] = {
|
|||||||
[MQUEUEFS] = "mqueuefs",
|
[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);
|
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(mount_mode, MountMode);
|
||||||
|
|
||||||
static const char *mount_entry_path(const MountEntry *p) {
|
static const char *mount_entry_path(const MountEntry *p) {
|
||||||
@@ -1231,17 +1246,32 @@ static int mount_image(
|
|||||||
const ImagePolicy *image_policy) {
|
const ImagePolicy *image_policy) {
|
||||||
|
|
||||||
_cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL,
|
_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;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
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) {
|
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(
|
r = parse_os_release(
|
||||||
empty_to_root(root_directory),
|
empty_to_root(root_directory),
|
||||||
"ID", &host_os_release_id,
|
"ID", &host_os_release_id,
|
||||||
"VERSION_ID", &host_os_release_version_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);
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(root_directory));
|
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,
|
image_policy,
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
host_os_release_version_id,
|
host_os_release_version_id,
|
||||||
host_os_release_sysext_level,
|
host_os_release_level,
|
||||||
NULL);
|
NULL);
|
||||||
if (r == -ENOENT && m->ignore)
|
if (r == -ENOENT && m->ignore)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1268,8 +1298,8 @@ static int mount_image(
|
|||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
host_os_release_version_id ? " VERSION_ID=" : "",
|
host_os_release_version_id ? " VERSION_ID=" : "",
|
||||||
strempty(host_os_release_version_id),
|
strempty(host_os_release_version_id),
|
||||||
host_os_release_sysext_level ? " SYSEXT_LEVEL=" : "",
|
host_os_release_level ? image_class_info[class].level_env_print : "",
|
||||||
strempty(host_os_release_sysext_level));
|
strempty(host_os_release_level));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to mount image %s on %s: %m", mount_entry_source(m), mount_entry_path(m));
|
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: {
|
case EXTENSION_DIRECTORIES: {
|
||||||
_cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL,
|
_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;
|
_cleanup_strv_free_ char **extension_release = NULL;
|
||||||
|
ImageClass class = IMAGE_SYSEXT;
|
||||||
|
|
||||||
r = path_extract_filename(mount_entry_source(m), &extension_name);
|
r = path_extract_filename(mount_entry_source(m), &extension_name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to extract extension name from %s: %m", mount_entry_source(m));
|
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(
|
r = parse_os_release(
|
||||||
empty_to_root(root_directory),
|
empty_to_root(root_directory),
|
||||||
"ID", &host_os_release_id,
|
"ID", &host_os_release_id,
|
||||||
"VERSION_ID", &host_os_release_version_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);
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(root_directory));
|
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))
|
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));
|
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)
|
if (r == -ENOENT && m->ignore)
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -1430,10 +1470,10 @@ static int apply_one_mount(
|
|||||||
extension_name,
|
extension_name,
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
host_os_release_version_id,
|
host_os_release_version_id,
|
||||||
host_os_release_sysext_level,
|
host_os_release_level,
|
||||||
/* host_sysext_scope */ NULL, /* Leave empty, we need to accept both system and portable */
|
/* host_extension_scope */ NULL, /* Leave empty, we need to accept both system and portable */
|
||||||
extension_release,
|
extension_release,
|
||||||
IMAGE_SYSEXT);
|
class);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Directory %s extension-release metadata does not match the root's", extension_name);
|
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Directory %s extension-release metadata does not match the root's", extension_name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -2091,7 +2131,8 @@ int setup_namespace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n_extension_images > 0 || !strv_isempty(extension_directories)) {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,9 @@ int parse_env_extension_hierarchies(char ***ret_hierarchies, const char *hierarc
|
|||||||
else if (streq(hierarchy_env, "SYSTEMD_SYSEXT_HIERARCHIES"))
|
else if (streq(hierarchy_env, "SYSTEMD_SYSEXT_HIERARCHIES"))
|
||||||
/* Default for sysext when unset */
|
/* Default for sysext when unset */
|
||||||
l = strv_new("/usr", "/opt");
|
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
|
else
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
} else if (r < 0)
|
} else if (r < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user