machined,machinectl: add calls for changing container/VM quotas
This commit is contained in:
@@ -182,6 +182,44 @@ int bus_image_method_mark_read_only(
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
int bus_image_method_set_limit(
|
||||
sd_bus *bus,
|
||||
sd_bus_message *message,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Image *image = userdata;
|
||||
Manager *m = image->userdata;
|
||||
uint64_t limit;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(message);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &limit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_verify_polkit_async(
|
||||
message,
|
||||
CAP_SYS_ADMIN,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
false,
|
||||
UID_INVALID,
|
||||
&m->polkit_registry,
|
||||
error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
|
||||
r = image_set_limit(image, limit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable image_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
|
||||
@@ -198,6 +236,7 @@ const sd_bus_vtable image_vtable[] = {
|
||||
SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
|
||||
@@ -34,3 +34,4 @@ int bus_image_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata
|
||||
int bus_image_method_rename(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_image_method_clone(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_image_method_mark_read_only(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_image_method_set_limit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -1961,6 +1961,56 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_limit(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
sd_bus *bus = userdata;
|
||||
uint64_t limit;
|
||||
int r;
|
||||
|
||||
if (streq(argv[argc-1], "-"))
|
||||
limit = (uint64_t) -1;
|
||||
else {
|
||||
off_t off;
|
||||
|
||||
r = parse_size(argv[argc-1], 1024, &off);
|
||||
if (r < 0)
|
||||
return log_error("Failed to parse size: %s", argv[argc-1]);
|
||||
|
||||
limit = (uint64_t) off;
|
||||
}
|
||||
|
||||
if (argc > 2)
|
||||
/* With two arguments changes the quota limit of the
|
||||
* specified image */
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.machine1",
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
"SetImageLimit",
|
||||
&error,
|
||||
NULL,
|
||||
"st", argv[1], limit);
|
||||
else
|
||||
/* With one argument changes the pool quota limit */
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.machine1",
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
"SetPoolLimit",
|
||||
&error,
|
||||
NULL,
|
||||
"t", limit);
|
||||
|
||||
if (r < 0) {
|
||||
log_error("Could not set limit: %s", bus_error_message(&error, -r));
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int help(int argc, char *argv[], void *userdata) {
|
||||
|
||||
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
|
||||
@@ -2012,7 +2062,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" clone NAME NAME Clone an image\n"
|
||||
" rename NAME NAME Rename an image\n"
|
||||
" read-only NAME [BOOL] Mark or unmark image read-only\n"
|
||||
" remove NAME... Remove an image\n\n"
|
||||
" remove NAME... Remove an image\n"
|
||||
" set-limit [NAME] BYTES Set image size limit (quota)\n\n"
|
||||
"Image Transfer Commands:\n"
|
||||
" pull-tar URL [NAME] Download a TAR container image\n"
|
||||
" pull-raw URL [NAME] Download a RAW container or VM image\n"
|
||||
@@ -2221,6 +2272,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
|
||||
{ "pull-dkr", 2, 3, 0, pull_dkr },
|
||||
{ "list-transfers", VERB_ANY, 1, 0, list_transfers },
|
||||
{ "cancel-transfer", 2, VERB_ANY, 0, cancel_transfer },
|
||||
{ "set-limit", 2, 3, 0, set_limit },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -776,6 +776,61 @@ static int method_mark_image_read_only(sd_bus *bus, sd_bus_message *message, voi
|
||||
return bus_image_method_mark_read_only(bus, message, i, error);
|
||||
}
|
||||
|
||||
static int method_set_pool_limit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
Manager *m = userdata;
|
||||
uint64_t limit;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
r = sd_bus_message_read(message, "t", &limit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_verify_polkit_async(
|
||||
message,
|
||||
CAP_SYS_ADMIN,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
false,
|
||||
UID_INVALID,
|
||||
&m->polkit_registry,
|
||||
error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
|
||||
r = btrfs_quota_limit("/var/lib/machines", limit);
|
||||
if (r == -ENOTTY)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
|
||||
else if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r, "Failed to adjust quota limit: %m");
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
static int method_set_image_limit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_(image_unrefp) Image *i = NULL;
|
||||
const char *name;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
r = sd_bus_message_read(message, "s", &name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!image_name_is_valid(name))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
|
||||
|
||||
r = image_find(name, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
|
||||
|
||||
i->userdata = userdata;
|
||||
return bus_image_method_set_limit(bus, message, i, error);
|
||||
}
|
||||
|
||||
const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("PoolPath", "s", property_get_pool_path, 0, 0),
|
||||
@@ -803,6 +858,8 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_SIGNAL("MachineNew", "so", 0),
|
||||
SD_BUS_SIGNAL("MachineRemoved", "so", 0),
|
||||
SD_BUS_VTABLE_END
|
||||
|
||||
@@ -104,6 +104,14 @@
|
||||
send_interface="org.freedesktop.machine1.Manager"
|
||||
send_member="MarkImageReadOnly"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.machine1"
|
||||
send_interface="org.freedesktop.machine1.Manager"
|
||||
send_member="SetPoolLimit"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.machine1"
|
||||
send_interface="org.freedesktop.machine1.Manager"
|
||||
send_member="SetImageLimit"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.machine1"
|
||||
send_interface="org.freedesktop.machine1.Machine"
|
||||
send_member="GetAddresses"/>
|
||||
@@ -148,6 +156,10 @@
|
||||
send_interface="org.freedesktop.machine1.Image"
|
||||
send_member="Clone"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.machine1"
|
||||
send_interface="org.freedesktop.machine1.Image"
|
||||
send_member="SetLimit"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.machine1"
|
||||
send_interface="org.freedesktop.machine1.Image"
|
||||
send_member="MarkReadOnly"/>
|
||||
|
||||
Reference in New Issue
Block a user