From: Lennart Poettering Date: Sat, 27 Dec 2014 01:35:47 +0000 (+0100) Subject: machined: add "machinectl remove" for removing images X-Git-Tag: v219~789 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=086821244b5113f00a0ef993b78dc56aae2a8f6c machined: add "machinectl remove" for removing images --- diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index c8d1328fe..be2369953 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -196,7 +196,6 @@ static int property_get_mtime( void *userdata, sd_bus_error *error) { - _cleanup_(image_unrefp) Image *image = NULL; int r; @@ -214,6 +213,29 @@ static int property_get_mtime( return 1; } +static int method_remove( + sd_bus *bus, + sd_bus_message *message, + void *userdata, + sd_bus_error *error) { + + _cleanup_(image_unrefp) Image *image = NULL; + 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 = image_remove(image); + 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), @@ -222,6 +244,7 @@ const sd_bus_vtable image_vtable[] = { SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0), 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_VTABLE_END }; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 0f69734dc..500e5b721 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1283,6 +1283,34 @@ static int login_machine(int argc, char *argv[], void *userdata) { return ret; } +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; + + assert(bus); + + for (i = 1; i < argc; i++) { + int r; + + r = sd_bus_call_method( + bus, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", + "org.freedesktop.machine1.Manager", + "RemoveImage", + &error, + NULL, + "s", argv[i]); + if (r < 0) { + log_error("Could not remove image: %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" @@ -1316,7 +1344,8 @@ static int help(int argc, char *argv[], void *userdata) { "Image Commands:\n" " list-images Show available images\n" " image-status NAME... Show image details\n" - " show-image NAME... Show properties of image\n", + " show-image NAME... Show properties of image\n" + " remove NAME... Remove an image\n", program_invocation_short_name); return 0; @@ -1452,6 +1481,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { { "bind", 3, 4, 0, bind_mount }, { "copy-to", 3, 4, 0, copy_files }, { "copy-from", 3, 4, 0, copy_files }, + { "remove", 2, VERB_ANY, 0, remove_image }, {} }; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 66594ab0b..9296377c6 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -551,7 +551,7 @@ static int method_open_machine_login(sd_bus *bus, sd_bus_message *message, void r = sd_bus_message_read(message, "s", &name); if (r < 0) - return sd_bus_error_set_errno(error, r); + return r; machine = hashmap_get(m->machines, name); if (!machine) @@ -560,6 +560,34 @@ static int method_open_machine_login(sd_bus *bus, sd_bus_message *message, void return bus_machine_method_open_login(bus, message, machine, error); } +static int method_remove_image(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); + assert(message); + + 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); + + r = image_remove(i); + 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), @@ -577,6 +605,7 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED), 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_SIGNAL("MachineNew", "so", 0), SD_BUS_SIGNAL("MachineRemoved", "so", 0), SD_BUS_VTABLE_END diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 51f89d592..fa06a0dc5 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -316,6 +316,21 @@ void image_hashmap_free(Hashmap *map) { hashmap_free(map); } +int image_remove(Image *i) { + int r; + + assert(i); + + if (path_equal(i->path, "/") || + path_startswith(i->path, "/usr")) + return -EROFS; + + if (i->type == IMAGE_SUBVOLUME) + return btrfs_subvol_remove(i->path); + else + return rm_rf_dangerous(i->path, false, true, false); +} + static const char* const image_type_table[_IMAGE_TYPE_MAX] = { [IMAGE_DIRECTORY] = "directory", [IMAGE_SUBVOLUME] = "subvolume", diff --git a/src/shared/machine-image.h b/src/shared/machine-image.h index 646598f9c..e17e32f4a 100644 --- a/src/shared/machine-image.h +++ b/src/shared/machine-image.h @@ -51,5 +51,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free); int image_find(const char *name, Image **ret); int image_discover(Hashmap *map); +int image_remove(Image *i); + const char* image_type_to_string(ImageType t) _const_; ImageType image_type_from_string(const char *s) _pure_;