diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-12-27 17:44:04 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-12-28 02:08:40 +0100 |
commit | ebd93cb684806ac0f352139e69ac8f53eb49f5e4 (patch) | |
tree | 537df721db4f8a9a05ff8a3093481f5ea5571a92 /src/machine | |
parent | 086821244b5113f00a0ef993b78dc56aae2a8f6c (diff) |
machinectl/machined: implement "rename", "clone", "read-only" verbs for machine images
Diffstat (limited to 'src/machine')
-rw-r--r-- | src/machine/image-dbus.c | 92 | ||||
-rw-r--r-- | src/machine/machinectl.c | 90 | ||||
-rw-r--r-- | src/machine/machined-dbus.c | 87 |
3 files changed, 263 insertions, 6 deletions
diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index be2369953c..1030cd314f 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -236,6 +236,95 @@ static int method_remove( return sd_bus_reply_method_return(message, NULL); } +static int method_rename( + sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error) { + + _cleanup_(image_unrefp) Image *image = NULL; + const char *new_name; + int r; + + assert(bus); + assert(message); + + r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "s", &new_name); + if (r < 0) + return r; + + if (!image_name_is_valid(new_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); + + r = image_rename(image, new_name); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + +static int method_clone( + sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error) { + + _cleanup_(image_unrefp) Image *image = NULL; + const char *new_name; + int r, read_only; + + assert(bus); + assert(message); + + r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "sb", &new_name, &read_only); + if (r < 0) + return r; + + if (!image_name_is_valid(new_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); + + r = image_clone(image, new_name, read_only); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + +static int method_mark_read_only( + sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error) { + + _cleanup_(image_unrefp) Image *image = NULL; + int r, read_only; + + assert(bus); + assert(message); + + r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "b", &read_only); + if (r < 0) + return r; + + r = image_read_only(image, read_only); + 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", property_get_name, 0, 0), @@ -245,6 +334,9 @@ const sd_bus_vtable image_vtable[] = { SD_BUS_PROPERTY("CreationTimestamp", "t", property_get_crtime, 0, 0), SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime, 0, 0), SD_BUS_METHOD("Remove", NULL, NULL, method_remove, 0), + SD_BUS_METHOD("Rename", "s", NULL, method_rename, 0), + SD_BUS_METHOD("Clone", "sb", NULL, method_clone, 0), + SD_BUS_METHOD("MarkeReadOnly", "b", NULL, method_mark_read_only, 0), SD_BUS_VTABLE_END }; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 500e5b721a..893b429342 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1286,13 +1286,11 @@ static int login_machine(int argc, char *argv[], void *userdata) { static int remove_image(int argc, char *argv[], void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = userdata; - int i; + int r, i; assert(bus); for (i = 1; i < argc; i++) { - int r; - r = sd_bus_call_method( bus, "org.freedesktop.machine1", @@ -1311,6 +1309,80 @@ static int remove_image(int argc, char *argv[], void *userdata) { return 0; } +static int rename_image(int argc, char *argv[], void *userdata) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus = userdata; + int r; + + r = sd_bus_call_method( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "RenameImage", + &error, + NULL, + "ss", argv[1], argv[2]); + if (r < 0) { + log_error("Could not rename image: %s", bus_error_message(&error, -r)); + return r; + } + + return 0; +} + +static int clone_image(int argc, char *argv[], void *userdata) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus = userdata; + int r; + + r = sd_bus_call_method( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "CloneImage", + &error, + NULL, + "ssb", argv[1], argv[2], arg_read_only); + if (r < 0) { + log_error("Could not clone image: %s", bus_error_message(&error, -r)); + return r; + } + + return 0; +} + +static int read_only_image(int argc, char *argv[], void *userdata) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus *bus = userdata; + int b = true, r; + + if (argc > 2) { + b = parse_boolean(argv[2]); + if (b < 0) { + log_error("Failed to parse boolean argument: %s", argv[2]); + return -EINVAL; + } + } + + r = sd_bus_call_method( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "MarkImageReadOnly", + &error, + NULL, + "sb", argv[1], b); + if (r < 0) { + log_error("Could not mark image read-only: %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" @@ -1336,15 +1408,18 @@ static int help(int argc, char *argv[], void *userdata) { " login NAME Get a login prompt on a container\n" " poweroff NAME... Power off one or more containers\n" " reboot NAME... Reboot one or more containers\n" - " kill NAME... Send signal to processes of a VM/container\n" " terminate NAME... Terminate one or more VMs/containers\n" - " bind NAME PATH [PATH] Bind mount a path from the host into a container\n" + " kill NAME... Send signal to processes of a VM/container\n" " copy-to NAME PATH [PATH] Copy files from the host to a container\n" - " copy-from NAME PATH [PATH] Copy files from a container to the host\n\n" + " copy-from NAME PATH [PATH] Copy files from a container to the host\n" + " bind NAME PATH [PATH] Bind mount a path from the host into a container\n\n" "Image Commands:\n" " list-images Show available images\n" " image-status NAME... Show image details\n" " show-image NAME... Show properties of image\n" + " 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", program_invocation_short_name); @@ -1482,6 +1557,9 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { { "copy-to", 3, 4, 0, copy_files }, { "copy-from", 3, 4, 0, copy_files }, { "remove", 2, VERB_ANY, 0, remove_image }, + { "rename", 3, 3, 0, rename_image }, + { "clone", 3, 3, 0, clone_image }, + { "read-only", 2, 3, 0, read_only_image }, {} }; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 9296377c6f..18b772d42d 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -588,6 +588,90 @@ static int method_remove_image(sd_bus *bus, sd_bus_message *message, void *userd return sd_bus_reply_method_return(message, NULL); } +static int method_rename_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_(image_unrefp) Image* i = NULL; + const char *old_name, *new_name; + int r; + + assert(bus); + assert(message); + + r = sd_bus_message_read(message, "ss", &old_name, &new_name); + if (r < 0) + return r; + + if (!image_name_is_valid(old_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name); + if (!image_name_is_valid(new_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); + + r = image_find(old_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", old_name); + + r = image_rename(i, new_name); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + +static int method_clone_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_(image_unrefp) Image *i = NULL; + const char *old_name, *new_name; + int read_only, r; + + assert(bus); + r = sd_bus_message_read(message, "ssb", &old_name, &new_name, &read_only); + if (r < 0) + return r; + + if (!image_name_is_valid(old_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name); + if (!image_name_is_valid(new_name)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); + + r = image_find(old_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", old_name); + + r = image_clone(i, new_name, read_only); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + +static int method_mark_image_read_only(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_(image_unrefp) Image *i = NULL; + const char *name; + int read_only, r; + + assert(bus); + r = sd_bus_message_read(message, "sb", &name, &read_only); + 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); + + r = image_read_only(i, read_only); + if (r < 0) + return r; + + return sd_bus_reply_method_return(message, NULL); +} + const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED), @@ -606,6 +690,9 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0), SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, 0), + SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, 0), + SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, 0), + SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, 0), SD_BUS_SIGNAL("MachineNew", "so", 0), SD_BUS_SIGNAL("MachineRemoved", "so", 0), SD_BUS_VTABLE_END |