1 /*
2 * libosinfo: An installed image of a (guest) OS
3 *
4 * Copyright (C) 2018-2020 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21 #include <osinfo/osinfo.h>
22 #include <gio/gio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib/gi18n-lib.h>
26
27 /**
28 * SECTION:osinfo_image
29 * @short_description: A pre-installed image for a (guest) OS
30 * @see_also: #OsinfoOs
31 *
32 * #OsinfoImage is an entity representing an installation image
33 * a (guest) operating system.
34 */
35
36 struct _OsinfoImagePrivate
37 {
38 GWeakRef os;
39 };
40
41 G_DEFINE_TYPE_WITH_PRIVATE(OsinfoImage, osinfo_image, OSINFO_TYPE_ENTITY);
42
43 enum {
44 PROP_0,
45
46 PROP_ARCHITECTURE,
47 PROP_FORMAT,
48 PROP_URL,
49 PROP_CLOUD_INIT,
50
51 LAST_PROP
52 };
53 static GParamSpec *properties[LAST_PROP];
54
55 static void
osinfo_image_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)56 osinfo_image_get_property(GObject *object,
57 guint property_id,
58 GValue *value,
59 GParamSpec *pspec)
60 {
61 OsinfoImage *image = OSINFO_IMAGE(object);
62
63 switch (property_id) {
64 case PROP_ARCHITECTURE:
65 g_value_set_string(value, osinfo_image_get_architecture(image));
66 break;
67
68 case PROP_FORMAT:
69 g_value_set_string(value, osinfo_image_get_format(image));
70 break;
71
72 case PROP_URL:
73 g_value_set_string(value, osinfo_image_get_url(image));
74 break;
75
76 case PROP_CLOUD_INIT:
77 g_value_set_boolean(value, osinfo_image_get_cloud_init(image));
78 break;
79
80 default:
81 /* We don't have any other property... */
82 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
83 break;
84 }
85 }
86
87 static void
osinfo_image_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)88 osinfo_image_set_property(GObject *object,
89 guint property_id,
90 const GValue *value,
91 GParamSpec *pspec)
92 {
93 OsinfoImage *image = OSINFO_IMAGE(object);
94
95 switch (property_id) {
96 case PROP_ARCHITECTURE:
97 osinfo_entity_set_param(OSINFO_ENTITY(image),
98 OSINFO_IMAGE_PROP_ARCHITECTURE,
99 g_value_get_string(value));
100 break;
101
102 case PROP_FORMAT:
103 osinfo_entity_set_param(OSINFO_ENTITY(image),
104 OSINFO_IMAGE_PROP_FORMAT,
105 g_value_get_string(value));
106 break;
107
108 case PROP_URL:
109 osinfo_entity_set_param(OSINFO_ENTITY(image),
110 OSINFO_IMAGE_PROP_URL,
111 g_value_get_string(value));
112 break;
113
114 case PROP_CLOUD_INIT:
115 osinfo_entity_set_param_boolean(OSINFO_ENTITY(image),
116 OSINFO_IMAGE_PROP_CLOUD_INIT,
117 g_value_get_boolean(value));
118 break;
119
120 default:
121 /* We don't have any other property... */
122 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
123 break;
124 }
125 }
126
osinfo_image_dispose(GObject * obj)127 static void osinfo_image_dispose(GObject *obj)
128 {
129 OsinfoImage *image = OSINFO_IMAGE(obj);
130
131 g_weak_ref_clear(&image->priv->os);
132
133 G_OBJECT_CLASS(osinfo_image_parent_class)->dispose(obj);
134 }
135
136 static void
osinfo_image_finalize(GObject * object)137 osinfo_image_finalize(GObject *object)
138 {
139 /* Chain up to the parent class */
140 G_OBJECT_CLASS(osinfo_image_parent_class)->finalize(object);
141 }
142
143 /* Init functions */
144 static void
osinfo_image_class_init(OsinfoImageClass * klass)145 osinfo_image_class_init(OsinfoImageClass *klass)
146 {
147 GObjectClass *g_klass = G_OBJECT_CLASS(klass);
148
149 g_klass->dispose = osinfo_image_dispose;
150 g_klass->finalize = osinfo_image_finalize;
151 g_klass->get_property = osinfo_image_get_property;
152 g_klass->set_property = osinfo_image_set_property;
153
154 /**
155 * OsinfoImage:architecture:
156 *
157 * The target hardware architecture of this image.
158 */
159 properties[PROP_ARCHITECTURE] = g_param_spec_string("architecture",
160 "ARCHITECTURE",
161 _("CPU Architecture"),
162 NULL /* default value */,
163 G_PARAM_READWRITE |
164 G_PARAM_STATIC_STRINGS);
165
166 /**
167 * OsinfoImage:format:
168 *
169 * The image format.
170 */
171 properties[PROP_FORMAT] = g_param_spec_string("format",
172 "FORMAT",
173 _("The image format"),
174 NULL /* default value */,
175 G_PARAM_READWRITE |
176 G_PARAM_STATIC_STRINGS);
177
178 /**
179 * OsinfoImage:url:
180 *
181 * The URL to this image.
182 */
183 properties[PROP_URL] = g_param_spec_string("url",
184 "URL",
185 _("The URL to this image"),
186 NULL /* default value */,
187 G_PARAM_READWRITE |
188 G_PARAM_STATIC_STRINGS);
189
190 /**
191 * OsinfoImage:cloud-init:
192 *
193 * Whether the image supports cloud-init customizations or not.
194 */
195 properties[PROP_CLOUD_INIT] = g_param_spec_string("cloud-init",
196 "CloudInit",
197 _("Whether cloud-init customizations are supported or not"),
198 FALSE /* default value */,
199 G_PARAM_READWRITE |
200 G_PARAM_STATIC_STRINGS);
201
202 g_object_class_install_properties(g_klass, LAST_PROP, properties);
203 }
204
205 static void
osinfo_image_init(OsinfoImage * image)206 osinfo_image_init(OsinfoImage *image)
207 {
208 image->priv = osinfo_image_get_instance_private(image);
209
210 g_weak_ref_init(&image->priv->os, NULL);
211 }
212
osinfo_image_new(const gchar * id,const gchar * architecture,const gchar * format)213 OsinfoImage *osinfo_image_new(const gchar *id,
214 const gchar *architecture,
215 const gchar *format)
216 {
217 OsinfoImage *image;
218
219 image = g_object_new(OSINFO_TYPE_IMAGE,
220 "id", id,
221 OSINFO_IMAGE_PROP_ARCHITECTURE, architecture,
222 OSINFO_IMAGE_PROP_FORMAT, format,
223 NULL);
224
225 return image;
226 }
227
228 /**
229 * osinfo_image_get_architecture:
230 * @image: an #OsinfoImage instance
231 *
232 * Retrieves the target hardware architecture of the OS @image provides.
233 *
234 * Returns: (transfer none): the hardware architecture, or NULL
235 *
236 * Since: 1.3.0
237 */
osinfo_image_get_architecture(OsinfoImage * image)238 const gchar *osinfo_image_get_architecture(OsinfoImage *image)
239 {
240 return osinfo_entity_get_param_value(OSINFO_ENTITY(image),
241 OSINFO_IMAGE_PROP_ARCHITECTURE);
242 }
243
244 /**
245 * osinfo_image_get_format:
246 * @image: an #OsinfoImage instance
247 *
248 * The format of the @image
249 *
250 * Returns: (transfer none): the format, or NULL
251 *
252 * Since: 1.3.0
253 */
osinfo_image_get_format(OsinfoImage * image)254 const gchar *osinfo_image_get_format(OsinfoImage *image)
255 {
256 return osinfo_entity_get_param_value(OSINFO_ENTITY(image),
257 OSINFO_IMAGE_PROP_FORMAT);
258 }
259
260 /**
261 * osinfo_image_get_url:
262 * @image: an #OsinfoImage instance
263 *
264 * The URL to the @image
265 *
266 * Returns: (transfer none): the URL, or NULL
267 *
268 * Since: 1.3.0
269 */
osinfo_image_get_url(OsinfoImage * image)270 const gchar *osinfo_image_get_url(OsinfoImage *image)
271 {
272 return osinfo_entity_get_param_value(OSINFO_ENTITY(image),
273 OSINFO_IMAGE_PROP_URL);
274 }
275
276 /**
277 * osinfo_image_get_cloud_init:
278 * @image: an #OsinfoImage instance
279 *
280 * Whether @image supports cloud init customizations
281 *
282 * Returns: #TRUE if @image supports cloud init customizations, #FALSE
283 * otherwise.
284 *
285 * Since: 1.3.0
286 */
osinfo_image_get_cloud_init(OsinfoImage * image)287 gboolean osinfo_image_get_cloud_init(OsinfoImage *image)
288 {
289 return osinfo_entity_get_param_value_boolean_with_default
290 (OSINFO_ENTITY(image), OSINFO_IMAGE_PROP_CLOUD_INIT, FALSE);
291 }
292
293 /**
294 * osinfo_image_get_os:
295 * @image: an #OsinfoImage instance
296 *
297 * Returns: (transfer full): the operating system, or NULL
298 *
299 * Since: 1.5.0
300 */
osinfo_image_get_os(OsinfoImage * image)301 OsinfoOs *osinfo_image_get_os(OsinfoImage *image)
302 {
303 g_return_val_if_fail(OSINFO_IS_IMAGE(image), NULL);
304
305 return g_weak_ref_get(&image->priv->os);
306 }
307
308 /**
309 * osinfo_image_set_os
310 * @image: an #OsinfoImage instance
311 * @os: an #OsinfoOs instance
312 *
313 * Sets the #OsinfoOs associated to the #OsinfoImage instance.
314 *
315 * Since: 1.5.0
316 */
osinfo_image_set_os(OsinfoImage * image,OsinfoOs * os)317 void osinfo_image_set_os(OsinfoImage *image, OsinfoOs *os)
318 {
319 g_return_if_fail(OSINFO_IS_IMAGE(image));
320
321 g_object_ref(os);
322 g_weak_ref_set(&image->priv->os, os);
323 g_object_unref(os);
324 }
325
326 /**
327 * osinfo_image_get_os_variants:
328 * @image: an #OsinfoImage instance
329 *
330 * Gets the varriants of the associated operating system
331 *
332 * Returns: (transfer full): the operating system variants, or NULL
333 *
334 * Since: 1.5.0
335 */
osinfo_image_get_os_variants(OsinfoImage * image)336 OsinfoOsVariantList *osinfo_image_get_os_variants(OsinfoImage *image)
337 {
338 OsinfoOs *os;
339 OsinfoOsVariantList *os_variants;
340 OsinfoOsVariantList *image_variants;
341 GList *ids, *node;
342 OsinfoFilter *filter;
343
344 g_return_val_if_fail(OSINFO_IS_IMAGE(image), NULL);
345
346 os = osinfo_image_get_os(image);
347 if (os == NULL)
348 return NULL;
349
350 os_variants = osinfo_os_get_variant_list(os);
351 g_object_unref(os);
352
353 ids = osinfo_entity_get_param_value_list(OSINFO_ENTITY(image),
354 OSINFO_IMAGE_PROP_VARIANT);
355 filter = osinfo_filter_new();
356 image_variants = osinfo_os_variantlist_new();
357 for (node = ids; node != NULL; node = node->next) {
358 osinfo_filter_clear_constraints(filter);
359 osinfo_filter_add_constraint(filter,
360 OSINFO_ENTITY_PROP_ID,
361 (const char *) node->data);
362 osinfo_list_add_filtered(OSINFO_LIST(image_variants),
363 OSINFO_LIST(os_variants),
364 filter);
365 }
366 g_object_unref(os_variants);
367
368 return image_variants;
369 }
370