summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2022-10-11 18:58:33 +0100
committerLuca Boccassi <bluca@debian.org>2022-10-12 09:57:24 +0100
commit06768b90a32ac0d36252ebc5f426ad471bf29fce (patch)
tree69c46b241bd6724e1bdddcd9c5176ffa45e1598a /src/portable
parentaad813bf170c7d901fcf1b664303e0204642ac61 (diff)
downloadsystemd-06768b90a32ac0d36252ebc5f426ad471bf29fce.tar.gz
portable: allow caller to override extension-release name check
When the --force flag is used, do not insist that the extension-release file has to match the extension image name
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/portable.c32
-rw-r--r--src/portable/portable.h11
-rw-r--r--src/portable/portablectl.c6
-rw-r--r--src/portable/portabled-image-bus.c3
4 files changed, 36 insertions, 16 deletions
diff --git a/src/portable/portable.c b/src/portable/portable.c
index 79bda5cf0b..be906f786c 100644
--- a/src/portable/portable.c
+++ b/src/portable/portable.c
@@ -171,6 +171,7 @@ static int extract_now(
char **matches,
const char *image_name,
bool path_is_extension,
+ bool relax_extension_release_check,
int socket_fd,
PortableMetadata **ret_os_release,
Hashmap **ret_unit_files) {
@@ -197,7 +198,7 @@ static int extract_now(
/* First, find os-release/extension-release and send it upstream (or just save it). */
if (path_is_extension) {
os_release_id = strjoina("/usr/lib/extension-release.d/extension-release.", image_name);
- r = open_extension_release(where, image_name, &os_release_path, &os_release_fd);
+ r = open_extension_release(where, image_name, relax_extension_release_check, &os_release_path, &os_release_fd);
} else {
os_release_id = "/etc/os-release";
r = open_os_release(where, &os_release_path, &os_release_fd);
@@ -321,6 +322,7 @@ static int extract_now(
static int portable_extract_by_path(
const char *path,
bool path_is_extension,
+ bool relax_extension_release_check,
char **matches,
PortableMetadata **ret_os_release,
Hashmap **ret_unit_files,
@@ -344,7 +346,7 @@ static int portable_extract_by_path(
if (r < 0)
return log_error_errno(r, "Failed to extract image name from path '%s': %m", path);
- r = extract_now(path, matches, image_name, path_is_extension, -1, &os_release, &unit_files);
+ r = extract_now(path, matches, image_name, path_is_extension, /* relax_extension_release_check= */ false, -1, &os_release, &unit_files);
if (r < 0)
return r;
@@ -400,7 +402,7 @@ static int portable_extract_by_path(
seq[0] = safe_close(seq[0]);
if (path_is_extension)
- flags |= DISSECT_IMAGE_VALIDATE_OS_EXT;
+ flags |= DISSECT_IMAGE_VALIDATE_OS_EXT | (relax_extension_release_check ? DISSECT_IMAGE_RELAX_SYSEXT_CHECK : 0);
else
flags |= DISSECT_IMAGE_VALIDATE_OS;
@@ -410,7 +412,7 @@ static int portable_extract_by_path(
goto child_finish;
}
- r = extract_now(tmpdir, matches, m->image_name, path_is_extension, seq[1], NULL, NULL);
+ r = extract_now(tmpdir, matches, m->image_name, path_is_extension, relax_extension_release_check, seq[1], NULL, NULL);
child_finish:
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
@@ -505,6 +507,7 @@ static int extract_image_and_extensions(
char **matches,
char **extension_image_paths,
bool validate_sysext,
+ bool relax_extension_release_check,
Image **ret_image,
OrderedHashmap **ret_extension_images,
OrderedHashmap **ret_extension_releases,
@@ -553,7 +556,7 @@ static int extract_image_and_extensions(
}
}
- r = portable_extract_by_path(image->path, /* path_is_extension= */ false, matches, &os_release, &unit_files, error);
+ r = portable_extract_by_path(image->path, /* path_is_extension= */ false, /* relax_extension_release_check= */ false, matches, &os_release, &unit_files, error);
if (r < 0)
return r;
@@ -593,7 +596,7 @@ static int extract_image_and_extensions(
_cleanup_fclose_ FILE *f = NULL;
const char *e;
- r = portable_extract_by_path(ext->path, /* path_is_extension= */ true, matches, &extension_release_meta, &extra_unit_files, error);
+ r = portable_extract_by_path(ext->path, /* path_is_extension= */ true, relax_extension_release_check, matches, &extension_release_meta, &extra_unit_files, error);
if (r < 0)
return r;
@@ -668,6 +671,7 @@ int portable_extract(
const char *name_or_path,
char **matches,
char **extension_image_paths,
+ PortableFlags flags,
PortableMetadata **ret_os_release,
OrderedHashmap **ret_extension_releases,
Hashmap **ret_unit_files,
@@ -688,6 +692,7 @@ int portable_extract(
matches,
extension_image_paths,
/* validate_sysext= */ false,
+ /* relax_extension_release_check= */ FLAGS_SET(flags, PORTABLE_FORCE_SYSEXT),
&image,
&extension_images,
&extension_releases,
@@ -955,6 +960,7 @@ static int install_chroot_dropin(
OrderedHashmap *extension_images,
const PortableMetadata *m,
const char *dropin_dir,
+ PortableFlags flags,
char **ret_dropin,
PortableChange **changes,
size_t *n_changes) {
@@ -1004,7 +1010,16 @@ static int install_chroot_dropin(
if (m->image_path && !path_equal(m->image_path, image_path))
ORDERED_HASHMAP_FOREACH(ext, extension_images)
- if (!strextend(&text, extension_setting_from_image(ext->type), ext->path, "\n"))
+ if (!strextend(&text,
+ extension_setting_from_image(ext->type),
+ ext->path,
+ /* With --force tell PID1 to avoid enforcing that the image <name> and
+ * extension-release.<name> have to match. */
+ !IN_SET(type, IMAGE_DIRECTORY, IMAGE_SUBVOLUME) &&
+ FLAGS_SET(flags, PORTABLE_FORCE_SYSEXT) ?
+ ":x-systemd.relax-extension-release-check" :
+ "",
+ "\n"))
return -ENOMEM;
}
@@ -1138,7 +1153,7 @@ static int attach_unit_file(
* is reloaded while we are creating things here: as long as only the drop-ins exist the unit doesn't exist at
* all for PID 1. */
- r = install_chroot_dropin(image_path, type, extension_images, m, dropin_dir, &chroot_dropin, changes, n_changes);
+ r = install_chroot_dropin(image_path, type, extension_images, m, dropin_dir, flags, &chroot_dropin, changes, n_changes);
if (r < 0)
return r;
@@ -1303,6 +1318,7 @@ int portable_attach(
matches,
extension_image_paths,
/* validate_sysext= */ true,
+ /* relax_extension_release_check= */ FLAGS_SET(flags, PORTABLE_FORCE_SYSEXT),
&image,
&extension_images,
/* extension_releases= */ NULL,
diff --git a/src/portable/portable.h b/src/portable/portable.h
index 30895b18f9..1a33f30944 100644
--- a/src/portable/portable.h
+++ b/src/portable/portable.h
@@ -23,10 +23,11 @@ typedef struct PortableMetadata {
typedef enum PortableFlags {
PORTABLE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */
PORTABLE_FORCE_ATTACH = 1 << 1, /* Public API via DBUS, do not change */
- PORTABLE_PREFER_COPY = 1 << 2,
- PORTABLE_PREFER_SYMLINK = 1 << 3,
- PORTABLE_REATTACH = 1 << 4,
- _PORTABLE_MASK_PUBLIC = PORTABLE_RUNTIME | PORTABLE_FORCE_ATTACH,
+ PORTABLE_FORCE_SYSEXT = 1 << 2, /* Public API via DBUS, do not change */
+ PORTABLE_PREFER_COPY = 1 << 3,
+ PORTABLE_PREFER_SYMLINK = 1 << 4,
+ PORTABLE_REATTACH = 1 << 5,
+ _PORTABLE_MASK_PUBLIC = PORTABLE_RUNTIME | PORTABLE_FORCE_ATTACH | PORTABLE_FORCE_SYSEXT,
_PORTABLE_TYPE_MAX,
_PORTABLE_TYPE_INVALID = -EINVAL,
} PortableFlags;
@@ -66,7 +67,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(PortableMetadata*, portable_metadata_unref);
int portable_metadata_hashmap_to_sorted_array(Hashmap *unit_files, PortableMetadata ***ret);
-int portable_extract(const char *image, char **matches, char **extension_image_paths, PortableMetadata **ret_os_release, OrderedHashmap **ret_extension_releases, Hashmap **ret_unit_files, char ***ret_valid_prefixes, sd_bus_error *error);
+int portable_extract(const char *image, char **matches, char **extension_image_paths, PortableFlags flags, PortableMetadata **ret_os_release, OrderedHashmap **ret_extension_releases, Hashmap **ret_unit_files, char ***ret_valid_prefixes, sd_bus_error *error);
int portable_attach(sd_bus *bus, const char *name_or_path, char **matches, const char *profile, char **extension_images, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error);
int portable_detach(sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableChange **changes, size_t *n_changes, sd_bus_error *error);
diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c
index 94a3970f87..6ee9ee8f43 100644
--- a/src/portable/portablectl.c
+++ b/src/portable/portablectl.c
@@ -260,7 +260,7 @@ static int maybe_reload(sd_bus **bus) {
static int get_image_metadata(sd_bus *bus, const char *image, char **matches, sd_bus_message **reply) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- uint64_t flags = 0;
+ uint64_t flags = arg_force ? PORTABLE_FORCE_SYSEXT : 0;
const char *method;
int r;
@@ -869,7 +869,7 @@ static int attach_reattach_image(int argc, char *argv[], const char *method) {
return bus_log_create_error(r);
if (STR_IN_SET(method, "AttachImageWithExtensions", "ReattachImageWithExtensions")) {
- uint64_t flags = (arg_runtime ? PORTABLE_RUNTIME : 0) | (arg_force ? PORTABLE_FORCE_ATTACH : 0);
+ uint64_t flags = (arg_runtime ? PORTABLE_RUNTIME : 0) | (arg_force ? PORTABLE_FORCE_ATTACH | PORTABLE_FORCE_SYSEXT : 0);
r = sd_bus_message_append(m, "st", arg_copy_mode, flags);
} else
@@ -941,7 +941,7 @@ static int detach_image(int argc, char *argv[], void *userdata) {
if (strv_isempty(arg_extension_images))
r = sd_bus_message_append(m, "b", arg_runtime);
else {
- uint64_t flags = (arg_runtime ? PORTABLE_RUNTIME : 0) | (arg_force ? PORTABLE_FORCE_ATTACH : 0);
+ uint64_t flags = (arg_runtime ? PORTABLE_RUNTIME : 0) | (arg_force ? PORTABLE_FORCE_ATTACH | PORTABLE_FORCE_SYSEXT : 0);
r = sd_bus_message_append(m, "t", flags);
}
diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c
index 7d393476a0..b108fd34af 100644
--- a/src/portable/portabled-image-bus.c
+++ b/src/portable/portabled-image-bus.c
@@ -108,6 +108,7 @@ int bus_image_common_get_metadata(
_cleanup_hashmap_free_ Hashmap *unit_files = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ PortableMetadata **sorted = NULL;
+ PortableFlags flags = 0;
int r;
assert(name_or_path || image);
@@ -142,6 +143,7 @@ int bus_image_common_get_metadata(
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
"Invalid 'flags' parameter '%" PRIu64 "'",
input_flags);
+ flags |= input_flags;
}
r = bus_image_acquire(m,
@@ -161,6 +163,7 @@ int bus_image_common_get_metadata(
image->path,
matches,
extension_images,
+ flags,
&os_release,
&extension_releases,
&unit_files,