machined: add "machinectl remove" for removing images

This commit is contained in:
Lennart Poettering 2014-12-27 02:35:47 +01:00
parent 1b9cebf638
commit 086821244b
5 changed files with 102 additions and 3 deletions

View file

@ -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
};

View file

@ -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 },
{}
};

View file

@ -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

View file

@ -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",

View file

@ -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_;