]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/machine/image-dbus.c
machined: add "machinectl remove" for removing images
[thirdparty/systemd.git] / src / machine / image-dbus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "bus-label.h"
23 #include "bus-common-errors.h"
24 #include "strv.h"
25 #include "machine-image.h"
26 #include "image-dbus.h"
27
28 static int image_find_by_bus_path(const char *path, Image **ret) {
29 _cleanup_free_ char *e = NULL;
30 const char *p;
31
32 assert(path);
33
34 p = startswith(path, "/org/freedesktop/machine1/image/");
35 if (!p)
36 return 0;
37
38 e = bus_label_unescape(p);
39 if (!e)
40 return -ENOMEM;
41
42 return image_find(e, ret);
43 }
44
45 static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
46 int r;
47
48 assert(path);
49
50 r = image_find_by_bus_path(path, ret);
51 if (r == 0)
52 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
53
54 return r;
55 }
56
57 static int property_get_name(
58 sd_bus *bus,
59 const char *path,
60 const char *interface,
61 const char *property,
62 sd_bus_message *reply,
63 void *userdata,
64 sd_bus_error *error) {
65
66 _cleanup_(image_unrefp) Image *image = NULL;
67 int r;
68
69 assert(bus);
70 assert(reply);
71
72 r = image_find_by_bus_path_with_error(path, &image, error);
73 if (r < 0)
74 return r;
75
76 r = sd_bus_message_append(reply, "s", image->name);
77 if (r < 0)
78 return r;
79
80 return 1;
81 }
82
83 static int property_get_path(
84 sd_bus *bus,
85 const char *path,
86 const char *interface,
87 const char *property,
88 sd_bus_message *reply,
89 void *userdata,
90 sd_bus_error *error) {
91
92 _cleanup_(image_unrefp) Image *image = NULL;
93 int r;
94
95 assert(bus);
96 assert(reply);
97
98 r = image_find_by_bus_path_with_error(path, &image, error);
99 if (r < 0)
100 return r;
101
102 r = sd_bus_message_append(reply, "s", image->path);
103 if (r < 0)
104 return r;
105
106 return 1;
107 }
108
109 static int property_get_type(
110 sd_bus *bus,
111 const char *path,
112 const char *interface,
113 const char *property,
114 sd_bus_message *reply,
115 void *userdata,
116 sd_bus_error *error) {
117
118
119 _cleanup_(image_unrefp) Image *image = NULL;
120 int r;
121
122 assert(bus);
123 assert(reply);
124
125 r = image_find_by_bus_path_with_error(path, &image, error);
126 if (r < 0)
127 return r;
128
129 r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
130 if (r < 0)
131 return r;
132
133 return 1;
134 }
135
136 static int property_get_read_only(
137 sd_bus *bus,
138 const char *path,
139 const char *interface,
140 const char *property,
141 sd_bus_message *reply,
142 void *userdata,
143 sd_bus_error *error) {
144
145
146 _cleanup_(image_unrefp) Image *image = NULL;
147 int r;
148
149 assert(bus);
150 assert(reply);
151
152 r = image_find_by_bus_path_with_error(path, &image, error);
153 if (r < 0)
154 return r;
155
156 r = sd_bus_message_append(reply, "b", image->read_only);
157 if (r < 0)
158 return r;
159
160 return 1;
161 }
162
163 static int property_get_crtime(
164 sd_bus *bus,
165 const char *path,
166 const char *interface,
167 const char *property,
168 sd_bus_message *reply,
169 void *userdata,
170 sd_bus_error *error) {
171
172
173 _cleanup_(image_unrefp) Image *image = NULL;
174 int r;
175
176 assert(bus);
177 assert(reply);
178
179 r = image_find_by_bus_path_with_error(path, &image, error);
180 if (r < 0)
181 return r;
182
183 r = sd_bus_message_append(reply, "t", image->crtime);
184 if (r < 0)
185 return r;
186
187 return 1;
188 }
189
190 static int property_get_mtime(
191 sd_bus *bus,
192 const char *path,
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
196 void *userdata,
197 sd_bus_error *error) {
198
199 _cleanup_(image_unrefp) Image *image = NULL;
200 int r;
201
202 assert(bus);
203 assert(reply);
204
205 r = image_find_by_bus_path_with_error(path, &image, error);
206 if (r < 0)
207 return r;
208
209 r = sd_bus_message_append(reply, "t", image->mtime);
210 if (r < 0)
211 return r;
212
213 return 1;
214 }
215
216 static int method_remove(
217 sd_bus *bus,
218 sd_bus_message *message,
219 void *userdata,
220 sd_bus_error *error) {
221
222 _cleanup_(image_unrefp) Image *image = NULL;
223 int r;
224
225 assert(bus);
226 assert(message);
227
228 r = image_find_by_bus_path_with_error(sd_bus_message_get_path(message), &image, error);
229 if (r < 0)
230 return r;
231
232 r = image_remove(image);
233 if (r < 0)
234 return r;
235
236 return sd_bus_reply_method_return(message, NULL);
237 }
238
239 const sd_bus_vtable image_vtable[] = {
240 SD_BUS_VTABLE_START(0),
241 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, 0),
242 SD_BUS_PROPERTY("Path", "s", property_get_path, 0, 0),
243 SD_BUS_PROPERTY("Type", "s", property_get_type, 0, 0),
244 SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
245 SD_BUS_PROPERTY("CreationTimestamp", "t", property_get_crtime, 0, 0),
246 SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime, 0, 0),
247 SD_BUS_METHOD("Remove", NULL, NULL, method_remove, 0),
248 SD_BUS_VTABLE_END
249 };
250
251 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
252 int r;
253
254 assert(bus);
255 assert(path);
256 assert(interface);
257 assert(found);
258
259 r = image_find_by_bus_path(path, NULL);
260 if (r <= 0)
261 return r;
262
263 *found = NULL;
264 return 1;
265 }
266
267 char *image_bus_path(const char *name) {
268 _cleanup_free_ char *e = NULL;
269
270 assert(name);
271
272 e = bus_label_escape(name);
273 if (!e)
274 return NULL;
275
276 return strappend("/org/freedesktop/machine1/image/", e);
277 }
278
279 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
280 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
281 _cleanup_strv_free_ char **l = NULL;
282 Image *image;
283 Iterator i;
284 int r;
285
286 assert(bus);
287 assert(path);
288 assert(nodes);
289
290 images = hashmap_new(&string_hash_ops);
291 if (!images)
292 return -ENOMEM;
293
294 r = image_discover(images);
295 if (r < 0)
296 return r;
297
298 HASHMAP_FOREACH(image, images, i) {
299 char *p;
300
301 p = image_bus_path(image->name);
302 if (!p)
303 return -ENOMEM;
304
305 r = strv_consume(&l, p);
306 if (r < 0)
307 return r;
308 }
309
310 *nodes = l;
311 l = NULL;
312
313 return 1;
314 }