mirror of
https://github.com/systemd/systemd
synced 2024-07-24 03:36:24 +00:00
portable: add GetImageStateWithExtensions method
Allow to correctly query a layered portable service for attached/detached state.
This commit is contained in:
parent
9697662915
commit
0017415cc5
|
@ -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()"/>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 log_error_errno(r, "Failed to get image state: %s", bus_error_message(&error, r));
|
||||
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, "%s failed: %s", method, bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "s", &state);
|
||||
if (r < 0)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue