chiark / gitweb /
machined: Move image discovery logic into src/shared, so that we can make use of...
[elogind.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
200         _cleanup_(image_unrefp) Image *image = NULL;
201         int r;
202
203         assert(bus);
204         assert(reply);
205
206         r = image_find_by_bus_path_with_error(path, &image, error);
207         if (r < 0)
208                 return r;
209
210         r = sd_bus_message_append(reply, "t", image->mtime);
211         if (r < 0)
212                 return r;
213
214         return 1;
215 }
216
217 const sd_bus_vtable image_vtable[] = {
218         SD_BUS_VTABLE_START(0),
219         SD_BUS_PROPERTY("Name",                  "s", property_get_name,      0, 0),
220         SD_BUS_PROPERTY("Path",                  "s", property_get_path,      0, 0),
221         SD_BUS_PROPERTY("Type",                  "s", property_get_type,      0, 0),
222         SD_BUS_PROPERTY("ReadOnly",              "b", property_get_read_only, 0, 0),
223         SD_BUS_PROPERTY("CreationTimestamp",     "t", property_get_crtime,    0, 0),
224         SD_BUS_PROPERTY("ModificationTimestamp", "t", property_get_mtime,     0, 0),
225         SD_BUS_VTABLE_END
226 };
227
228 int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
229         int r;
230
231         assert(bus);
232         assert(path);
233         assert(interface);
234         assert(found);
235
236         r = image_find_by_bus_path(path, NULL);
237         if (r <= 0)
238                 return r;
239
240         *found = NULL;
241         return 1;
242 }
243
244 char *image_bus_path(const char *name) {
245         _cleanup_free_ char *e = NULL;
246
247         assert(name);
248
249         e = bus_label_escape(name);
250         if (!e)
251                 return NULL;
252
253         return strappend("/org/freedesktop/machine1/image/", e);
254 }
255
256 int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
257         _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
258         _cleanup_strv_free_ char **l = NULL;
259         Image *image;
260         Iterator i;
261         int r;
262
263         assert(bus);
264         assert(path);
265         assert(nodes);
266
267         images = hashmap_new(&string_hash_ops);
268         if (!images)
269                 return -ENOMEM;
270
271         r = image_discover(images);
272         if (r < 0)
273                 return r;
274
275         HASHMAP_FOREACH(image, images, i) {
276                 char *p;
277
278                 p = image_bus_path(image->name);
279                 if (!p)
280                         return -ENOMEM;
281
282                 r = strv_consume(&l, p);
283                 if (r < 0)
284                         return r;
285         }
286
287         *nodes = l;
288         l = NULL;
289
290         return 1;
291 }