summaryrefslogtreecommitdiff
path: root/src/portable/portabled-image-bus.c
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2020-06-23 13:09:42 +0100
committerLuca Boccassi <luca.boccassi@gmail.com>2021-03-31 09:56:44 +0100
commit907952bbc92dd6656807d9b2eb0d0c94a4c9e865 (patch)
treeb5a1f594b1191699443798922b2c94e6d7fb0c76 /src/portable/portabled-image-bus.c
parent248b1e0aa41d97958c6f45132f6cc7e888263eb7 (diff)
downloadsystemd-907952bbc92dd6656807d9b2eb0d0c94a4c9e865.tar.gz
portabled: add --extension parameter for layered images support
Add an --extension parameter to portablectl, and new DBUS methods to attach/detach/reattach/inspect. Allows to append separate images on top of the root directory (os-release will be searched in there) and mount the images using an overlay-like setup (unit files will be searched in there) using the new ExtensionImages service option.
Diffstat (limited to 'src/portable/portabled-image-bus.c')
-rw-r--r--src/portable/portabled-image-bus.c198
1 files changed, 171 insertions, 27 deletions
diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c
index 8332332c91..88d8f914e0 100644
--- a/src/portable/portabled-image-bus.c
+++ b/src/portable/portabled-image-bus.c
@@ -75,20 +75,22 @@ static int bus_image_method_get_os_release(sd_bus_message *message, void *userda
static int append_fd(sd_bus_message *m, PortableMetadata *d) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *buf = NULL;
- size_t n;
+ size_t n = 0;
int r;
assert(m);
- assert(d);
- assert(d->fd >= 0);
- f = take_fdopen(&d->fd, "r");
- if (!f)
- return -errno;
+ if (d) {
+ assert(d->fd >= 0);
- r = read_full_stream(f, &buf, &n);
- if (r < 0)
- return r;
+ f = take_fdopen(&d->fd, "r");
+ if (!f)
+ return -errno;
+
+ r = read_full_stream(f, &buf, &n);
+ if (r < 0)
+ return r;
+ }
return sd_bus_message_append_array(m, 'y', buf, n);
}
@@ -101,10 +103,12 @@ int bus_image_common_get_metadata(
sd_bus_error *error) {
_cleanup_(portable_metadata_unrefp) PortableMetadata *os_release = NULL;
+ _cleanup_strv_free_ char **matches = NULL, **extension_images = NULL;
_cleanup_hashmap_free_ Hashmap *unit_files = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ PortableMetadata **sorted = NULL;
- _cleanup_strv_free_ char **matches = NULL;
+ /* Unused for now, but added to the DBUS methods for future-proofing */
+ uint64_t input_flags = 0;
size_t i;
int r;
@@ -116,10 +120,29 @@ int bus_image_common_get_metadata(
m = image->userdata;
}
+ if (sd_bus_message_is_method_call(message, NULL, "GetImageMetadataWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "GetMetadataWithExtensions")) {
+ r = sd_bus_message_read_strv(message, &extension_images);
+ if (r < 0)
+ return r;
+ }
+
r = sd_bus_message_read_strv(message, &matches);
if (r < 0)
return r;
+ if (sd_bus_message_is_method_call(message, NULL, "GetImageMetadataWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "GetMetadataWithExtensions")) {
+ r = sd_bus_message_read(message, "t", &input_flags);
+ if (r < 0)
+ return r;
+ /* Let clients know that this version doesn't support any flags */
+ if (input_flags != 0)
+ return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid 'flags' parameter '%" PRIu64 "'",
+ input_flags);
+ }
+
r = bus_image_acquire(m,
message,
name_or_path,
@@ -136,6 +159,7 @@ int bus_image_common_get_metadata(
r = portable_extract(
image->path,
matches,
+ extension_images,
&os_release,
&unit_files,
error);
@@ -223,12 +247,12 @@ int bus_image_common_attach(
Image *image,
sd_bus_error *error) {
- _cleanup_strv_free_ char **matches = NULL;
+ _cleanup_strv_free_ char **matches = NULL, **extension_images = NULL;
PortableChange *changes = NULL;
PortableFlags flags = 0;
const char *profile, *copy_mode;
size_t n_changes = 0;
- int runtime, r;
+ int r;
assert(message);
assert(name_or_path || image);
@@ -238,14 +262,44 @@ int bus_image_common_attach(
m = image->userdata;
}
+ if (sd_bus_message_is_method_call(message, NULL, "AttachImageWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "AttachWithExtensions")) {
+ r = sd_bus_message_read_strv(message, &extension_images);
+ if (r < 0)
+ return r;
+ }
+
r = sd_bus_message_read_strv(message, &matches);
if (r < 0)
return r;
- r = sd_bus_message_read(message, "sbs", &profile, &runtime, &copy_mode);
+ r = sd_bus_message_read(message, "s", &profile);
if (r < 0)
return r;
+ if (sd_bus_message_is_method_call(message, NULL, "AttachImageWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "AttachWithExtensions")) {
+ uint64_t input_flags = 0;
+
+ r = sd_bus_message_read(message, "st", &copy_mode, &input_flags);
+ if (r < 0)
+ return r;
+ if ((input_flags & ~_PORTABLE_MASK_PUBLIC) != 0)
+ return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid 'flags' parameter '%" PRIu64 "'",
+ input_flags);
+ flags |= input_flags;
+ } else {
+ int runtime;
+
+ r = sd_bus_message_read(message, "bs", &runtime, &copy_mode);
+ if (r < 0)
+ return r;
+
+ if (runtime)
+ flags |= PORTABLE_RUNTIME;
+ }
+
if (streq(copy_mode, "symlink"))
flags |= PORTABLE_PREFER_SYMLINK;
else if (streq(copy_mode, "copy"))
@@ -253,9 +307,6 @@ int bus_image_common_attach(
else if (!isempty(copy_mode))
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Unknown copy mode '%s'", copy_mode);
- if (runtime)
- flags |= PORTABLE_RUNTIME;
-
r = bus_image_acquire(m,
message,
name_or_path,
@@ -274,6 +325,7 @@ int bus_image_common_attach(
image->path,
matches,
profile,
+ extension_images,
flags,
&changes,
&n_changes,
@@ -297,19 +349,46 @@ static int bus_image_method_detach(
void *userdata,
sd_bus_error *error) {
+ _cleanup_strv_free_ char **extension_images = NULL;
PortableChange *changes = NULL;
Image *image = userdata;
Manager *m = image->userdata;
+ PortableFlags flags = 0;
size_t n_changes = 0;
- int r, runtime;
+ int r;
assert(message);
assert(image);
assert(m);
- r = sd_bus_message_read(message, "b", &runtime);
- if (r < 0)
- return r;
+ if (sd_bus_message_is_method_call(message, NULL, "DetachWithExtensions")) {
+ r = sd_bus_message_read_strv(message, &extension_images);
+ if (r < 0)
+ return r;
+ }
+
+ if (sd_bus_message_is_method_call(message, NULL, "DetachWithExtensions")) {
+ uint64_t input_flags = 0;
+
+ r = sd_bus_message_read(message, "t", &input_flags);
+ if (r < 0)
+ return r;
+
+ if ((input_flags & ~_PORTABLE_MASK_PUBLIC) != 0)
+ return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid 'flags' parameter '%" PRIu64 "'",
+ input_flags);
+ flags |= input_flags;
+ } else {
+ int runtime;
+
+ r = sd_bus_message_read(message, "b", &runtime);
+ if (r < 0)
+ return r;
+
+ if (runtime)
+ flags |= PORTABLE_RUNTIME;
+ }
r = bus_verify_polkit_async(
message,
@@ -328,7 +407,8 @@ static int bus_image_method_detach(
r = portable_detach(
sd_bus_message_get_bus(message),
image->path,
- runtime ? PORTABLE_RUNTIME : 0,
+ extension_images,
+ flags,
&changes,
&n_changes,
error);
@@ -510,10 +590,10 @@ int bus_image_common_reattach(
PortableChange *changes_detached = NULL, *changes_attached = NULL, *changes_gone = NULL;
size_t n_changes_detached = 0, n_changes_attached = 0, n_changes_gone = 0;
- _cleanup_strv_free_ char **matches = NULL;
+ _cleanup_strv_free_ char **matches = NULL, **extension_images = NULL;
PortableFlags flags = PORTABLE_REATTACH;
const char *profile, *copy_mode;
- int runtime, r;
+ int r;
assert(message);
assert(name_or_path || image);
@@ -523,14 +603,45 @@ int bus_image_common_reattach(
m = image->userdata;
}
+ if (sd_bus_message_is_method_call(message, NULL, "ReattachImageWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "ReattachWithExtensions")) {
+ r = sd_bus_message_read_strv(message, &extension_images);
+ if (r < 0)
+ return r;
+ }
+
r = sd_bus_message_read_strv(message, &matches);
if (r < 0)
return r;
- r = sd_bus_message_read(message, "sbs", &profile, &runtime, &copy_mode);
+ r = sd_bus_message_read(message, "s", &profile);
if (r < 0)
return r;
+ if (sd_bus_message_is_method_call(message, NULL, "ReattachImageWithExtensions") ||
+ sd_bus_message_is_method_call(message, NULL, "ReattachWithExtensions")) {
+ uint64_t input_flags = 0;
+
+ r = sd_bus_message_read(message, "st", &copy_mode, &input_flags);
+ if (r < 0)
+ return r;
+
+ if ((input_flags & ~_PORTABLE_MASK_PUBLIC) != 0)
+ return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid 'flags' parameter '%" PRIu64 "'",
+ input_flags);
+ flags |= input_flags;
+ } else {
+ int runtime;
+
+ r = sd_bus_message_read(message, "bs", &runtime, &copy_mode);
+ if (r < 0)
+ return r;
+
+ if (runtime)
+ flags |= PORTABLE_RUNTIME;
+ }
+
if (streq(copy_mode, "symlink"))
flags |= PORTABLE_PREFER_SYMLINK;
else if (streq(copy_mode, "copy"))
@@ -538,9 +649,6 @@ int bus_image_common_reattach(
else if (!isempty(copy_mode))
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Unknown copy mode '%s'", copy_mode);
- if (runtime)
- flags |= PORTABLE_RUNTIME;
-
r = bus_image_acquire(m,
message,
name_or_path,
@@ -557,6 +665,7 @@ int bus_image_common_reattach(
r = portable_detach(
sd_bus_message_get_bus(message),
image->path,
+ extension_images,
flags,
&changes_detached,
&n_changes_detached,
@@ -569,6 +678,7 @@ int bus_image_common_reattach(
image->path,
matches,
profile,
+ extension_images,
flags,
&changes_attached,
&n_changes_attached,
@@ -721,6 +831,15 @@ const sd_bus_vtable image_vtable[] = {
"a{say}", units),
bus_image_method_get_metadata,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("GetMetadataWithExtensions",
+ SD_BUS_ARGS("as", extensions,
+ "as", matches,
+ "t", flags),
+ SD_BUS_RESULT("s", image,
+ "ay", os_release,
+ "a{say}", units),
+ bus_image_method_get_metadata,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("GetState",
SD_BUS_NO_ARGS,
SD_BUS_RESULT("s", state),
@@ -734,11 +853,26 @@ const sd_bus_vtable image_vtable[] = {
SD_BUS_RESULT("a(sss)", changes),
bus_image_method_attach,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("AttachWithExtensions",
+ SD_BUS_ARGS("as", extensions,
+ "as", matches,
+ "s", profile,
+ "s", copy_mode,
+ "t", flags),
+ SD_BUS_RESULT("a(sss)", changes),
+ bus_image_method_attach,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("Detach",
SD_BUS_ARGS("b", runtime),
SD_BUS_RESULT("a(sss)", changes),
bus_image_method_detach,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("DetachWithExtensions",
+ SD_BUS_ARGS("as", extensions,
+ "t", flags),
+ SD_BUS_RESULT("a(sss)", changes),
+ bus_image_method_detach,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("Reattach",
SD_BUS_ARGS("as", matches,
"s", profile,
@@ -748,6 +882,16 @@ const sd_bus_vtable image_vtable[] = {
"a(sss)", changes_updated),
bus_image_method_reattach,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_ARGS("ReattacheWithExtensions",
+ SD_BUS_ARGS("as", extensions,
+ "as", matches,
+ "s", profile,
+ "s", copy_mode,
+ "t", flags),
+ SD_BUS_RESULT("a(sss)", changes_removed,
+ "a(sss)", changes_updated),
+ bus_image_method_reattach,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("Remove",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,