diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2020-06-23 13:09:42 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2021-03-31 09:56:44 +0100 |
commit | 907952bbc92dd6656807d9b2eb0d0c94a4c9e865 (patch) | |
tree | b5a1f594b1191699443798922b2c94e6d7fb0c76 /src/portable/portabled-image-bus.c | |
parent | 248b1e0aa41d97958c6f45132f6cc7e888263eb7 (diff) | |
download | systemd-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.c | 198 |
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, ©_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", ©_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, ©_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, ©_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", ©_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, ©_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, |