mirror of
https://github.com/systemd/systemd
synced 2025-10-08 13:14:45 +02:00
Compare commits
2 Commits
162e5e4a77
...
04b3529cf1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
04b3529cf1 | ||
![]() |
aef605c631 |
@ -108,8 +108,9 @@
|
|||||||
follows the syntax and rules as described in the <ulink
|
follows the syntax and rules as described in the <ulink
|
||||||
url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> page. The purpose of this
|
url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> page. The purpose of this
|
||||||
file is to identify the extension and to allow the operating system to verify that the extension image
|
file is to identify the extension and to allow the operating system to verify that the extension image
|
||||||
matches the base OS. This is typically implemented by checking that the <varname>ID=</varname> options
|
matches the base OS. This is typically implemented by checking that the extension <varname>ID=</varname>
|
||||||
match, and either <varname>SYSEXT_LEVEL=</varname> exists and matches too, or if it is not present,
|
option either matches the host <varname>ID=</varname> option or is included the host <varname>ID_LIKE=</varname>
|
||||||
|
option, and either <varname>SYSEXT_LEVEL=</varname> exists and matches too, or if it is not present,
|
||||||
<varname>VERSION_ID=</varname> exists and matches. This ensures ABI/API compatibility between the
|
<varname>VERSION_ID=</varname> exists and matches. This ensures ABI/API compatibility between the
|
||||||
layers and prevents merging of an incompatible image in an overlay.</para>
|
layers and prevents merging of an incompatible image in an overlay.</para>
|
||||||
|
|
||||||
|
@ -1516,7 +1516,7 @@ static int mount_image(
|
|||||||
const char *root_directory,
|
const char *root_directory,
|
||||||
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_id_like = NULL, *host_os_release_version_id = NULL,
|
||||||
*host_os_release_sysext_level = NULL, *host_os_release_confext_level = NULL,
|
*host_os_release_sysext_level = NULL, *host_os_release_confext_level = NULL,
|
||||||
*extension_name = NULL;
|
*extension_name = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -1531,6 +1531,7 @@ static int mount_image(
|
|||||||
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,
|
||||||
|
"ID_LIKE", &host_os_release_id_like,
|
||||||
"VERSION_ID", &host_os_release_version_id,
|
"VERSION_ID", &host_os_release_version_id,
|
||||||
image_class_info[IMAGE_SYSEXT].level_env, &host_os_release_sysext_level,
|
image_class_info[IMAGE_SYSEXT].level_env, &host_os_release_sysext_level,
|
||||||
image_class_info[IMAGE_CONFEXT].level_env, &host_os_release_confext_level,
|
image_class_info[IMAGE_CONFEXT].level_env, &host_os_release_confext_level,
|
||||||
@ -1542,12 +1543,13 @@ static int mount_image(
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = verity_dissect_and_mount(
|
r = verity_dissect_and_mount(
|
||||||
/* src_fd= */ -1,
|
/* src_fd= */ -EBADF,
|
||||||
mount_entry_source(m),
|
mount_entry_source(m),
|
||||||
mount_entry_path(m),
|
mount_entry_path(m),
|
||||||
m->image_options_const,
|
m->image_options_const,
|
||||||
image_policy,
|
image_policy,
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
|
host_os_release_id_like,
|
||||||
host_os_release_version_id,
|
host_os_release_version_id,
|
||||||
host_os_release_sysext_level,
|
host_os_release_sysext_level,
|
||||||
host_os_release_confext_level,
|
host_os_release_confext_level,
|
||||||
@ -1558,9 +1560,10 @@ static int mount_image(
|
|||||||
return 0;
|
return 0;
|
||||||
if (r == -ESTALE && host_os_release_id)
|
if (r == -ESTALE && host_os_release_id)
|
||||||
return log_error_errno(r, // FIXME: this should not be logged ad LOG_ERR, as it will result in duplicate logging.
|
return log_error_errno(r, // FIXME: this should not be logged ad LOG_ERR, as it will result in duplicate logging.
|
||||||
"Failed to mount image %s, extension-release metadata does not match the lower layer's: ID=%s%s%s%s%s%s%s",
|
"Failed to mount image %s, extension-release metadata does not match the lower layer's: ID=%s ID_LIKE='%s'%s%s%s%s%s%s",
|
||||||
mount_entry_source(m),
|
mount_entry_source(m),
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
|
strempty(host_os_release_id_like),
|
||||||
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 ? image_class_info[IMAGE_SYSEXT].level_env_print : "",
|
host_os_release_sysext_level ? image_class_info[IMAGE_SYSEXT].level_env_print : "",
|
||||||
@ -1735,8 +1738,9 @@ static int apply_one_mount(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MOUNT_EXTENSION_DIRECTORY: {
|
case MOUNT_EXTENSION_DIRECTORY: {
|
||||||
_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_id_like = NULL,
|
||||||
*host_os_release_level = NULL, *extension_name = NULL;
|
*host_os_release_version_id = 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;
|
ImageClass class = IMAGE_SYSEXT;
|
||||||
|
|
||||||
@ -1768,6 +1772,7 @@ static int apply_one_mount(
|
|||||||
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,
|
||||||
|
"ID_LIKE", &host_os_release_id_like,
|
||||||
"VERSION_ID", &host_os_release_version_id,
|
"VERSION_ID", &host_os_release_version_id,
|
||||||
image_class_info[class].level_env, &host_os_release_level,
|
image_class_info[class].level_env, &host_os_release_level,
|
||||||
NULL);
|
NULL);
|
||||||
@ -1779,6 +1784,7 @@ static int apply_one_mount(
|
|||||||
r = extension_release_validate(
|
r = extension_release_validate(
|
||||||
extension_name,
|
extension_name,
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
|
host_os_release_id_like,
|
||||||
host_os_release_version_id,
|
host_os_release_version_id,
|
||||||
host_os_release_level,
|
host_os_release_level,
|
||||||
/* host_extension_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 */
|
||||||
|
@ -563,7 +563,7 @@ static int extract_image_and_extensions(
|
|||||||
char ***ret_valid_prefixes,
|
char ***ret_valid_prefixes,
|
||||||
sd_bus_error *error) {
|
sd_bus_error *error) {
|
||||||
|
|
||||||
_cleanup_free_ char *id = NULL, *version_id = NULL, *sysext_level = NULL, *confext_level = NULL;
|
_cleanup_free_ char *id = NULL, *id_like = NULL, *version_id = NULL, *sysext_level = NULL, *confext_level = NULL;
|
||||||
_cleanup_(portable_metadata_unrefp) PortableMetadata *os_release = NULL;
|
_cleanup_(portable_metadata_unrefp) PortableMetadata *os_release = NULL;
|
||||||
_cleanup_ordered_hashmap_free_ OrderedHashmap *extension_images = NULL, *extension_releases = NULL;
|
_cleanup_ordered_hashmap_free_ OrderedHashmap *extension_images = NULL, *extension_releases = NULL;
|
||||||
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
|
||||||
@ -664,6 +664,7 @@ static int extract_image_and_extensions(
|
|||||||
|
|
||||||
r = parse_env_file_fd(os_release->fd, os_release->name,
|
r = parse_env_file_fd(os_release->fd, os_release->name,
|
||||||
"ID", &id,
|
"ID", &id,
|
||||||
|
"ID_LIKE", &id_like,
|
||||||
"VERSION_ID", &version_id,
|
"VERSION_ID", &version_id,
|
||||||
"SYSEXT_LEVEL", &sysext_level,
|
"SYSEXT_LEVEL", &sysext_level,
|
||||||
"CONFEXT_LEVEL", &confext_level,
|
"CONFEXT_LEVEL", &confext_level,
|
||||||
@ -710,9 +711,9 @@ static int extract_image_and_extensions(
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (validate_extension) {
|
if (validate_extension) {
|
||||||
r = extension_release_validate(ext->path, id, version_id, sysext_level, "portable", extension_release, IMAGE_SYSEXT);
|
r = extension_release_validate(ext->path, id, id_like, version_id, sysext_level, "portable", extension_release, IMAGE_SYSEXT);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
r = extension_release_validate(ext->path, id, version_id, confext_level, "portable", extension_release, IMAGE_CONFEXT);
|
r = extension_release_validate(ext->path, id, id_like, version_id, confext_level, "portable", extension_release, IMAGE_CONFEXT);
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return sd_bus_error_set_errnof(error, ESTALE, "Image %s extension-release metadata does not match the root's", ext->path);
|
return sd_bus_error_set_errnof(error, ESTALE, "Image %s extension-release metadata does not match the root's", ext->path);
|
||||||
|
@ -4030,6 +4030,7 @@ int verity_dissect_and_mount(
|
|||||||
const MountOptions *options,
|
const MountOptions *options,
|
||||||
const ImagePolicy *image_policy,
|
const ImagePolicy *image_policy,
|
||||||
const char *required_host_os_release_id,
|
const char *required_host_os_release_id,
|
||||||
|
const char *required_host_os_release_id_like,
|
||||||
const char *required_host_os_release_version_id,
|
const char *required_host_os_release_version_id,
|
||||||
const char *required_host_os_release_sysext_level,
|
const char *required_host_os_release_sysext_level,
|
||||||
const char *required_host_os_release_confext_level,
|
const char *required_host_os_release_confext_level,
|
||||||
@ -4158,6 +4159,7 @@ int verity_dissect_and_mount(
|
|||||||
r = extension_release_validate(
|
r = extension_release_validate(
|
||||||
dissected_image->image_name,
|
dissected_image->image_name,
|
||||||
required_host_os_release_id,
|
required_host_os_release_id,
|
||||||
|
required_host_os_release_id_like,
|
||||||
required_host_os_release_version_id,
|
required_host_os_release_version_id,
|
||||||
class == IMAGE_SYSEXT ? required_host_os_release_sysext_level : required_host_os_release_confext_level,
|
class == IMAGE_SYSEXT ? required_host_os_release_sysext_level : required_host_os_release_confext_level,
|
||||||
required_sysext_scope,
|
required_sysext_scope,
|
||||||
|
@ -226,7 +226,7 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
|
|||||||
|
|
||||||
int mount_image_privately_interactively(const char *path, const ImagePolicy *image_policy, DissectImageFlags flags, char **ret_directory, int *ret_dir_fd, LoopDevice **ret_loop_device);
|
int mount_image_privately_interactively(const char *path, const ImagePolicy *image_policy, DissectImageFlags flags, char **ret_directory, int *ret_dir_fd, LoopDevice **ret_loop_device);
|
||||||
|
|
||||||
int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const ImagePolicy *image_policy, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_host_os_release_confext_level, const char *required_sysext_scope, VeritySettings *verity, DissectedImage **ret_image);
|
int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const ImagePolicy *image_policy, const char *required_host_os_release_id, const char *required_host_os_release_id_like, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_host_os_release_confext_level, const char *required_sysext_scope, VeritySettings *verity, DissectedImage **ret_image);
|
||||||
|
|
||||||
int dissect_fstype_ok(const char *fstype);
|
int dissect_fstype_ok(const char *fstype);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
int extension_release_validate(
|
int extension_release_validate(
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *host_os_release_id,
|
const char *host_os_release_id,
|
||||||
|
const char *host_os_release_id_like,
|
||||||
const char *host_os_release_version_id,
|
const char *host_os_release_version_id,
|
||||||
const char *host_os_extension_release_level,
|
const char *host_os_extension_release_level,
|
||||||
const char *host_extension_scope,
|
const char *host_extension_scope,
|
||||||
@ -21,6 +22,7 @@ int extension_release_validate(
|
|||||||
const char *extension_release_id = NULL, *extension_release_level = NULL, *extension_architecture = NULL;
|
const char *extension_release_id = NULL, *extension_release_level = NULL, *extension_architecture = NULL;
|
||||||
const char *extension_level = image_class == IMAGE_CONFEXT ? "CONFEXT_LEVEL" : "SYSEXT_LEVEL";
|
const char *extension_level = image_class == IMAGE_CONFEXT ? "CONFEXT_LEVEL" : "SYSEXT_LEVEL";
|
||||||
const char *extension_scope = image_class == IMAGE_CONFEXT ? "CONFEXT_SCOPE" : "SYSEXT_SCOPE";
|
const char *extension_scope = image_class == IMAGE_CONFEXT ? "CONFEXT_SCOPE" : "SYSEXT_SCOPE";
|
||||||
|
_cleanup_strv_free_ char **id_like_l = NULL;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(!isempty(host_os_release_id));
|
assert(!isempty(host_os_release_id));
|
||||||
@ -77,9 +79,19 @@ int extension_release_validate(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!streq(host_os_release_id, extension_release_id)) {
|
/* Match extension OS ID against host OS ID or ID_LIKE */
|
||||||
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
|
if (host_os_release_id_like) {
|
||||||
name, extension_release_id, host_os_release_id);
|
id_like_l = strv_split(host_os_release_id_like, WHITESPACE);
|
||||||
|
if (!id_like_l)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!streq(host_os_release_id, extension_release_id) && !strv_contains(id_like_l, extension_release_id)) {
|
||||||
|
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'%s%s%s.",
|
||||||
|
name, extension_release_id, host_os_release_id,
|
||||||
|
host_os_release_id_like ? " (like '" : "",
|
||||||
|
strempty(host_os_release_id_like),
|
||||||
|
host_os_release_id_like ? "')" : "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
int extension_release_validate(
|
int extension_release_validate(
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *host_os_release_id,
|
const char *host_os_release_id,
|
||||||
|
const char *host_os_release_id_like,
|
||||||
const char *host_os_release_version_id,
|
const char *host_os_release_version_id,
|
||||||
const char *host_os_extension_release_level,
|
const char *host_os_extension_release_level,
|
||||||
const char *host_extension_scope,
|
const char *host_extension_scope,
|
||||||
|
@ -929,6 +929,7 @@ static int mount_in_namespace_legacy(
|
|||||||
options,
|
options,
|
||||||
image_policy,
|
image_policy,
|
||||||
/* required_host_os_release_id= */ NULL,
|
/* required_host_os_release_id= */ NULL,
|
||||||
|
/* required_host_os_release_id_like= */ NULL,
|
||||||
/* required_host_os_release_version_id= */ NULL,
|
/* required_host_os_release_version_id= */ NULL,
|
||||||
/* required_host_os_release_sysext_level= */ NULL,
|
/* required_host_os_release_sysext_level= */ NULL,
|
||||||
/* required_host_os_release_confext_level= */ NULL,
|
/* required_host_os_release_confext_level= */ NULL,
|
||||||
@ -1140,6 +1141,7 @@ static int mount_in_namespace(
|
|||||||
options,
|
options,
|
||||||
image_policy,
|
image_policy,
|
||||||
/* required_host_os_release_id= */ NULL,
|
/* required_host_os_release_id= */ NULL,
|
||||||
|
/* required_host_os_release_id_like= */ NULL,
|
||||||
/* required_host_os_release_version_id= */ NULL,
|
/* required_host_os_release_version_id= */ NULL,
|
||||||
/* required_host_os_release_sysext_level= */ NULL,
|
/* required_host_os_release_sysext_level= */ NULL,
|
||||||
/* required_host_os_release_confext_level= */ NULL,
|
/* required_host_os_release_confext_level= */ NULL,
|
||||||
|
@ -1638,7 +1638,9 @@ static int merge_subprocess(
|
|||||||
Hashmap *images,
|
Hashmap *images,
|
||||||
const char *workspace) {
|
const char *workspace) {
|
||||||
|
|
||||||
_cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, *host_os_release_api_level = NULL, *buf = NULL, *filename = NULL;
|
_cleanup_free_ char *host_os_release_id = NULL, *host_os_release_id_like = NULL,
|
||||||
|
*host_os_release_version_id = NULL, *host_os_release_api_level = NULL,
|
||||||
|
*buf = NULL, *filename = NULL;
|
||||||
_cleanup_strv_free_ char **extensions = NULL, **extensions_v = NULL, **paths = NULL;
|
_cleanup_strv_free_ char **extensions = NULL, **extensions_v = NULL, **paths = NULL;
|
||||||
size_t n_extensions = 0;
|
size_t n_extensions = 0;
|
||||||
unsigned n_ignored = 0;
|
unsigned n_ignored = 0;
|
||||||
@ -1670,6 +1672,7 @@ static int merge_subprocess(
|
|||||||
r = parse_os_release(
|
r = parse_os_release(
|
||||||
arg_root,
|
arg_root,
|
||||||
"ID", &host_os_release_id,
|
"ID", &host_os_release_id,
|
||||||
|
"ID_LIKE", &host_os_release_id_like,
|
||||||
"VERSION_ID", &host_os_release_version_id,
|
"VERSION_ID", &host_os_release_version_id,
|
||||||
image_class_info[image_class].level_env, &host_os_release_api_level);
|
image_class_info[image_class].level_env, &host_os_release_api_level);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1804,6 +1807,7 @@ static int merge_subprocess(
|
|||||||
r = extension_release_validate(
|
r = extension_release_validate(
|
||||||
img->name,
|
img->name,
|
||||||
host_os_release_id,
|
host_os_release_id,
|
||||||
|
host_os_release_id_like,
|
||||||
host_os_release_version_id,
|
host_os_release_version_id,
|
||||||
host_os_release_api_level,
|
host_os_release_api_level,
|
||||||
in_initrd() ? "initrd" : "system",
|
in_initrd() ? "initrd" : "system",
|
||||||
|
@ -85,6 +85,7 @@ prepare_root() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
echo "ID=testtest"
|
echo "ID=testtest"
|
||||||
|
echo "ID_LIKE=\"foobar test_alike something-else\""
|
||||||
echo "VERSION=1.2.3"
|
echo "VERSION=1.2.3"
|
||||||
} >"$root/usr/lib/os-release"
|
} >"$root/usr/lib/os-release"
|
||||||
|
|
||||||
@ -120,6 +121,38 @@ prepare_extension_image() {
|
|||||||
prepend_trap "rm -rf ${ext_dir@Q}"
|
prepend_trap "rm -rf ${ext_dir@Q}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_extension_image_with_matching_id() {
|
||||||
|
local root=${1:-}
|
||||||
|
local hierarchy=${2:?}
|
||||||
|
local ext_dir ext_release name
|
||||||
|
|
||||||
|
name="test-extension-matching-id"
|
||||||
|
ext_dir="$root/var/lib/extensions/$name"
|
||||||
|
ext_release="$ext_dir/usr/lib/extension-release.d/extension-release.$name"
|
||||||
|
mkdir -p "${ext_release%/*}"
|
||||||
|
echo "ID=testtest" >"$ext_release"
|
||||||
|
mkdir -p "$ext_dir/$hierarchy"
|
||||||
|
touch "$ext_dir$hierarchy/preexisting-file-in-extension-image"
|
||||||
|
|
||||||
|
prepend_trap "rm -rf ${ext_dir@Q}"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_extension_image_with_matching_id_like() {
|
||||||
|
local root=${1:-}
|
||||||
|
local hierarchy=${2:?}
|
||||||
|
local ext_dir ext_release name
|
||||||
|
|
||||||
|
name="test-extension-matching-id-like"
|
||||||
|
ext_dir="$root/var/lib/extensions/$name"
|
||||||
|
ext_release="$ext_dir/usr/lib/extension-release.d/extension-release.$name"
|
||||||
|
mkdir -p "${ext_release%/*}"
|
||||||
|
echo "ID=test_alike" >"$ext_release"
|
||||||
|
mkdir -p "$ext_dir/$hierarchy"
|
||||||
|
touch "$ext_dir$hierarchy/preexisting-file-in-extension-image"
|
||||||
|
|
||||||
|
prepend_trap "rm -rf ${ext_dir@Q}"
|
||||||
|
}
|
||||||
|
|
||||||
prepare_extension_mutable_dir() {
|
prepare_extension_mutable_dir() {
|
||||||
local dir=${1:?}
|
local dir=${1:?}
|
||||||
|
|
||||||
@ -981,6 +1014,40 @@ for mutable_mode in no yes ephemeral; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
( init_trap
|
||||||
|
: "Check if merging an extension with matching ID succeeds"
|
||||||
|
fake_root=${roots_dir:+"$roots_dir/matching-id"}
|
||||||
|
hierarchy=/opt
|
||||||
|
|
||||||
|
prepare_root "$fake_root" "$hierarchy"
|
||||||
|
prepare_extension_image_with_matching_id "$fake_root" "$hierarchy"
|
||||||
|
prepare_read_only_hierarchy "$fake_root" "$hierarchy"
|
||||||
|
|
||||||
|
run_systemd_sysext "$fake_root" merge
|
||||||
|
extension_verify_after_merge "$fake_root" "$hierarchy" -e -h
|
||||||
|
|
||||||
|
run_systemd_sysext "$fake_root" unmerge
|
||||||
|
extension_verify_after_unmerge "$fake_root" "$hierarchy" -h
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
( init_trap
|
||||||
|
: "Check if merging an extension that matches host ID_LIKE succeeds"
|
||||||
|
fake_root=${roots_dir:+"$roots_dir/matching-id-like"}
|
||||||
|
hierarchy=/opt
|
||||||
|
|
||||||
|
prepare_root "$fake_root" "$hierarchy"
|
||||||
|
prepare_extension_image_with_matching_id_like "$fake_root" "$hierarchy"
|
||||||
|
prepare_read_only_hierarchy "$fake_root" "$hierarchy"
|
||||||
|
|
||||||
|
run_systemd_sysext "$fake_root" merge
|
||||||
|
extension_verify_after_merge "$fake_root" "$hierarchy" -e -h
|
||||||
|
|
||||||
|
run_systemd_sysext "$fake_root" unmerge
|
||||||
|
extension_verify_after_unmerge "$fake_root" "$hierarchy" -h
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
( init_trap
|
( init_trap
|
||||||
: "Check if merging fails in case of invalid mutable directory permissions"
|
: "Check if merging fails in case of invalid mutable directory permissions"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user