diff options
-rw-r--r-- | man/org.freedesktop.portable1.xml | 19 | ||||
-rw-r--r-- | src/portable/portable.c | 8 | ||||
-rw-r--r-- | src/portable/portable.h | 2 | ||||
-rw-r--r-- | src/portable/portablectl.c | 28 | ||||
-rw-r--r-- | src/portable/portabled-bus.c | 28 | ||||
-rw-r--r-- | src/portable/portabled-image-bus.c | 27 | ||||
-rwxr-xr-x | test/units/testsuite-29.sh | 8 |
7 files changed, 112 insertions, 8 deletions
diff --git a/man/org.freedesktop.portable1.xml b/man/org.freedesktop.portable1.xml index 53c960206e..a63b6aeebe 100644 --- a/man/org.freedesktop.portable1.xml +++ b/man/org.freedesktop.portable1.xml @@ -57,6 +57,10 @@ node /org/freedesktop/portable1 { out a{say} units); GetImageState(in s image, out s state); + GetImageStateWithExtensions(in s image, + in as extensions, + in t flags, + out s state); AttachImage(in s image, in as matches, in s profile, @@ -132,6 +136,8 @@ node /org/freedesktop/portable1 { <variablelist class="dbus-method" generated="True" extra-ref="GetImageState()"/> + <variablelist class="dbus-method" generated="True" extra-ref="GetImageStateWithExtensions()"/> + <variablelist class="dbus-method" generated="True" extra-ref="AttachImage()"/> <variablelist class="dbus-method" generated="True" extra-ref="AttachImageWithExtensions()"/> @@ -207,6 +213,12 @@ node /org/freedesktop/portable1 { <listitem><para>running-runtime</para></listitem> </itemizedlist></para> + <para><function>GetImageStateWithExtensions()</function> is a superset of + <function>GetImageState()</function>, with additional support for a list of extensions + as input parameters, which is necessary to query the state in case the image was attached + in that particular way. The <varname>flag</varname> parameter is currently unused and + reserved for future purposes.</para> + <para><function>AttachImage()</function> attaches a portable image to the system. This method takes an image path or name, a list of strings that will be used to search for unit files inside the image (partial or complete matches), a string indicating which @@ -334,6 +346,9 @@ node /org/freedesktop/portable1 { out ay os_release, out a{say} units); GetState(out s state); + GetStateWithExtensions(in as extensions, + in t flags, + out s state); Attach(in as matches, in s profile, in b runtime, @@ -402,6 +417,8 @@ node /org/freedesktop/portable1 { <!--method GetState is not documented!--> + <!--method GetStateWithExtensions is not documented!--> + <!--method Attach is not documented!--> <!--method AttachWithExtensions is not documented!--> @@ -434,6 +451,8 @@ node /org/freedesktop/portable1 { <variablelist class="dbus-method" generated="True" extra-ref="GetState()"/> + <variablelist class="dbus-method" generated="True" extra-ref="GetStateWithExtensions()"/> + <variablelist class="dbus-method" generated="True" extra-ref="Attach()"/> <variablelist class="dbus-method" generated="True" extra-ref="AttachWithExtensions()"/> diff --git a/src/portable/portable.c b/src/portable/portable.c index b79992b245..f460a6b224 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -1662,6 +1662,7 @@ not_found: static int portable_get_state_internal( sd_bus *bus, const char *name_or_path, + char **extension_image_paths, PortableFlags flags, PortableState *ret, sd_bus_error *error) { @@ -1706,7 +1707,7 @@ static int portable_get_state_internal( if (!IN_SET(de->d_type, DT_LNK, DT_REG)) continue; - r = test_chroot_dropin(d, where, de->d_name, name_or_path, NULL, NULL); + r = test_chroot_dropin(d, where, de->d_name, name_or_path, extension_image_paths, NULL); if (r < 0) return r; if (r == 0) @@ -1739,6 +1740,7 @@ static int portable_get_state_internal( int portable_get_state( sd_bus *bus, const char *name_or_path, + char **extension_image_paths, PortableFlags flags, PortableState *ret, sd_bus_error *error) { @@ -1752,12 +1754,12 @@ int portable_get_state( /* We look for matching units twice: once in the regular directories, and once in the runtime directories — but * the latter only if we didn't find anything in the former. */ - r = portable_get_state_internal(bus, name_or_path, flags & ~PORTABLE_RUNTIME, &state, error); + r = portable_get_state_internal(bus, name_or_path, extension_image_paths, flags & ~PORTABLE_RUNTIME, &state, error); if (r < 0) return r; if (state == PORTABLE_DETACHED) { - r = portable_get_state_internal(bus, name_or_path, flags | PORTABLE_RUNTIME, &state, error); + r = portable_get_state_internal(bus, name_or_path, extension_image_paths, flags | PORTABLE_RUNTIME, &state, error); if (r < 0) return r; } diff --git a/src/portable/portable.h b/src/portable/portable.h index 2837e8b286..fddb4e46ce 100644 --- a/src/portable/portable.h +++ b/src/portable/portable.h @@ -70,7 +70,7 @@ int portable_extract(const char *image, char **matches, char **extension_image_p 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); -int portable_get_state(sd_bus *bus, const char *name_or_path, PortableFlags flags, PortableState *ret, sd_bus_error *error); +int portable_get_state(sd_bus *bus, const char *name_or_path, char **extension_image_paths, PortableFlags flags, PortableState *ret, sd_bus_error *error); int portable_get_profiles(char ***ret); diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c index 60feac6f5d..27883eb867 100644 --- a/src/portable/portablectl.c +++ b/src/portable/portablectl.c @@ -1034,11 +1034,11 @@ static int set_limit(int argc, char *argv[], void *userdata) { } static int is_image_attached(int argc, char *argv[], void *userdata) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_free_ char *image = NULL; - const char *state; + const char *state, *method; int r; r = determine_image(argv[1], true, &image); @@ -1049,9 +1049,29 @@ static int is_image_attached(int argc, char *argv[], void *userdata) { if (r < 0) return r; - r = bus_call_method(bus, bus_portable_mgr, "GetImageState", &error, &reply, "s", image); + method = strv_isempty(arg_extension_images) ? "GetImageState" : "GetImageStateWithExtensions"; + + r = bus_message_new_method_call(bus, &m, bus_portable_mgr, method); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append(m, "s", image); + if (r < 0) + return bus_log_create_error(r); + + r = attach_extensions_to_message(m, arg_extension_images); + if (r < 0) + return r; + + if (!strv_isempty(arg_extension_images)) { + r = sd_bus_message_append(m, "t", 0); + if (r < 0) + return bus_log_create_error(r); + } + + r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) - return log_error_errno(r, "Failed to get image state: %s", bus_error_message(&error, r)); + return log_error_errno(r, "%s failed: %s", method, bus_error_message(&error, r)); r = sd_bus_message_read(reply, "s", &state); if (r < 0) diff --git a/src/portable/portabled-bus.c b/src/portable/portabled-bus.c index 5b992d9df8..214fdb5b30 100644 --- a/src/portable/portabled-bus.c +++ b/src/portable/portabled-bus.c @@ -169,6 +169,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er r = portable_get_state( sd_bus_message_get_bus(message), image->path, + NULL, 0, &state, &error_state); @@ -225,6 +226,7 @@ static int method_get_image_metadata(sd_bus_message *message, void *userdata, sd } static int method_get_image_state(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_strv_free_ char **extension_images = NULL; const char *name_or_path; PortableState state; int r; @@ -235,9 +237,28 @@ static int method_get_image_state(sd_bus_message *message, void *userdata, sd_bu if (r < 0) return r; + if (sd_bus_message_is_method_call(message, NULL, "GetImageStateWithExtensions")) { + uint64_t input_flags = 0; + + r = sd_bus_message_read_strv(message, &extension_images); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "t", &input_flags); + if (r < 0) + return r; + + /* No flags are supported by this method for now. */ + if (input_flags != 0) + return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, + "Invalid 'flags' parameter '%" PRIu64 "'", + input_flags); + } + r = portable_get_state( sd_bus_message_get_bus(message), name_or_path, + extension_images, 0, &state, error); @@ -428,6 +449,13 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_RESULT("s", state), method_get_image_state, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("GetImageStateWithExtensions", + SD_BUS_ARGS("s", image, + "as", extensions, + "t", flags), + SD_BUS_RESULT("s", state), + method_get_image_state, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("AttachImage", SD_BUS_ARGS("s", image, "as", matches, diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c index ede062dbfb..4a1798ac52 100644 --- a/src/portable/portabled-image-bus.c +++ b/src/portable/portabled-image-bus.c @@ -222,6 +222,7 @@ static int bus_image_method_get_state( void *userdata, sd_bus_error *error) { + _cleanup_strv_free_ char **extension_images = NULL; Image *image = userdata; PortableState state; int r; @@ -229,9 +230,28 @@ static int bus_image_method_get_state( assert(message); assert(image); + if (sd_bus_message_is_method_call(message, NULL, "GetStateWithExtensions")) { + uint64_t input_flags = 0; + + r = sd_bus_message_read_strv(message, &extension_images); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "t", &input_flags); + if (r < 0) + return r; + + /* No flags are supported by this method for now. */ + if (input_flags != 0) + return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, + "Invalid 'flags' parameter '%" PRIu64 "'", + input_flags); + } + r = portable_get_state( sd_bus_message_get_bus(message), image->path, + extension_images, 0, &state, error); @@ -462,6 +482,7 @@ int bus_image_common_remove( r = portable_get_state( sd_bus_message_get_bus(message), image->path, + NULL, 0, &state, error); @@ -846,6 +867,12 @@ const sd_bus_vtable image_vtable[] = { SD_BUS_RESULT("s", state), bus_image_method_get_state, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("GetStateWithExtensions", + SD_BUS_ARGS("as", extensions, + "t", flags), + SD_BUS_RESULT("s", state), + bus_image_method_get_state, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("Attach", SD_BUS_ARGS("as", matches, "s", profile, diff --git a/test/units/testsuite-29.sh b/test/units/testsuite-29.sh index 5008a1b44c..b4e41495a3 100755 --- a/test/units/testsuite-29.sh +++ b/test/units/testsuite-29.sh @@ -84,20 +84,28 @@ portablectl list | grep -q -F "No images." portablectl "${ARGS[@]}" attach --now --runtime --extension /usr/share/app0.raw /usr/share/minimal_0.raw app0 systemctl is-active app0.service +status="$(portablectl is-attached --extension app0 minimal_0)" +[[ "${status}" == "running-runtime" ]] portablectl "${ARGS[@]}" reattach --now --runtime --extension /usr/share/app0.raw /usr/share/minimal_1.raw app0 systemctl is-active app0.service +status="$(portablectl is-attached --extension app0 minimal_1)" +[[ "${status}" == "running-runtime" ]] portablectl detach --now --runtime --extension /usr/share/app0.raw /usr/share/minimal_1.raw app0 portablectl "${ARGS[@]}" attach --now --runtime --extension /usr/share/app1.raw /usr/share/minimal_0.raw app1 systemctl is-active app1.service +status="$(portablectl is-attached --extension app1 minimal_0)" +[[ "${status}" == "running-runtime" ]] portablectl "${ARGS[@]}" reattach --now --runtime --extension /usr/share/app1.raw /usr/share/minimal_1.raw app1 systemctl is-active app1.service +status="$(portablectl is-attached --extension app1 minimal_1)" +[[ "${status}" == "running-runtime" ]] portablectl detach --now --runtime --extension /usr/share/app1.raw /usr/share/minimal_1.raw app1 |