diff --git a/src/machine/image-varlink.c b/src/machine/image-varlink.c index 4a4f611bda8..0e616da9d1d 100644 --- a/src/machine/image-varlink.c +++ b/src/machine/image-varlink.c @@ -4,9 +4,12 @@ #include "sd-varlink.h" #include "bus-polkit.h" +#include "btrfs-util.h" #include "fd-util.h" #include "image-varlink.h" +#include "io-util.h" #include "machine.h" +#include "machine-pool.h" #include "string-util.h" typedef struct ImageUpdateParameters { @@ -230,3 +233,47 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var TAKE_FD(errno_pipe_fd[0]); return 1; } + +int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + static const sd_json_dispatch_field dispatch_table[] = { + { "limit", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, 0, SD_JSON_MANDATORY }, + VARLINK_DISPATCH_POLKIT_FIELD, + {} + }; + + Manager *manager = ASSERT_PTR(userdata); + uint64_t limit; + int r; + + assert(link); + assert(parameters); + + r = sd_varlink_dispatch(link, parameters, dispatch_table, &limit); + if (r != 0) + return r; + + if (!FILE_SIZE_VALID_OR_INFINITY(limit)) + return sd_varlink_error_invalid_parameter_name(link, "limit"); + + r = varlink_verify_polkit_async( + link, + manager->bus, + "org.freedesktop.machine1.manage-images", + (const char**) STRV_MAKE("verb", "set_pool_limit"), + &manager->polkit_registry); + if (r <= 0) + return r; + + /* Set up the machine directory if necessary */ + r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true); + if (r < 0) + return r; + + r = image_set_pool_limit(IMAGE_MACHINE, limit); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED, NULL); + if (r < 0) + return r; + + return sd_varlink_reply(link, NULL); +} diff --git a/src/machine/image-varlink.h b/src/machine/image-varlink.h index 7f68fe86fbd..5d94edf6786 100644 --- a/src/machine/image-varlink.h +++ b/src/machine/image-varlink.h @@ -5,7 +5,9 @@ #define VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE "io.systemd.MachineImage.NoSuchImage" #define VARLINK_ERROR_MACHINE_IMAGE_TOO_MANY_OPERATIONS "io.systemd.MachineImage.TooManyOperations" +#define VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED "io.systemd.MachineImage.NotSupported" int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); +int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index 72ded672dc1..dc293f58958 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -797,7 +797,8 @@ static int manager_varlink_init_machine(Manager *m) { "io.systemd.MachineImage.List", vl_method_list_images, "io.systemd.MachineImage.Update", vl_method_update_image, "io.systemd.MachineImage.Clone", vl_method_clone_image, - "io.systemd.MachineImage.Remove", vl_method_remove_image); + "io.systemd.MachineImage.Remove", vl_method_remove_image, + "io.systemd.MachineImage.SetPoolLimit", vl_method_set_pool_limit); if (r < 0) return log_error_errno(r, "Failed to register varlink methods: %m"); diff --git a/src/shared/varlink-io.systemd.MachineImage.c b/src/shared/varlink-io.systemd.MachineImage.c index 813b6c8e68d..8e9d90fe70a 100644 --- a/src/shared/varlink-io.systemd.MachineImage.c +++ b/src/shared/varlink-io.systemd.MachineImage.c @@ -80,8 +80,15 @@ static SD_VARLINK_DEFINE_METHOD( Remove, VARLINK_DEFINE_IMAGE_LOOKUP_AND_POLKIT_FIELDS); +static SD_VARLINK_DEFINE_METHOD( + SetPoolLimit, + VARLINK_DEFINE_POLKIT_INPUT, + SD_VARLINK_FIELD_COMMENT("New image quota limit"), + SD_VARLINK_DEFINE_INPUT(limit, SD_VARLINK_INT, 0)); + static SD_VARLINK_DEFINE_ERROR(NoSuchImage); static SD_VARLINK_DEFINE_ERROR(TooManyOperations); +static SD_VARLINK_DEFINE_ERROR(NotSupported); SD_VARLINK_DEFINE_INTERFACE( io_systemd_MachineImage, @@ -90,13 +97,17 @@ SD_VARLINK_DEFINE_INTERFACE( &vl_type_AcquireMetadata, SD_VARLINK_SYMBOL_COMMENT("List images"), &vl_method_List, - SD_VARLINK_SYMBOL_COMMENT("Update image allowing to rename or toggle read-only flag"), + SD_VARLINK_SYMBOL_COMMENT("Update image allowing to rename, toggle read-only flag, or set a limit"), &vl_method_Update, SD_VARLINK_SYMBOL_COMMENT("Clone image"), &vl_method_Clone, SD_VARLINK_SYMBOL_COMMENT("Remove image"), &vl_method_Remove, + SD_VARLINK_SYMBOL_COMMENT("Sets an overall quota limit on the pool of images"), + &vl_method_SetPoolLimit, SD_VARLINK_SYMBOL_COMMENT("No matching image exists"), &vl_error_NoSuchImage, SD_VARLINK_SYMBOL_COMMENT("Too many ongoing background operations"), - &vl_error_TooManyOperations); + &vl_error_TooManyOperations, + SD_VARLINK_SYMBOL_COMMENT("Requested operation is not supported"), + &vl_error_NotSupported);