]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/machine/image-dbus.c
machined: add a full bus object for images
[thirdparty/systemd.git] / src / machine / image-dbus.c
CommitLineData
ebeccf9e
LP
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 "image.h"
26
27static int image_find_by_bus_path(const char *path, Image **ret) {
28 _cleanup_free_ char *e = NULL;
29 const char *p;
30
31 assert(path);
32
33 p = startswith(path, "/org/freedesktop/machine1/image/");
34 if (!p)
35 return 0;
36
37 e = bus_label_unescape(p);
38 if (!e)
39 return -ENOMEM;
40
41 return image_find(e, ret);
42}
43
44static int image_find_by_bus_path_with_error(const char *path, Image **ret, sd_bus_error *error) {
45 int r;
46
47 assert(path);
48
49 r = image_find_by_bus_path(path, ret);
50 if (r == 0)
51 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "Image doesn't exist.");
52
53 return r;
54}
55
56static int property_get_name(
57 sd_bus *bus,
58 const char *path,
59 const char *interface,
60 const char *property,
61 sd_bus_message *reply,
62 void *userdata,
63 sd_bus_error *error) {
64
65 _cleanup_(image_unrefp) Image *image = NULL;
66 int r;
67
68 assert(bus);
69 assert(reply);
70
71 r = image_find_by_bus_path_with_error(path, &image, error);
72 if (r < 0)
73 return r;
74
75 r = sd_bus_message_append(reply, "s", image->name);
76 if (r < 0)
77 return r;
78
79 return 1;
80}
81
82static int property_get_path(
83 sd_bus *bus,
84 const char *path,
85 const char *interface,
86 const char *property,
87 sd_bus_message *reply,
88 void *userdata,
89 sd_bus_error *error) {
90
91 _cleanup_(image_unrefp) Image *image = NULL;
92 int r;
93
94 assert(bus);
95 assert(reply);
96
97 r = image_find_by_bus_path_with_error(path, &image, error);
98 if (r < 0)
99 return r;
100
101 r = sd_bus_message_append(reply, "s", image->path);
102 if (r < 0)
103 return r;
104
105 return 1;
106}
107
108static int property_get_type(
109 sd_bus *bus,
110 const char *path,
111 const char *interface,
112 const char *property,
113 sd_bus_message *reply,
114 void *userdata,
115 sd_bus_error *error) {
116
117
118 _cleanup_(image_unrefp) Image *image = NULL;
119 int r;
120
121 assert(bus);
122 assert(reply);
123
124 r = image_find_by_bus_path_with_error(path, &image, error);
125 if (r < 0)
126 return r;
127
128 r = sd_bus_message_append(reply, "s", image_type_to_string(image->type));
129 if (r < 0)
130 return r;
131
132 return 1;
133}
134
135static int property_get_read_only(
136 sd_bus *bus,
137 const char *path,
138 const char *interface,
139 const char *property,
140 sd_bus_message *reply,
141 void *userdata,
142 sd_bus_error *error) {
143
144
145 _cleanup_(image_unrefp) Image *image = NULL;
146 int r;
147
148 assert(bus);
149 assert(reply);
150
151 r = image_find_by_bus_path_with_error(path, &image, error);
152 if (r < 0)
153 return r;
154
155 r = sd_bus_message_append(reply, "b", image->read_only);
156 if (r < 0)
157 return r;
158
159 return 1;
160}
161
162const sd_bus_vtable image_vtable[] = {
163 SD_BUS_VTABLE_START(0),
164 SD_BUS_PROPERTY("Name", "s", property_get_name, 0, 0),
165 SD_BUS_PROPERTY("Path", "s", property_get_path, 0, 0),
166 SD_BUS_PROPERTY("Type", "s", property_get_type, 0, 0),
167 SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
168 SD_BUS_VTABLE_END
169};
170
171int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
172 int r;
173
174 assert(bus);
175 assert(path);
176 assert(interface);
177 assert(found);
178
179 r = image_find_by_bus_path(path, NULL);
180 if (r <= 0)
181 return r;
182
183 *found = NULL;
184 return 1;
185}
186
187char *image_bus_path(const char *name) {
188 _cleanup_free_ char *e = NULL;
189
190 assert(name);
191
192 e = bus_label_escape(name);
193 if (!e)
194 return NULL;
195
196 return strappend("/org/freedesktop/machine1/image/", e);
197}
198
199int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
200 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
201 _cleanup_strv_free_ char **l = NULL;
202 Image *image;
203 Iterator i;
204 int r;
205
206 assert(bus);
207 assert(path);
208 assert(nodes);
209
210 images = hashmap_new(&string_hash_ops);
211 if (!images)
212 return -ENOMEM;
213
214 r = image_discover(images);
215 if (r < 0)
216 return r;
217
218 HASHMAP_FOREACH(image, images, i) {
219 char *p;
220
221 p = image_bus_path(image->name);
222 if (!p)
223 return -ENOMEM;
224
225 r = strv_consume(&l, p);
226 if (r < 0)
227 return r;
228 }
229
230 *nodes = l;
231 l = NULL;
232
233 return 1;
234}