1 /*
2 * libosinfo:
3 *
4 * Copyright (C) 2009-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 <string.h>
23 #include <libxml/tree.h>
24 #include <libxslt/transform.h>
25 #include <libxslt/xsltutils.h>
26 #include <libxslt/xsltInternals.h>
27 #include <glib/gi18n-lib.h>
28 #include "osinfo_install_script_private.h"
29
30 /**
31 * SECTION:osinfo_install_script
32 * @short_description: OS install script generation
33 * @see_also: #OsinfoInstallConfig
34 *
35 * #OsinfoInstallScript is an object used to generate an
36 * automated installation script for an OS. The OS
37 * configuration data (language, keyboard, timezone, ...)
38 * comes from an #OsinfoInstallConfig object.
39 */
40
41 struct _OsinfoInstallScriptPrivate
42 {
43 gchar *output_prefix;
44 gchar *output_filename;
45 OsinfoInstallConfigParamList *config_params;
46 OsinfoAvatarFormat *avatar;
47 };
48
49 G_DEFINE_TYPE_WITH_PRIVATE(OsinfoInstallScript, osinfo_install_script, OSINFO_TYPE_ENTITY);
50
51 enum {
52 PROP_0,
53
54 PROP_TEMPLATE_URI,
55 PROP_TEMPLATE_DATA,
56 PROP_PROFILE,
57 PROP_PRODUCT_KEY_FORMAT,
58 PROP_PATH_FORMAT,
59 PROP_AVATAR_FORMAT,
60 PROP_PREFERRED_INJECTION_METHOD,
61 PROP_INSTALLATION_SOURCE,
62
63 LAST_PROP
64 };
65 static GParamSpec *properties[LAST_PROP];
66
67 typedef struct _OsinfoInstallScriptGenerateData OsinfoInstallScriptGenerateData;
68 typedef struct _OsinfoInstallScriptGenerateOutputData OsinfoInstallScriptGenerateOutputData;
69 typedef struct _OsinfoInstallScriptGenerateSyncData OsinfoInstallScriptGenerateSyncData;
70
71
72 static void
osinfo_install_script_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)73 osinfo_install_script_set_property(GObject *object,
74 guint property_id,
75 const GValue *value,
76 GParamSpec *pspec)
77 {
78 OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object);
79 const gchar *data;
80
81 switch (property_id) {
82 case PROP_TEMPLATE_URI:
83 data = g_value_get_string(value);
84 if (data)
85 osinfo_entity_set_param(OSINFO_ENTITY(script),
86 OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_URI,
87 data);
88 break;
89
90 case PROP_TEMPLATE_DATA:
91 data = g_value_get_string(value);
92 if (data)
93 osinfo_entity_set_param(OSINFO_ENTITY(script),
94 OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA,
95 data);
96 break;
97
98 case PROP_PROFILE:
99 data = g_value_get_string(value);
100 if (data)
101 osinfo_entity_set_param(OSINFO_ENTITY(script),
102 OSINFO_INSTALL_SCRIPT_PROP_PROFILE,
103 data);
104 break;
105
106 case PROP_PREFERRED_INJECTION_METHOD:
107 osinfo_install_script_set_preferred_injection_method(script,
108 g_value_get_flags(value));
109 break;
110
111 case PROP_INSTALLATION_SOURCE:
112 osinfo_install_script_set_installation_source(script,
113 g_value_get_enum(value));
114 break;
115
116 default:
117 /* We don't have any other property... */
118 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
119 break;
120 }
121 }
122
123 static void
osinfo_install_script_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)124 osinfo_install_script_get_property(GObject *object,
125 guint property_id,
126 GValue *value,
127 GParamSpec *pspec)
128 {
129 OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object);
130
131 switch (property_id) {
132 case PROP_TEMPLATE_URI:
133 g_value_set_string(value,
134 osinfo_install_script_get_template_uri(script));
135 break;
136
137 case PROP_TEMPLATE_DATA:
138 g_value_set_string(value,
139 osinfo_install_script_get_template_data(script));
140 break;
141
142 case PROP_PROFILE:
143 g_value_set_string(value,
144 osinfo_install_script_get_profile(script));
145 break;
146
147 case PROP_PRODUCT_KEY_FORMAT:
148 g_value_set_string(value,
149 osinfo_install_script_get_product_key_format(script));
150 break;
151
152 case PROP_PATH_FORMAT:
153 g_value_set_enum(value,
154 osinfo_install_script_get_path_format(script));
155 break;
156
157 case PROP_AVATAR_FORMAT:
158 g_value_set_object(value,
159 osinfo_install_script_get_avatar_format(script));
160 break;
161
162 case PROP_PREFERRED_INJECTION_METHOD:
163 g_value_set_flags(value,
164 osinfo_install_script_get_preferred_injection_method(script));
165 break;
166
167 case PROP_INSTALLATION_SOURCE:
168 g_value_set_enum(value,
169 osinfo_install_script_get_installation_source(script));
170 break;
171
172 default:
173 /* We don't have any other property... */
174 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
175 break;
176 }
177 }
178
179
180 static void
osinfo_install_script_finalize(GObject * object)181 osinfo_install_script_finalize(GObject *object)
182 {
183 OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object);
184 g_free(script->priv->output_prefix);
185 g_free(script->priv->output_filename);
186
187 if (script->priv->config_params)
188 g_object_unref(script->priv->config_params);
189
190 if (script->priv->avatar)
191 g_object_unref(script->priv->avatar);
192
193 /* Chain up to the parent class */
194 G_OBJECT_CLASS(osinfo_install_script_parent_class)->finalize(object);
195 }
196
197 /* Init functions */
198 static void
osinfo_install_script_class_init(OsinfoInstallScriptClass * klass)199 osinfo_install_script_class_init(OsinfoInstallScriptClass *klass)
200 {
201 GObjectClass *g_klass = G_OBJECT_CLASS(klass);
202
203 g_klass->get_property = osinfo_install_script_get_property;
204 g_klass->set_property = osinfo_install_script_set_property;
205 g_klass->finalize = osinfo_install_script_finalize;
206
207 properties[PROP_TEMPLATE_URI] = g_param_spec_string("template-uri",
208 "TemplateURI",
209 _("URI for install script template"),
210 NULL /* default value */,
211 G_PARAM_READABLE |
212 G_PARAM_WRITABLE |
213 G_PARAM_CONSTRUCT_ONLY |
214 G_PARAM_STATIC_STRINGS);
215
216 properties[PROP_TEMPLATE_DATA] = g_param_spec_string("template-data",
217 "TemplateData",
218 _("Data for install script template"),
219 NULL /* default value */,
220 G_PARAM_READABLE |
221 G_PARAM_WRITABLE |
222 G_PARAM_CONSTRUCT_ONLY |
223 G_PARAM_STATIC_STRINGS);
224
225 properties[PROP_PROFILE] = g_param_spec_string("profile",
226 "Profile",
227 _("Install script profile name"),
228 NULL /* default value */,
229 G_PARAM_READABLE |
230 G_PARAM_WRITABLE |
231 G_PARAM_CONSTRUCT_ONLY |
232 G_PARAM_STATIC_STRINGS);
233
234 properties[PROP_PRODUCT_KEY_FORMAT] = g_param_spec_string("product-key-format",
235 "Product Key Format",
236 _("Product key format mask"),
237 NULL /* default value */,
238 G_PARAM_READABLE |
239 G_PARAM_STATIC_STRINGS);
240
241 properties[PROP_PATH_FORMAT] = g_param_spec_enum("path-format",
242 "Path Format",
243 _("Expected path format"),
244 OSINFO_TYPE_PATH_FORMAT,
245 OSINFO_PATH_FORMAT_UNIX /* default value */,
246 G_PARAM_READABLE |
247 G_PARAM_STATIC_STRINGS);
248
249 properties[PROP_AVATAR_FORMAT] = g_param_spec_object("avatar-format",
250 "Avatar Format",
251 _("Expected avatar format"),
252 OSINFO_TYPE_AVATAR_FORMAT,
253 G_PARAM_READABLE |
254 G_PARAM_STATIC_STRINGS);
255
256 properties[PROP_PREFERRED_INJECTION_METHOD] = g_param_spec_flags("preferred-injection-method",
257 "Preferred Injection Method",
258 _("The preferred injection method"),
259 OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD,
260 OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK, /* default value */
261 G_PARAM_READABLE |
262 G_PARAM_WRITABLE |
263 G_PARAM_STATIC_STRINGS);
264
265 properties[PROP_INSTALLATION_SOURCE] = g_param_spec_enum("installation-source",
266 "Installation Source",
267 _("The installation source to be used"),
268 OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE,
269 OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA,
270 G_PARAM_READABLE |
271 G_PARAM_STATIC_STRINGS);
272
273 g_object_class_install_properties(g_klass, LAST_PROP, properties);
274 }
275
osinfo_install_script_add_config_param(OsinfoInstallScript * script,OsinfoInstallConfigParam * param)276 void osinfo_install_script_add_config_param(OsinfoInstallScript *script, OsinfoInstallConfigParam *param)
277 {
278 g_return_if_fail(OSINFO_IS_INSTALL_SCRIPT(script));
279 g_return_if_fail(OSINFO_IS_INSTALL_CONFIG_PARAM(param));
280
281 osinfo_list_add(OSINFO_LIST(script->priv->config_params),
282 OSINFO_ENTITY(param));
283 }
284
285 /**
286 * osinfo_install_script_has_config_param:
287 * @script: the install script
288 * @config_param: an #OsinfoInstallConfigParam
289 *
290 * Returns whether the @script has the @config_param searched or not.
291 *
292 * This code assumes that the 'id' and 'name' entity properties are the same.
293 *
294 * Since: 0.2.0
295 */
osinfo_install_script_has_config_param(OsinfoInstallScript * script,OsinfoInstallConfigParam * config_param)296 gboolean osinfo_install_script_has_config_param(OsinfoInstallScript *script, OsinfoInstallConfigParam *config_param)
297 {
298 const char *name = osinfo_install_config_param_get_name(config_param);
299 return osinfo_install_script_has_config_param_name(script, name);
300 }
301
302 /**
303 * osinfo_install_script_has_config_param_name:
304 * @script: the install script
305 * @name: the configuration parameter name
306 *
307 * Returns whether the @script has a configuration parameter matching @name or not.
308 *
309 * Since: 0.2.0
310 */
osinfo_install_script_has_config_param_name(OsinfoInstallScript * script,const gchar * name)311 gboolean osinfo_install_script_has_config_param_name(OsinfoInstallScript *script, const gchar *name)
312 {
313 OsinfoList *l = OSINFO_LIST(script->priv->config_params);
314 return (osinfo_list_find_by_id(l, name) != NULL);
315 }
316
317 /**
318 * osinfo_install_script_get_config_param_list:
319 * @script: the install script
320 *
321 * Get the list of valid config parameters for @script.
322 *
323 * Returns: (transfer container) (element-type OsinfoInstallScript): the
324 * list of valid #OsinfoInstallConfigParam parameters. Free with
325 * g_list_free() when done. The elements are owned by libosinfo.
326 *
327 * Since: 0.2.0
328 */
osinfo_install_script_get_config_param_list(OsinfoInstallScript * script)329 GList *osinfo_install_script_get_config_param_list(OsinfoInstallScript *script)
330 {
331 return osinfo_list_get_elements(OSINFO_LIST(script->priv->config_params));
332 }
333
334 /**
335 * osinfo_install_script_get_config_params:
336 * @script: the install script
337 *
338 * Get the list of valid config parameters for @script.
339 *
340 * Returns: (transfer none): the list of valid #OsinfoInstallConfigParam
341 * parameters.
342 *
343 * Since: 0.2.3
344 */
osinfo_install_script_get_config_params(OsinfoInstallScript * script)345 OsinfoInstallConfigParamList *osinfo_install_script_get_config_params(OsinfoInstallScript *script)
346 {
347 return script->priv->config_params;
348 }
349
350 /**
351 * osinfo_install_script_get_config_param:
352 * @script: the install script
353 * @name: name of the parameter
354 *
355 * Get a config param from the config param's list
356 *
357 * Returns: (transfer full): the sought config param, if exists.
358 * NULL otherwise.
359 *
360 * This code assumes that the 'id' and 'name' entity properties are
361 * the same.
362 *
363 * Since: 0.2.1
364 */
365 OsinfoInstallConfigParam *
osinfo_install_script_get_config_param(OsinfoInstallScript * script,const gchar * name)366 osinfo_install_script_get_config_param(OsinfoInstallScript *script,
367 const gchar *name)
368 {
369 OsinfoInstallConfigParam *param;
370 OsinfoList *l = OSINFO_LIST(script->priv->config_params);
371 param = OSINFO_INSTALL_CONFIG_PARAM(osinfo_list_find_by_id(l, name));
372 if (param == NULL)
373 return NULL;
374
375 return g_object_ref(G_OBJECT(param));
376 }
377
378 static void
osinfo_install_script_init(OsinfoInstallScript * list)379 osinfo_install_script_init(OsinfoInstallScript *list)
380 {
381 list->priv = osinfo_install_script_get_instance_private(list);
382 list->priv->config_params = osinfo_install_config_paramlist_new();
383 }
384
385
386 /**
387 * oisinfo_install_script_new:
388 * @id: a unique identifier
389 *
390 * Construct an empty new install script.
391 *
392 * Returns: (transfer full): a new install script
393 *
394 * Since: 0.2.0
395 */
osinfo_install_script_new(const gchar * id)396 OsinfoInstallScript *osinfo_install_script_new(const gchar *id)
397 {
398 return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT,
399 "id", id,
400 NULL);
401 }
402
403 /**
404 * osinfo_install_script_new_data:
405 * @id: a unique identifier
406 * @profile: the profile of script
407 * @templateData: style sheet data
408 *
409 * Construct a new install script from stylesheet data
410 *
411 * Returns: (transfer full): an new install script
412 *
413 * Since: 0.2.0
414 */
osinfo_install_script_new_data(const gchar * id,const gchar * profile,const gchar * templateData)415 OsinfoInstallScript *osinfo_install_script_new_data(const gchar *id,
416 const gchar *profile,
417 const gchar *templateData)
418 {
419 return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT,
420 "id", id,
421 "profile", profile,
422 "template-data", templateData,
423 NULL);
424 }
425
426
427 /**
428 * osinfo_install_script_new_uri:
429 * @id: a unique identifier
430 * @profile: the profile of script
431 * @templateUri: style sheet URI
432 *
433 * Construct a new install script from a stylesheet URI
434 *
435 * Returns: (transfer full): an new install script
436 *
437 * Since: 0.2.0
438 */
osinfo_install_script_new_uri(const gchar * id,const gchar * profile,const gchar * templateUri)439 OsinfoInstallScript *osinfo_install_script_new_uri(const gchar *id,
440 const gchar *profile,
441 const gchar *templateUri)
442 {
443 return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT,
444 "id", id,
445 "profile", profile,
446 "template-uri", templateUri,
447 NULL);
448 }
449
450
451 /**
452 * osinfo_install_script_get_template_uri:
453 * @script: the install script
454 *
455 * Returns the stylesheet URI used to construct the install script.
456 *
457 * Since: 0.2.0
458 */
osinfo_install_script_get_template_uri(OsinfoInstallScript * script)459 const gchar *osinfo_install_script_get_template_uri(OsinfoInstallScript *script)
460 {
461 return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
462 OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_URI);
463 }
464
465 /**
466 * osinfo_install_script_get_template_data:
467 * @script: the install script
468 *
469 * Returns the stylesheet data used to construct the install script.
470 *
471 * Since: 0.2.0
472 */
osinfo_install_script_get_template_data(OsinfoInstallScript * script)473 const gchar *osinfo_install_script_get_template_data(OsinfoInstallScript *script)
474 {
475 return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
476 OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA);
477 }
478
479 /**
480 * osinfo_install_script_get_profile:
481 * @script: the install script
482 *
483 * Returns a string representing the install script profile that's going to be
484 * used.
485 *
486 * The values supported are "jeos" for minimal installations and "desktop" for
487 * workstation/desktop installations.
488 *
489 * Since: 0.2.0
490 */
osinfo_install_script_get_profile(OsinfoInstallScript * script)491 const gchar *osinfo_install_script_get_profile(OsinfoInstallScript *script)
492 {
493 return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
494 OSINFO_INSTALL_SCRIPT_PROP_PROFILE);
495 }
496
497 /**
498 * osinfo_install_script_get_product_key_format:
499 * @script: the install script
500 *
501 * If this function returns a non-NULL string, it means that the @script
502 * requires you to specify product registration key through #OsinfoInstallConfig
503 * instance passed to script generation methods.
504 *
505 * The returned string specifies the expected format of the product key like this:
506 *
507 * @ - any character
508 * % - alphabet
509 * # - numeric character
510 * $ - alphanumeric character
511 *
512 * All other characters represent themselves.
513 *
514 * For example in case of installer for Microsoft Windows XP, you'll get
515 * "$$$$$-$$$$$-$$$$$-$$$$$-$$$$$". That means a product key consists of 24
516 * alphanumeric characters and 4 '-' characters at (0-based) indices 5, 11, 17
517 * and 23.
518 *
519 * Returns: (transfer none): Product key format mask, or NULL.
520 *
521 * Since: 0.2.2
522 */
osinfo_install_script_get_product_key_format(OsinfoInstallScript * script)523 const gchar *osinfo_install_script_get_product_key_format(OsinfoInstallScript *script)
524 {
525 return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
526 OSINFO_INSTALL_SCRIPT_PROP_PRODUCT_KEY_FORMAT);
527 }
528
529 /**
530 * osinfo_install_script_set_output_prefix:
531 * @script: the install script
532 * @prefix: a prefix to be added to the file generated
533 *
534 * Mind that not all installers support any name for the installer scripts.
535 *
536 * Since: 0.2.0
537 */
osinfo_install_script_set_output_prefix(OsinfoInstallScript * script,const gchar * prefix)538 void osinfo_install_script_set_output_prefix(OsinfoInstallScript *script,
539 const gchar *prefix)
540 {
541 const char *output_filename =
542 osinfo_install_script_get_expected_filename(script);
543
544 g_free(script->priv->output_prefix);
545 script->priv->output_prefix = g_strdup(prefix);
546
547 /* update output_filename whenever output_prefix is changed */
548 g_free(script->priv->output_filename);
549 script->priv->output_filename = g_strjoin("-",
550 prefix,
551 output_filename,
552 NULL);
553 }
554
555 /**
556 * osinfo_install_script_get_output_prefix:
557 * @script: the install script
558 *
559 * Returns: the prefix of the file generated
560 *
561 * Since: 0.2.8
562 */
osinfo_install_script_get_output_prefix(OsinfoInstallScript * script)563 const gchar *osinfo_install_script_get_output_prefix(OsinfoInstallScript *script)
564 {
565 return script->priv->output_prefix;
566 }
567
568 /**
569 * osinfo_install_script_get_expected_filename:
570 * @script: the install script
571 *
572 * Some operating systems (as Windows) expect that script filename has
573 * particular name to work.
574 *
575 * Returns: (transfer none): the expected script filename
576 *
577 * Since: 0.2.1
578 */
osinfo_install_script_get_expected_filename(OsinfoInstallScript * script)579 const gchar *osinfo_install_script_get_expected_filename(OsinfoInstallScript *script)
580 {
581 return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
582 OSINFO_INSTALL_SCRIPT_PROP_EXPECTED_FILENAME);
583 }
584
585 /**
586 * osinfo_install_script_get_output_filename:
587 * @script: the install script
588 *
589 * Some operating systems are able to use any script filename, allowing the
590 * application to set the filename as desired. libosinfo provides this
591 * functionality by set the expected filename's prefix using
592 * osinfo_install_script_set_output_prefix() function.
593 *
594 * Returns: (transfer none): the output script filename
595 *
596 * Since: 0.2.0
597 */
osinfo_install_script_get_output_filename(OsinfoInstallScript * script)598 const gchar *osinfo_install_script_get_output_filename(OsinfoInstallScript *script)
599 {
600 if (script->priv->output_filename == NULL)
601 return osinfo_install_script_get_expected_filename(script);
602
603 return script->priv->output_filename;
604 }
605
606 void
osinfo_install_script_set_avatar_format(OsinfoInstallScript * script,OsinfoAvatarFormat * avatar)607 osinfo_install_script_set_avatar_format(OsinfoInstallScript *script,
608 OsinfoAvatarFormat *avatar)
609 {
610 g_return_if_fail(OSINFO_IS_INSTALL_SCRIPT(script));
611 g_return_if_fail(OSINFO_IS_AVATAR_FORMAT(avatar));
612
613 if (script->priv->avatar != NULL)
614 g_object_unref(script->priv->avatar);
615 script->priv->avatar = g_object_ref(avatar);
616 }
617
618 /**
619 * osinfo_install_script_get_avatar_format:
620 * @script: the install script
621 *
622 * Some install scripts have restrictions on the format of the user avatar. Use
623 * this method to retrieve those restrictions in the form of an
624 * #OsinfoAvatarFormat instance.
625 *
626 * Returns: (transfer none): The avatar format, or NULL if there is no restrictions on the
627 * format of avatar
628 *
629 * Since: 0.2.2
630 */
osinfo_install_script_get_avatar_format(OsinfoInstallScript * script)631 OsinfoAvatarFormat *osinfo_install_script_get_avatar_format(OsinfoInstallScript *script)
632 {
633 g_return_val_if_fail(OSINFO_IS_INSTALL_SCRIPT(script), NULL);
634
635 if (script->priv->avatar == NULL)
636 return NULL;
637
638 return script->priv->avatar;
639 }
640
641 struct _OsinfoInstallScriptGenerateData {
642 GTask *res;
643 OsinfoOs *os;
644 OsinfoMedia *media;
645 OsinfoTree *tree;
646 OsinfoInstallConfig *config;
647 OsinfoInstallScript *script;
648 };
649
650
osinfo_install_script_generate_data_free(OsinfoInstallScriptGenerateData * data)651 static void osinfo_install_script_generate_data_free(OsinfoInstallScriptGenerateData *data)
652 {
653 g_object_unref(data->os);
654 if (data->media != NULL)
655 g_object_unref(data->media);
656 if (data->tree != NULL)
657 g_object_unref(data->tree);
658 g_object_unref(data->config);
659 g_object_unref(data->script);
660 g_object_unref(data->res);
661 g_free(data);
662 }
663
664 struct _OsinfoInstallScriptGenerateOutputData {
665 GTask *res;
666 GError *error;
667 GFile *file;
668 GFileOutputStream *stream;
669 gchar *output;
670 gssize output_len;
671 gssize output_pos;
672 };
673
osinfo_install_script_generate_output_data_free(OsinfoInstallScriptGenerateOutputData * data)674 static void osinfo_install_script_generate_output_data_free(OsinfoInstallScriptGenerateOutputData *data)
675 {
676 g_object_unref(data->stream);
677 g_object_unref(data->res);
678 g_free(data);
679 }
680
681
osinfo_install_script_load_template(const gchar * uri,const gchar * template,GError ** error)682 static xsltStylesheetPtr osinfo_install_script_load_template(const gchar *uri,
683 const gchar *template,
684 GError **error)
685 {
686 xsltStylesheetPtr xslt = NULL;
687 xmlDocPtr doc = NULL;
688 xmlParserCtxtPtr pctxt;
689
690 /* Set up a parser context so we can catch the details of XML errors. */
691 pctxt = xmlNewParserCtxt();
692 if (!pctxt || !pctxt->sax) {
693 g_set_error_literal(error, OSINFO_ERROR, 0,
694 _("Unable to create XML parser context"));
695 goto cleanup;
696 }
697
698 if (!(doc = xmlCtxtReadDoc(pctxt, BAD_CAST template, uri, NULL,
699 XML_PARSE_NONET |
700 XML_PARSE_NOWARNING))) {
701 g_set_error_literal(error, OSINFO_ERROR, 0,
702 _("Unable to read XSL template"));
703 goto cleanup;
704 }
705
706 if (!(xslt = xsltParseStylesheetDoc(doc))) {
707 g_set_error_literal(error, OSINFO_ERROR, 0,
708 _("Unable to parse XSL template"));
709 goto cleanup;
710 }
711
712 cleanup:
713 xmlFreeParserCtxt(pctxt);
714 return xslt;
715 }
716
717
718 static OsinfoDatamap *
osinfo_install_script_get_param_datamap(OsinfoInstallScript * script,const gchar * param_name)719 osinfo_install_script_get_param_datamap(OsinfoInstallScript *script,
720 const gchar *param_name)
721 {
722 OsinfoEntity *entity;
723 OsinfoInstallConfigParam *param;
724
725 if (!script->priv->config_params)
726 return NULL;
727
728 entity = osinfo_list_find_by_id(OSINFO_LIST(script->priv->config_params),
729 param_name);
730 if (entity == NULL) {
731 g_debug("%s is not a known parameter for this config", param_name);
732 return NULL;
733 }
734
735 param = OSINFO_INSTALL_CONFIG_PARAM(entity);
736 return osinfo_install_config_param_get_value_map(param);
737 }
738
739
740 static GList *
osinfo_install_script_get_param_value_list(OsinfoInstallScript * script,OsinfoInstallConfig * config,const gchar * key)741 osinfo_install_script_get_param_value_list(OsinfoInstallScript *script,
742 OsinfoInstallConfig *config,
743 const gchar *key)
744 {
745 GList *values;
746 GList *it;
747 OsinfoDatamap *map;
748
749 values = osinfo_entity_get_param_value_list(OSINFO_ENTITY(config), key);
750 if (values == NULL)
751 return NULL;
752
753 map = osinfo_install_script_get_param_datamap(script, key);
754 if (map != NULL) {
755 for (it = values; it != NULL; it = it->next) {
756 const char *transformed_value;
757 transformed_value = osinfo_datamap_lookup(map, it->data);
758 if (transformed_value == NULL) {
759 continue;
760 }
761 it->data = (gpointer)transformed_value;
762 }
763 }
764
765 return values;
766 }
767
768 static void propagate_libxml_error(GError **error, const char *format, ...) G_GNUC_PRINTF(2, 3);
769
propagate_libxml_error(GError ** error,const char * format,...)770 static void propagate_libxml_error(GError **error, const char *format, ...)
771 {
772 xmlErrorPtr err = xmlGetLastError();
773 char *prefix;
774 va_list ap;
775
776 va_start(ap, format);
777 prefix = g_strdup_vprintf(format, ap);
778 va_end(ap);
779
780 if (err == NULL) {
781 g_set_error_literal(error, OSINFO_ERROR, 0, prefix);
782 } else {
783 g_set_error(error, OSINFO_ERROR, 0, "%s: %s", prefix, err->message);
784 }
785 g_free(prefix);
786 }
787
osinfo_install_script_generate_entity_xml(OsinfoInstallScript * script,OsinfoEntity * entity,const gchar * name,GError ** error)788 static xmlNodePtr osinfo_install_script_generate_entity_xml(OsinfoInstallScript *script,
789 OsinfoEntity *entity,
790 const gchar *name,
791 GError **error)
792 {
793 xmlNodePtr node = NULL;
794 xmlNodePtr data = NULL;
795 GList *keys = NULL;
796 GList *tmp1;
797
798 if (!(node = xmlNewDocNode(NULL, NULL, (xmlChar*)name, NULL))) {
799 propagate_libxml_error(error, _("Unable to create XML node '%s'"), name);
800 goto error;
801 }
802
803 if (!(data = xmlNewDocRawNode(NULL, NULL, (const xmlChar*)"id",
804 (const xmlChar*)osinfo_entity_get_id(entity)))) {
805 propagate_libxml_error(error, _("Unable to create XML node 'id'"));
806 goto error;
807 }
808 if (!(xmlAddChild(node, data))) {
809 propagate_libxml_error(error, _("Unable to add XML child"));
810 goto error;
811 }
812 data = NULL;
813
814 tmp1 = keys = osinfo_entity_get_param_keys(entity);
815 while (tmp1) {
816 GList *values;
817 GList *tmp2;
818
819 if (OSINFO_IS_INSTALL_CONFIG(entity))
820 values = osinfo_install_script_get_param_value_list(script,
821 OSINFO_INSTALL_CONFIG(entity),
822 tmp1->data);
823 else
824 values = osinfo_entity_get_param_value_list(entity, tmp1->data);
825
826 tmp2 = values;
827 while (tmp2) {
828 if (!(data = xmlNewDocRawNode(NULL, NULL, (const xmlChar*)tmp1->data,
829 (const xmlChar*)tmp2->data))) {
830 propagate_libxml_error(error, _("Unable to create XML node '%s'"),
831 (const gchar *)tmp1->data);
832 goto error;
833 }
834 if (!(xmlAddChild(node, data))) {
835 propagate_libxml_error(error, _("Unable to add XML child"));
836 goto error;
837 }
838 data = NULL;
839
840 tmp2 = tmp2->next;
841 }
842 g_list_free(values);
843
844 tmp1 = tmp1->next;
845 }
846 g_list_free(keys);
847
848 return node;
849
850 error:
851 g_list_free(keys);
852 xmlFreeNode(data);
853 xmlFreeNode(node);
854 return NULL;
855 }
856
857
osinfo_install_script_generate_config_xml(OsinfoInstallScript * script,OsinfoOs * os,OsinfoMedia * media,OsinfoTree * tree,OsinfoInstallConfig * config,const gchar * node_name,GError ** error)858 static xmlDocPtr osinfo_install_script_generate_config_xml(OsinfoInstallScript *script,
859 OsinfoOs *os,
860 OsinfoMedia *media,
861 OsinfoTree *tree,
862 OsinfoInstallConfig *config,
863 const gchar *node_name,
864 GError **error)
865 {
866 xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0");
867 xmlNodePtr root;
868 xmlNodePtr node;
869
870 root = xmlNewDocNode(NULL,
871 NULL,
872 (xmlChar*)node_name,
873 NULL);
874 xmlDocSetRootElement(doc, root);
875
876 if (!(node = osinfo_install_script_generate_entity_xml(script,
877 OSINFO_ENTITY(script),
878 "script",
879 error)))
880 goto error;
881 if (!(xmlAddChild(root, node))) {
882 propagate_libxml_error(error, _("Unable to set XML root"));
883 goto error;
884 }
885
886 if (!(node = osinfo_install_script_generate_entity_xml(script,
887 OSINFO_ENTITY(os),
888 "os",
889 error)))
890 goto error;
891 if (!(xmlAddChild(root, node))) {
892 propagate_libxml_error(error, _("Unable to set XML root"));
893 goto error;
894 }
895
896 if (media != NULL) {
897 if (!(node = osinfo_install_script_generate_entity_xml(script,
898 OSINFO_ENTITY(media),
899 "media",
900 error)))
901 goto error;
902 if (!(xmlAddChild(root, node))) {
903 propagate_libxml_error(error, _("Unable to set 'media' node"));
904 goto error;
905 }
906 }
907
908 if (tree != NULL) {
909 if (!(node = osinfo_install_script_generate_entity_xml(script,
910 OSINFO_ENTITY(tree),
911 "tree",
912 error)))
913 goto error;
914 if (!(xmlAddChild(root, node))) {
915 propagate_libxml_error(error, _("Unable to set 'tree' node"));
916 goto error;
917 }
918 }
919
920 if (!(node = osinfo_install_script_generate_entity_xml(script,
921 OSINFO_ENTITY(config),
922 "config",
923 error)))
924 goto error;
925 if (!(xmlAddChild(root, node))) {
926 propagate_libxml_error(error, _("Unable to set XML root"));
927 goto error;
928 }
929
930 return doc;
931
932 error:
933 xmlFreeDoc(doc);
934 doc = NULL;
935 return NULL;
936 }
937
osinfo_install_script_apply_xslt(xsltStylesheetPtr ss,xmlDocPtr doc,GError ** error)938 static gchar *osinfo_install_script_apply_xslt(xsltStylesheetPtr ss,
939 xmlDocPtr doc,
940 GError **error)
941 {
942 xsltTransformContextPtr ctxt;
943 xmlChar *xsltResult;
944 gchar *ret = NULL;
945 xmlDocPtr docOut = NULL;
946 int len;
947
948 if (!(ctxt = xsltNewTransformContext(ss, doc))) {
949 g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to create XSL transform context"));
950 goto cleanup;
951 }
952
953 if (!(docOut = xsltApplyStylesheetUser(ss, doc, NULL, NULL, NULL, ctxt))) {
954 g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to apply XSL transform context"));
955 goto cleanup;
956 }
957
958 if (xsltSaveResultToString(&xsltResult, &len, docOut, ss) < 0) {
959 g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to convert XSL output to string"));
960 goto cleanup;
961 }
962 ret = g_strdup((gchar *)xsltResult);
963 xmlFree(xsltResult);
964
965 cleanup:
966 xmlFreeDoc(docOut);
967 xsltFreeTransformContext(ctxt);
968 return ret;
969 }
970
971
osinfo_install_script_apply_template(OsinfoInstallScript * script,OsinfoOs * os,OsinfoMedia * media,OsinfoTree * tree,const gchar * templateUri,const gchar * template,const gchar * node_name,gchar ** result,OsinfoInstallConfig * config,GError ** error)972 static gboolean osinfo_install_script_apply_template(OsinfoInstallScript *script,
973 OsinfoOs *os,
974 OsinfoMedia *media,
975 OsinfoTree *tree,
976 const gchar *templateUri,
977 const gchar *template,
978 const gchar *node_name,
979 gchar **result,
980 OsinfoInstallConfig *config,
981 GError **error)
982 {
983 gboolean ret = FALSE;
984 xsltStylesheetPtr templateXsl = osinfo_install_script_load_template(templateUri, template, error);
985 xmlDocPtr configXml = osinfo_install_script_generate_config_xml(script, os, media, tree, config, node_name, error);
986
987 if (!templateXsl || !configXml)
988 goto cleanup;
989
990 if (!(*result = osinfo_install_script_apply_xslt(templateXsl, configXml, error)))
991 goto cleanup;
992
993 ret = TRUE;
994
995 cleanup:
996 xsltFreeStylesheet(templateXsl);
997 xmlFreeDoc(configXml);
998 return ret;
999 }
1000
1001
osinfo_install_script_template_loaded(GObject * src,GAsyncResult * res,gpointer user_data)1002 static void osinfo_install_script_template_loaded(GObject *src,
1003 GAsyncResult *res,
1004 gpointer user_data)
1005 {
1006 OsinfoInstallScriptGenerateData *data = user_data;
1007 GError *error = NULL;
1008 gchar *input = NULL;
1009 gchar *output = NULL;
1010 gsize length = 0;
1011 GFile *file = G_FILE(src);
1012 gchar *uri = g_file_get_uri(file);
1013
1014 if (!g_file_load_contents_finish(file,
1015 res,
1016 &input,
1017 &length,
1018 NULL,
1019 &error)) {
1020 g_prefix_error(&error, _("Failed to load script template %s: "), uri);
1021 g_task_return_error(data->res, error);
1022 goto cleanup;
1023 }
1024
1025
1026 if (!osinfo_install_script_apply_template(data->script,
1027 data->os,
1028 data->media,
1029 data->tree,
1030 uri,
1031 input,
1032 "install-script-config",
1033 &output,
1034 data->config,
1035 &error)) {
1036 g_prefix_error(&error, _("Failed to apply script template %s: "), uri);
1037 g_task_return_error(data->res, error);
1038 goto cleanup;
1039 }
1040
1041 g_task_return_pointer(data->res, output, g_free);
1042
1043 cleanup:
1044 g_free(input);
1045 osinfo_install_script_generate_data_free(data);
1046 g_free(uri);
1047 }
1048
1049
osinfo_install_script_generate_async_common(OsinfoInstallScript * script,OsinfoOs * os,OsinfoMedia * media,OsinfoTree * tree,OsinfoInstallConfig * config,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1050 static void osinfo_install_script_generate_async_common(OsinfoInstallScript *script,
1051 OsinfoOs *os,
1052 OsinfoMedia *media,
1053 OsinfoTree *tree,
1054 OsinfoInstallConfig *config,
1055 GCancellable *cancellable,
1056 GAsyncReadyCallback callback,
1057 gpointer user_data)
1058 {
1059 OsinfoInstallScriptGenerateData *data;
1060 const gchar *templateData;
1061 const gchar *templateUri;
1062
1063 g_return_if_fail(os != NULL);
1064
1065 data = g_new0(OsinfoInstallScriptGenerateData, 1);
1066 templateData = osinfo_install_script_get_template_data(script);
1067 templateUri = osinfo_install_script_get_template_uri(script);
1068
1069 data->os = g_object_ref(os);
1070 if (media != NULL)
1071 data->media = g_object_ref(media);
1072 if (tree != NULL)
1073 data->tree = g_object_ref(tree);
1074 data->config = g_object_ref(config);
1075 data->script = g_object_ref(script);
1076 data->res = g_task_new(G_OBJECT(script),
1077 cancellable,
1078 callback,
1079 user_data);
1080
1081 if (templateData) {
1082 GError *error = NULL;
1083 gchar *output;
1084 if (!osinfo_install_script_apply_template(script,
1085 os,
1086 media,
1087 NULL,
1088 "<data>",
1089 templateData,
1090 "install-script-config",
1091 &output,
1092 data->config,
1093 &error)) {
1094 g_prefix_error(&error, "%s", _("Failed to apply script template: "));
1095 g_task_return_error(data->res, error);
1096 osinfo_install_script_generate_data_free(data);
1097 return;
1098 }
1099 g_task_return_pointer(data->res, output, g_free);
1100 osinfo_install_script_generate_data_free(data);
1101 } else {
1102 GFile *file = g_file_new_for_uri(templateUri);
1103
1104 g_file_load_contents_async(file,
1105 cancellable,
1106 osinfo_install_script_template_loaded,
1107 data);
1108 g_object_unref(file);
1109 }
1110 }
1111
1112 /**
1113 * osinfo_install_script_generate_async:
1114 * @script: the install script
1115 * @os: the os
1116 * @config: the install script config
1117 * @cancellable: (allow-none): a #GCancellable, or %NULL
1118 * @callback: Function to call when result of this call is ready
1119 * @user_data: The user data to pass to @callback, or %NULL
1120 *
1121 * Asynchronous variant of #osinfo_install_script_generate(). From the callback,
1122 * call #osinfo_install_script_generate_finish() to conclude this call and get
1123 * the generated script.
1124 *
1125 * If you are generating the script for a specific media, it is recommended that
1126 * you use #osinfo_install_script_generate_for_media_async() instead.
1127 *
1128 * Since: 0.2.0
1129 */
osinfo_install_script_generate_async(OsinfoInstallScript * script,OsinfoOs * os,OsinfoInstallConfig * config,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1130 void osinfo_install_script_generate_async(OsinfoInstallScript *script,
1131 OsinfoOs *os,
1132 OsinfoInstallConfig *config,
1133 GCancellable *cancellable,
1134 GAsyncReadyCallback callback,
1135 gpointer user_data)
1136 {
1137 osinfo_install_script_generate_async_common(script,
1138 os,
1139 NULL,
1140 NULL,
1141 config,
1142 cancellable,
1143 callback,
1144 user_data);
1145 }
1146
osinfo_install_script_generate_finish_common(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1147 static gpointer osinfo_install_script_generate_finish_common(OsinfoInstallScript *script,
1148 GAsyncResult *res,
1149 GError **error)
1150 {
1151 GTask *task = G_TASK(res);
1152
1153 g_return_val_if_fail(error == NULL || *error == NULL, NULL);
1154
1155 return g_task_propagate_pointer(task, error);
1156 }
1157
1158 /**
1159 * osinfo_install_script_generate_finish:
1160 * @script: the install script
1161 * @res: a #GAsyncResult
1162 * @error: The location where to store any error, or NULL
1163 *
1164 * Returns: (transfer full): the generated script, or NULL on error
1165 *
1166 * Since: 0.2.0
1167 */
osinfo_install_script_generate_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1168 gchar *osinfo_install_script_generate_finish(OsinfoInstallScript *script,
1169 GAsyncResult *res,
1170 GError **error)
1171 {
1172 return osinfo_install_script_generate_finish_common(script,
1173 res,
1174 error);
1175 }
1176
1177 /**
1178 * osinfo_install_script_generate_for_media_finish:
1179 * @script: the install script
1180 * @res: a #GAsyncResult
1181 * @error: The location where to store any error, or NULL
1182 *
1183 * Returns: (transfer full): the generated script, or NULL on error
1184 *
1185 * Since: 0.2.12
1186 */
osinfo_install_script_generate_for_media_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1187 gchar *osinfo_install_script_generate_for_media_finish(OsinfoInstallScript *script,
1188 GAsyncResult *res,
1189 GError **error)
1190 {
1191 return osinfo_install_script_generate_finish_common(script,
1192 res,
1193 error);
1194 }
1195
1196 /**
1197 * osinfo_install_script_generate_for_tree_finish:
1198 * @script: the install script
1199 * @res: a #GAsyncResult
1200 * @error: the location where to story any error, or NULL
1201 *
1202 * Returns: (transfer full): the generated script, or NULL or error
1203 *
1204 * Since: 1.6.0
1205 */
osinfo_install_script_generate_for_tree_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1206 gchar *osinfo_install_script_generate_for_tree_finish(OsinfoInstallScript *script,
1207 GAsyncResult *res,
1208 GError **error)
1209 {
1210 return osinfo_install_script_generate_finish_common(script,
1211 res,
1212 error);
1213 }
1214
1215 /**
1216 * osinfo_install_script_generate_output_finish:
1217 * @script: the install script
1218 * @res: a #GAsyncResult
1219 * @error: The location where to store any error, or NULL
1220 *
1221 * Returns: (transfer full): a file containing the script, or NULL on error
1222 *
1223 * Since: 0.2.3
1224 */
osinfo_install_script_generate_output_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1225 GFile *osinfo_install_script_generate_output_finish(OsinfoInstallScript *script,
1226 GAsyncResult *res,
1227 GError **error)
1228 {
1229 return osinfo_install_script_generate_finish_common(script,
1230 res,
1231 error);
1232 }
1233
1234 /**
1235 * osinfo_install_script_generate_output_for_media_finish:
1236 * @script: the install script
1237 * @res: a #GAsyncResult
1238 * @error: the location where to store any error, or NULL
1239 *
1240 * Returns: (transfer full): a file containing the script, or NULL on error.
1241 *
1242 * Since: 0.2.12
1243 */
osinfo_install_script_generate_output_for_media_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1244 GFile *osinfo_install_script_generate_output_for_media_finish(OsinfoInstallScript *script,
1245 GAsyncResult *res,
1246 GError **error)
1247 {
1248 return osinfo_install_script_generate_finish_common(script,
1249 res,
1250 error);
1251 }
1252
1253 /**
1254 * osinfo_install_script_generate_output_for_tree_finish:
1255 * @script: the install script
1256 * @res: a #GAsyncResult
1257 * @error: the location where to store any error, or NULL
1258 *
1259 * Returns: (transfer full): a file containing the script, or NULL on error.
1260 *
1261 * Since: 1.6.0
1262 */
osinfo_install_script_generate_output_for_tree_finish(OsinfoInstallScript * script,GAsyncResult * res,GError ** error)1263 GFile *osinfo_install_script_generate_output_for_tree_finish(OsinfoInstallScript *script,
1264 GAsyncResult *res,
1265 GError **error)
1266 {
1267 return osinfo_install_script_generate_finish_common(script,
1268 res,
1269 error);
1270 }
1271
1272 struct _OsinfoInstallScriptGenerateSyncData {
1273 GMainLoop *loop;
1274 GError *error;
1275 gchar *output;
1276 GFile *file;
1277 };
1278
osinfo_install_script_generate_output_done(GObject * src,GAsyncResult * res,gpointer user_data)1279 static void osinfo_install_script_generate_output_done(GObject *src,
1280 GAsyncResult *res,
1281 gpointer user_data)
1282 {
1283 OsinfoInstallScriptGenerateSyncData *data = user_data;
1284
1285 data->file =
1286 osinfo_install_script_generate_output_finish(OSINFO_INSTALL_SCRIPT(src),
1287 res,
1288 &data->error);
1289 g_main_loop_quit(data->loop);
1290 }
1291
osinfo_install_script_generate_output_for_media_done(GObject * src,GAsyncResult * res,gpointer user_data)1292 static void osinfo_install_script_generate_output_for_media_done(GObject *src,
1293 GAsyncResult *res,
1294 gpointer user_data)
1295 {
1296 OsinfoInstallScriptGenerateSyncData *data = user_data;
1297
1298 data->file =
1299 osinfo_install_script_generate_output_for_media_finish(OSINFO_INSTALL_SCRIPT(src),
1300 res,
1301 &data->error);
1302 g_main_loop_quit(data->loop);
1303 }
1304
osinfo_install_script_generate_output_for_tree_done(GObject * src,GAsyncResult * res,gpointer user_data)1305 static void osinfo_install_script_generate_output_for_tree_done(GObject *src,
1306 GAsyncResult *res,
1307 gpointer user_data)
1308 {
1309 OsinfoInstallScriptGenerateSyncData *data = user_data;
1310
1311 data->file =
1312 osinfo_install_script_generate_output_for_tree_finish(OSINFO_INSTALL_SCRIPT(src),
1313 res,
1314 &data->error);
1315 g_main_loop_quit(data->loop);
1316 }
1317
osinfo_install_script_generate_output_close_file(GObject * src,GAsyncResult * res,gpointer user_data)1318 static void osinfo_install_script_generate_output_close_file(GObject *src,
1319 GAsyncResult *res,
1320 gpointer user_data)
1321 {
1322 OsinfoInstallScriptGenerateOutputData *data = user_data;
1323
1324 g_output_stream_close_finish(G_OUTPUT_STREAM(src),
1325 res,
1326 &data->error);
1327
1328 g_task_return_pointer(data->res, data->file, NULL);
1329
1330 osinfo_install_script_generate_output_data_free(data);
1331 }
1332
osinfo_install_script_generate_done(GObject * src,GAsyncResult * res,gpointer user_data)1333 static void osinfo_install_script_generate_done(GObject *src,
1334 GAsyncResult *res,
1335 gpointer user_data)
1336 {
1337 OsinfoInstallScriptGenerateSyncData *data = user_data;
1338
1339 data->output =
1340 osinfo_install_script_generate_finish(OSINFO_INSTALL_SCRIPT(src),
1341 res,
1342 &data->error);
1343 g_main_loop_quit(data->loop);
1344 }
1345
1346 /**
1347 * osinfo_install_script_generate:
1348 * @script: the install script
1349 * @os: the os
1350 * @config: the install script config
1351 * @cancellable: (allow-none): a #GCancellable, or %NULL
1352 * @error: The location where to store any error, or %NULL
1353 *
1354 * Creates an install script.
1355 *
1356 * Returns: (transfer full): the script as string.
1357 *
1358 * If you are generating the script for a specific media, it is recommended
1359 * that you use #osinfo_install_script_generate_for_media() instead.
1360 *
1361 * If you are generating the script for a specific tree, it is recommended
1362 * that you use #osinfo_install_script_generate_for_tree() in instead.
1363 *
1364 * Since: 0.2.0
1365 */
osinfo_install_script_generate(OsinfoInstallScript * script,OsinfoOs * os,OsinfoInstallConfig * config,GCancellable * cancellable,GError ** error)1366 gchar *osinfo_install_script_generate(OsinfoInstallScript *script,
1367 OsinfoOs *os,
1368 OsinfoInstallConfig *config,
1369 GCancellable *cancellable,
1370 GError **error)
1371 {
1372 GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
1373 FALSE);
1374 OsinfoInstallScriptGenerateSyncData data = {
1375 loop, NULL, NULL, NULL
1376 };
1377
1378 osinfo_install_script_generate_async(script,
1379 os,
1380 config,
1381 cancellable,
1382 osinfo_install_script_generate_done,
1383 &data);
1384
1385 g_main_loop_run(loop);
1386
1387 if (data.error)
1388 g_propagate_error(error, data.error);
1389
1390 g_main_loop_unref(loop);
1391
1392 return data.output;
1393 }
1394
1395 /**
1396 * osinfo_install_script_generate_for_media_async:
1397 * @script: the install script
1398 * @media: the media
1399 * @config: the install script config
1400 * @cancellable: (allow-none): a #GCancellable, or %NULL
1401 * @callback: Function to call when result of this call is ready
1402 * @user_data: The user data to pass to @callback, or %NULL
1403 *
1404 * Asynchronous variant of #osinfo_install_script_generate_for_media(). From the
1405 * callback, call #osinfo_install_script_generate_for_media_finish() to
1406 * conclude this call and get the generated script.
1407 *
1408 * Since: 0.2.12
1409 */
osinfo_install_script_generate_for_media_async(OsinfoInstallScript * script,OsinfoMedia * media,OsinfoInstallConfig * config,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1410 void osinfo_install_script_generate_for_media_async(OsinfoInstallScript *script,
1411 OsinfoMedia *media,
1412 OsinfoInstallConfig *config,
1413 GCancellable *cancellable,
1414 GAsyncReadyCallback callback,
1415 gpointer user_data) {
1416 OsinfoOs *os;
1417
1418 g_return_if_fail(media != NULL);
1419
1420 os = osinfo_media_get_os(media);
1421
1422 osinfo_install_script_generate_async_common(script,
1423 os,
1424 media,
1425 NULL,
1426 config,
1427 cancellable,
1428 callback,
1429 user_data);
1430
1431 g_object_unref(os);
1432 }
1433
osinfo_install_script_generate_for_media_done(GObject * src,GAsyncResult * res,gpointer user_data)1434 static void osinfo_install_script_generate_for_media_done(GObject *src,
1435 GAsyncResult *res,
1436 gpointer user_data)
1437 {
1438 OsinfoInstallScriptGenerateSyncData *data = user_data;
1439
1440 data->output =
1441 osinfo_install_script_generate_for_media_finish(OSINFO_INSTALL_SCRIPT(src),
1442 res,
1443 &data->error);
1444 g_main_loop_quit(data->loop);
1445 }
1446
1447 /**
1448 * osinfo_install_script_generate_for_media:
1449 * @script: the install script
1450 * @media: the media
1451 * @config: the install script config
1452 * @cancellable: (allow-none): a #GCancellable, or %NULL
1453 * @error: The location where to store any error, or %NULL
1454 *
1455 * Creates an install script. The media @media must have been identified
1456 * successfully using #osinfo_db_identify_media() before calling this function.
1457 *
1458 * Returns: (transfer full): the script as string.
1459 *
1460 * Since: 0.2.12
1461 */
osinfo_install_script_generate_for_media(OsinfoInstallScript * script,OsinfoMedia * media,OsinfoInstallConfig * config,GCancellable * cancellable,GError ** error)1462 gchar *osinfo_install_script_generate_for_media(OsinfoInstallScript *script,
1463 OsinfoMedia *media,
1464 OsinfoInstallConfig *config,
1465 GCancellable *cancellable,
1466 GError **error)
1467 {
1468 GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
1469 FALSE);
1470 OsinfoInstallScriptGenerateSyncData data = {
1471 loop, NULL, NULL, NULL
1472 };
1473
1474 osinfo_install_script_generate_for_media_async(script,
1475 media,
1476 config,
1477 cancellable,
1478 osinfo_install_script_generate_for_media_done,
1479 &data);
1480
1481 g_main_loop_run(loop);
1482
1483 if (data.error)
1484 g_propagate_error(error, data.error);
1485
1486 g_main_loop_unref(loop);
1487
1488 return data.output;
1489 }
1490
1491 /**
1492 * osinfo_install_script_generate_for_tree_async:
1493 * @script: the install script
1494 * @tree: the tree
1495 * @config: the install script config
1496 * @cancellable: (allow-none): a #GCancellable, or %NULL
1497 * @callback: Function to call when result of this call is ready
1498 * @user_data: The user data to pass to @callback, or %NULL
1499 *
1500 * Asynchronous variant of #osinfo_install_script_generate_for_tree(). From the
1501 * callback, call #osinfo_install_script_generate_for_tree_finish() to
1502 * conclude this call and get the generated script.
1503 *
1504 * Since: 1.6.0
1505 */
osinfo_install_script_generate_for_tree_async(OsinfoInstallScript * script,OsinfoTree * tree,OsinfoInstallConfig * config,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1506 void osinfo_install_script_generate_for_tree_async(OsinfoInstallScript *script,
1507 OsinfoTree *tree,
1508 OsinfoInstallConfig *config,
1509 GCancellable *cancellable,
1510 GAsyncReadyCallback callback,
1511 gpointer user_data) {
1512 OsinfoOs *os;
1513
1514 g_return_if_fail(tree != NULL);
1515
1516 os = osinfo_tree_get_os(tree);
1517
1518 osinfo_install_script_generate_async_common(script,
1519 os,
1520 NULL,
1521 tree,
1522 config,
1523 cancellable,
1524 callback,
1525 user_data);
1526
1527 g_object_unref(os);
1528 }
1529
osinfo_install_script_generate_for_tree_done(GObject * src,GAsyncResult * res,gpointer user_data)1530 static void osinfo_install_script_generate_for_tree_done(GObject *src,
1531 GAsyncResult *res,
1532 gpointer user_data)
1533 {
1534 OsinfoInstallScriptGenerateSyncData *data = user_data;
1535
1536 data->output =
1537 osinfo_install_script_generate_for_tree_finish(OSINFO_INSTALL_SCRIPT(src),
1538 res,
1539 &data->error);
1540 g_main_loop_quit(data->loop);
1541 }
1542
1543 /**
1544 * osinfo_install_script_generate_for_tree:
1545 * @script: the install script
1546 * @tree: the tree
1547 * @config: the install script config
1548 * @cancellable: (allow-none): a #GCancellable, or %NULL
1549 * @error: The location where to store any error, or %NULL
1550 *
1551 * Creates an install script. The tree @tree must have been identified
1552 * successfully using #osinfo_db_identify_tree() before calling this function.
1553 *
1554 * Returns: (transfer full): the script as string.
1555 *
1556 * Since: 1.6.0
1557 */
osinfo_install_script_generate_for_tree(OsinfoInstallScript * script,OsinfoTree * tree,OsinfoInstallConfig * config,GCancellable * cancellable,GError ** error)1558 gchar *osinfo_install_script_generate_for_tree(OsinfoInstallScript *script,
1559 OsinfoTree *tree,
1560 OsinfoInstallConfig *config,
1561 GCancellable *cancellable,
1562 GError **error)
1563 {
1564 GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
1565 FALSE);
1566 OsinfoInstallScriptGenerateSyncData data = {
1567 loop, NULL, NULL, NULL
1568 };
1569
1570 osinfo_install_script_generate_for_tree_async(script,
1571 tree,
1572 config,
1573 cancellable,
1574 osinfo_install_script_generate_for_tree_done,
1575 &data);
1576
1577 g_main_loop_run(loop);
1578
1579 if (data.error)
1580 g_propagate_error(error, data.error);
1581
1582 g_main_loop_unref(loop);
1583
1584 return data.output;
1585 }
1586
osinfo_install_script_generate_output_write_file(GObject * src,GAsyncResult * res,gpointer user_data)1587 static void osinfo_install_script_generate_output_write_file(GObject *src,
1588 GAsyncResult *res,
1589 gpointer user_data)
1590 {
1591 OsinfoInstallScriptGenerateOutputData *data = user_data;
1592
1593 if (data->stream == NULL)
1594 data->stream = g_file_replace_finish(G_FILE(src), res, &data->error);
1595 else
1596 data->output_pos += g_output_stream_write_finish(G_OUTPUT_STREAM(data->stream),
1597 res,
1598 &data->error);
1599
1600 if (data->output_pos < data->output_len) {
1601 g_output_stream_write_async(G_OUTPUT_STREAM(data->stream),
1602 data->output + data->output_pos,
1603 data->output_len - data->output_pos,
1604 G_PRIORITY_DEFAULT,
1605 g_task_get_cancellable(data->res),
1606 osinfo_install_script_generate_output_write_file,
1607 data);
1608
1609 } else {
1610 g_output_stream_close_async(G_OUTPUT_STREAM(data->stream),
1611 G_PRIORITY_DEFAULT,
1612 g_task_get_cancellable(data->res),
1613 osinfo_install_script_generate_output_close_file,
1614 data);
1615 }
1616 }
1617
osinfo_install_script_generate_output_async_common(OsinfoInstallScript * script,OsinfoOs * os,OsinfoMedia * media,OsinfoTree * tree,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1618 static void osinfo_install_script_generate_output_async_common(OsinfoInstallScript *script,
1619 OsinfoOs *os,
1620 OsinfoMedia *media,
1621 OsinfoTree *tree,
1622 OsinfoInstallConfig *config,
1623 GFile *output_dir,
1624 GCancellable *cancellable,
1625 GAsyncReadyCallback callback,
1626 gpointer user_data)
1627 {
1628 const gchar *filename;
1629 const gchar *prefix;
1630 OsinfoInstallScriptGenerateOutputData *data =
1631 g_new0(OsinfoInstallScriptGenerateOutputData, 1);
1632
1633 OsinfoInstallScriptGenerateSyncData *data_sync = user_data;
1634
1635 data->res = g_task_new(G_OBJECT(script),
1636 cancellable,
1637 callback,
1638 user_data);
1639
1640 data->error = data_sync->error;
1641 if (media != NULL) {
1642 data->output = osinfo_install_script_generate_for_media(script,
1643 media,
1644 config,
1645 cancellable,
1646 &data->error);
1647 } else if (tree != NULL) {
1648 data->output = osinfo_install_script_generate_for_tree(script,
1649 tree,
1650 config,
1651 cancellable,
1652 &data->error);
1653 } else {
1654 data->output = osinfo_install_script_generate(script,
1655 os,
1656 config,
1657 cancellable,
1658 &data->error);
1659 }
1660 data->output_pos = 0;
1661 data->output_len = strlen(data->output);
1662
1663 prefix =
1664 osinfo_install_script_get_output_prefix(script);
1665 filename =
1666 osinfo_install_script_get_output_filename(script);
1667
1668 if (prefix) {
1669 gchar *output_filename = g_strdup_printf("%s-%s", prefix, filename);
1670 data->file = g_file_get_child(output_dir, output_filename);
1671 g_free(output_filename);
1672 } else {
1673 data->file = g_file_get_child(output_dir, filename);
1674 }
1675
1676 g_file_replace_async(data->file,
1677 NULL,
1678 TRUE,
1679 G_FILE_CREATE_NONE,
1680 G_PRIORITY_DEFAULT,
1681 cancellable,
1682 osinfo_install_script_generate_output_write_file,
1683 data);
1684 }
1685
1686 /**
1687 * osinfo_install_script_generate_output_async:
1688 * @script: the install script
1689 * @os: the os
1690 * @config: the install script config
1691 * @output_dir: the directory where the file containing the output script
1692 * will be written
1693 * @cancellable: (allow-none): a #GCancellable, or %NULL
1694 * @callback: Function to call when result of this call is ready
1695 * @user_data: The user data to pass to @callback, or %NULL
1696 *
1697 * Asynchronous variant of #osinfo_install_script_generate_output(). From the
1698 * callback, call #osinfo_install_script_generate_output_finish() to conclude
1699 * this call and get the generated script.
1700 *
1701 * If you are generating the script for a specific media, it is recommended that
1702 * you use #osinfo_install_script_generate_output_for_media_async() instead.
1703 *
1704 * Since: 0.2.0
1705 */
osinfo_install_script_generate_output_async(OsinfoInstallScript * script,OsinfoOs * os,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1706 void osinfo_install_script_generate_output_async(OsinfoInstallScript *script,
1707 OsinfoOs *os,
1708 OsinfoInstallConfig *config,
1709 GFile *output_dir,
1710 GCancellable *cancellable,
1711 GAsyncReadyCallback callback,
1712 gpointer user_data)
1713 {
1714 osinfo_install_script_generate_output_async_common(script,
1715 os,
1716 NULL,
1717 NULL,
1718 config,
1719 output_dir,
1720 cancellable,
1721 callback,
1722 user_data);
1723 }
1724
osinfo_install_script_generate_output_common(OsinfoInstallScript * script,OsinfoOs * os,OsinfoMedia * media,OsinfoTree * tree,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GError ** error)1725 static GFile *osinfo_install_script_generate_output_common(OsinfoInstallScript *script,
1726 OsinfoOs *os,
1727 OsinfoMedia *media,
1728 OsinfoTree *tree,
1729 OsinfoInstallConfig *config,
1730 GFile *output_dir,
1731 GCancellable *cancellable,
1732 GError **error)
1733 {
1734 GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
1735 FALSE);
1736 OsinfoInstallScriptGenerateSyncData data = {
1737 loop, NULL, NULL, NULL
1738 };
1739
1740 if (media != NULL) {
1741 osinfo_install_script_generate_output_for_media_async
1742 (script,
1743 media,
1744 config,
1745 output_dir,
1746 cancellable,
1747 osinfo_install_script_generate_output_for_media_done,
1748 &data);
1749 } else if (tree != NULL) {
1750 osinfo_install_script_generate_output_for_tree_async
1751 (script,
1752 tree,
1753 config,
1754 output_dir,
1755 cancellable,
1756 osinfo_install_script_generate_output_for_tree_done,
1757 &data);
1758 } else {
1759 osinfo_install_script_generate_output_async
1760 (script,
1761 os,
1762 config,
1763 output_dir,
1764 cancellable,
1765 osinfo_install_script_generate_output_done,
1766 &data);
1767 }
1768
1769 g_main_loop_run(loop);
1770
1771 if (data.error)
1772 g_propagate_error(error, data.error);
1773
1774 g_main_loop_unref(loop);
1775
1776 return data.file;
1777 }
1778
1779 /**
1780 * osinfo_install_script_generate_output:
1781 * @script: the install script
1782 * @os: the os entity
1783 * @config: the install script config
1784 * @output_dir: the directory where the file containing the output script
1785 * will be written
1786 * @cancellable: (allow-none): a #GCancellable, or %NULL
1787 * @error: The location where to store any error, or %NULL
1788 *
1789 * Creates an install script that is written to the returned file.
1790 *
1791 * Returns: (transfer full): a file containing the script
1792 *
1793 * If you are generating the script for a specific media, it is recommended
1794 * that you use #osinfo_install_script_generate_output_for_media() instead.
1795 *
1796 * If you are generating the script for a specific tree, it is recommended
1797 * that you use #osinfo_install_script_generate_output_for_tree() instead.
1798 *
1799 * Since: 0.2.0
1800 */
osinfo_install_script_generate_output(OsinfoInstallScript * script,OsinfoOs * os,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GError ** error)1801 GFile *osinfo_install_script_generate_output(OsinfoInstallScript *script,
1802 OsinfoOs *os,
1803 OsinfoInstallConfig *config,
1804 GFile *output_dir,
1805 GCancellable *cancellable,
1806 GError **error)
1807 {
1808 return osinfo_install_script_generate_output_common(script,
1809 os,
1810 NULL,
1811 NULL,
1812 config,
1813 output_dir,
1814 cancellable,
1815 error);
1816 }
1817
1818 /**
1819 * osinfo_install_script_generate_output_for_media_async:
1820 * @script: the install script
1821 * @media: the media
1822 * @config: the install script config
1823 * @output_dir: the directory where the file containing the output script
1824 * will be written
1825 * @cancellable: (allow-none): a #GCancellable, or %NULL
1826 * @callback: Function to call when result of this call is ready
1827 * @user_data: The user data to pass to @callback, or %NULL
1828 *
1829 * Asynchronous variant of #osinfo_install_script_generate_output_for_media().
1830 * From the callback, call
1831 * #osinfo_install_script_generate_output_for_media_finish() to conclude this
1832 * call and get the generated file.
1833 *
1834 * Since: 0.2.12
1835 */
osinfo_install_script_generate_output_for_media_async(OsinfoInstallScript * script,OsinfoMedia * media,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1836 void osinfo_install_script_generate_output_for_media_async(OsinfoInstallScript *script,
1837 OsinfoMedia *media,
1838 OsinfoInstallConfig *config,
1839 GFile *output_dir,
1840 GCancellable *cancellable,
1841 GAsyncReadyCallback callback,
1842 gpointer user_data)
1843 {
1844 osinfo_install_script_generate_output_async_common(script,
1845 NULL,
1846 media,
1847 NULL,
1848 config,
1849 output_dir,
1850 cancellable,
1851 callback,
1852 user_data);
1853 }
1854
1855 /**
1856 * osinfo_install_script_generate_output_for_media:
1857 * @script: the install script
1858 * @media: the media
1859 * @config: the install script config
1860 * @output_dir: the directory where the file containing the output script
1861 * will be written
1862 * @cancellable: (allow-none): a #GCancellable, or %NULL
1863 * @error: The location where to store any error, or %NULL
1864 *
1865 * Creates an install script that is written to the returned file.
1866 *
1867 * Returns: (transfer full): a file containing the script.
1868 *
1869 * Since: 0.2.12
1870 */
osinfo_install_script_generate_output_for_media(OsinfoInstallScript * script,OsinfoMedia * media,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GError ** error)1871 GFile *osinfo_install_script_generate_output_for_media(OsinfoInstallScript *script,
1872 OsinfoMedia *media,
1873 OsinfoInstallConfig *config,
1874 GFile *output_dir,
1875 GCancellable *cancellable,
1876 GError **error)
1877 {
1878 return osinfo_install_script_generate_output_common(script,
1879 NULL,
1880 media,
1881 NULL,
1882 config,
1883 output_dir,
1884 cancellable,
1885 error);
1886 }
1887
1888 /**
1889 * osinfo_install_script_generate_output_for_tree_async:
1890 * @script: the install script
1891 * @tree: the tree
1892 * @config: the install script config
1893 * @output_dir: the directory where the file containing the output script
1894 * will be written
1895 * @cancellable: (allow-none): a #GCancellable, or %NULL
1896 * @callback: Function to call when result of this call is ready
1897 * @user_data: The user data to pass to @callback, or %NULL
1898 *
1899 * Asynchronous variant of #osinfo_install_script_generate_output_for_tree().
1900 * From the callback, call
1901 * #osinfo_install_script_generate_output_for_tree_finish() to conclude this
1902 * call and get the generated file.
1903 *
1904 * Since: 1.6.0
1905 */
osinfo_install_script_generate_output_for_tree_async(OsinfoInstallScript * script,OsinfoTree * tree,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1906 void osinfo_install_script_generate_output_for_tree_async(OsinfoInstallScript *script,
1907 OsinfoTree *tree,
1908 OsinfoInstallConfig *config,
1909 GFile *output_dir,
1910 GCancellable *cancellable,
1911 GAsyncReadyCallback callback,
1912 gpointer user_data)
1913 {
1914 osinfo_install_script_generate_output_async_common(script,
1915 NULL,
1916 NULL,
1917 tree,
1918 config,
1919 output_dir,
1920 cancellable,
1921 callback,
1922 user_data);
1923 }
1924
1925 /**
1926 * osinfo_install_script_generate_output_for_tree:
1927 * @script: the install script
1928 * @tree: the tree
1929 * @config: the install script config
1930 * @output_dir: the directory where the file containing the output script
1931 * will be written
1932 * @cancellable: (allow-none): a #GCancellable, or %NULL
1933 * @error: The location where to store any error, or %NULL
1934 *
1935 * Creates an install script that is written to the returned file.
1936 *
1937 * Returns: (transfer full): a file containing the script.
1938 *
1939 * Since: 1.6.0
1940 */
osinfo_install_script_generate_output_for_tree(OsinfoInstallScript * script,OsinfoTree * tree,OsinfoInstallConfig * config,GFile * output_dir,GCancellable * cancellable,GError ** error)1941 GFile *osinfo_install_script_generate_output_for_tree(OsinfoInstallScript *script,
1942 OsinfoTree *tree,
1943 OsinfoInstallConfig *config,
1944 GFile *output_dir,
1945 GCancellable *cancellable,
1946 GError **error)
1947 {
1948 return osinfo_install_script_generate_output_common(script,
1949 NULL,
1950 NULL,
1951 tree,
1952 config,
1953 output_dir,
1954 cancellable,
1955 error);
1956 }
1957
1958 /**
1959 * osinfo_install_script_generate_command_line:
1960 * @script: the install script
1961 * @os: the os entity
1962 * @config: the install script config
1963 *
1964 * Some install scripts need to pass a command line to the kernel, Such install
1965 * scripts belong to OSs that provide paths to the kernel and initrd files that
1966 * can be used to directly boot
1967 * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot)
1968 * the OS in order to pass the needed commandline to it.
1969 *
1970 * If you are generating the command line for a specific media, it is
1971 * recommended that you use
1972 * #osinfo_install_script_generate_command_line_for_media() instead.
1973 *
1974 * If you are generating the command line for a specific tree, it is
1975 * recommended that you use
1976 * #osinfo_install_script_generate_command_line_for_tree() instead.
1977 *
1978 * Returns: (transfer full): The generated command line string, NULL otherwise.
1979 *
1980 * Since: 0.2.7
1981 */
osinfo_install_script_generate_command_line(OsinfoInstallScript * script,OsinfoOs * os,OsinfoInstallConfig * config)1982 gchar *osinfo_install_script_generate_command_line(OsinfoInstallScript *script,
1983 OsinfoOs *os,
1984 OsinfoInstallConfig *config)
1985 {
1986 const gchar *templateData = osinfo_install_script_get_template_data(script);
1987 gchar *output = NULL;
1988
1989 if (templateData) {
1990 GError *error = NULL;
1991 if (!osinfo_install_script_apply_template(script,
1992 os,
1993 NULL,
1994 NULL,
1995 "<data>",
1996 templateData,
1997 "command-line",
1998 &output,
1999 config,
2000 &error)) {
2001 g_prefix_error(&error, "%s", _("Failed to apply script template: "));
2002 }
2003 }
2004
2005 return output;
2006 }
2007
2008 /**
2009 * osinfo_install_script_generate_command_line_for_media:
2010 * @script: the install script
2011 * @media: the media
2012 * @config: the install script config
2013 *
2014 * Some install scripts need to pass a command line to the kernel, Such install
2015 * scripts belong to OSs that provide paths to the kernel and initrd files that
2016 * can be used to directly boot
2017 * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot)
2018 * the OS in order to pass the needed commandline to it.
2019 *
2020 * The media @media must have been identified successfully using
2021 * #osinfo_db_identify_media() before calling this function.
2022 *
2023 * Returns: (transfer full): The generated command line string, NULL otherwise.
2024 *
2025 * Since: 0.2.12
2026 */
osinfo_install_script_generate_command_line_for_media(OsinfoInstallScript * script,OsinfoMedia * media,OsinfoInstallConfig * config)2027 gchar *osinfo_install_script_generate_command_line_for_media(OsinfoInstallScript *script,
2028 OsinfoMedia *media,
2029 OsinfoInstallConfig *config)
2030 {
2031 const gchar *templateData = osinfo_install_script_get_template_data(script);
2032 gchar *output = NULL;
2033 OsinfoOs *os;
2034
2035 g_return_val_if_fail(media != NULL, NULL);
2036
2037 os = osinfo_media_get_os(media);
2038 g_return_val_if_fail(os != NULL, NULL);
2039
2040 if (templateData) {
2041 GError *error = NULL;
2042 if (!osinfo_install_script_apply_template(script,
2043 os,
2044 media,
2045 NULL,
2046 "<data>",
2047 templateData,
2048 "command-line",
2049 &output,
2050 config,
2051 &error)) {
2052 g_prefix_error(&error, "%s", _("Failed to apply script template: "));
2053 }
2054 }
2055 g_object_unref(os);
2056
2057 return output;
2058 }
2059
2060 /**
2061 * osinfo_install_script_generate_command_line_for_tree:
2062 * @script: the install script
2063 * @tree: the tree
2064 * @config: the install script config
2065 *
2066 * Some install scripts need to pass a command line to the kernel, Such install
2067 * scripts belong to OSs that provide paths to the kernel and initrd files that
2068 * can be used to directly boot
2069 * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot)
2070 * the OS in order to pass the needed commandline to it.
2071 *
2072 * The tree @tree must have been identified successfully using
2073 * #osinfo_db_identify_tree() before calling this function.
2074 *
2075 * Returns: (transfer full): The generated command line string, NULL otherwise.
2076 *
2077 * Since: 1.6.0
2078 */
osinfo_install_script_generate_command_line_for_tree(OsinfoInstallScript * script,OsinfoTree * tree,OsinfoInstallConfig * config)2079 gchar *osinfo_install_script_generate_command_line_for_tree(OsinfoInstallScript *script,
2080 OsinfoTree *tree,
2081 OsinfoInstallConfig *config)
2082 {
2083 const gchar *templateData = osinfo_install_script_get_template_data(script);
2084 gchar *output = NULL;
2085 OsinfoOs *os;
2086
2087 g_return_val_if_fail(tree != NULL, NULL);
2088
2089 os = osinfo_tree_get_os(tree);
2090 g_return_val_if_fail(os != NULL, NULL);
2091
2092 if (templateData) {
2093 GError *error = NULL;
2094 if (!osinfo_install_script_apply_template(script,
2095 os,
2096 NULL,
2097 tree,
2098 "<data>",
2099 templateData,
2100 "command-line",
2101 &output,
2102 config,
2103 &error)) {
2104 g_prefix_error(&error, "%s", _("Failed to apply script template: "));
2105 }
2106 }
2107 g_object_unref(os);
2108
2109 return output;
2110 }
2111
2112 /**
2113 * osinfo_install_script_get_path_format:
2114 * @script: the install script
2115 *
2116 * Returns the path format to be used for the files and disks which will
2117 * be used during the installation.
2118 *
2119 * Returns: the path format to be used. OSINFO_PATH_FORMAT_UNIX is the
2120 * default option.
2121 *
2122 * Since: 0.2.2
2123 */
osinfo_install_script_get_path_format(OsinfoInstallScript * script)2124 OsinfoPathFormat osinfo_install_script_get_path_format(OsinfoInstallScript *script)
2125 {
2126 return osinfo_entity_get_param_value_enum
2127 (OSINFO_ENTITY(script),
2128 OSINFO_INSTALL_SCRIPT_PROP_PATH_FORMAT,
2129 OSINFO_TYPE_PATH_FORMAT,
2130 OSINFO_PATH_FORMAT_UNIX);
2131 }
2132
2133 /**
2134 * osinfo_install_script_get_can_pre_install_drivers:
2135 * @script: the install script
2136 *
2137 * Whether install script can install drivers at the very beginning of
2138 * installation. This is needed for devices for which the OS in question does
2139 * not have out of the box support for and devices are required/preferred to be
2140 * available during actual installation.
2141 *
2142 * Returns: TRUE if install script supports pre-installable drivers, FALSE otherwise.
2143 *
2144 * Since: 0.2.2
2145 */
osinfo_install_script_get_can_pre_install_drivers(OsinfoInstallScript * script)2146 gboolean osinfo_install_script_get_can_pre_install_drivers(OsinfoInstallScript *script)
2147 {
2148 return osinfo_entity_get_param_value_boolean
2149 (OSINFO_ENTITY(script),
2150 OSINFO_INSTALL_SCRIPT_PROP_CAN_PRE_INSTALL_DRIVERS);
2151 }
2152
2153 /**
2154 * osinfo_install_script_get_can_post_install_drivers:
2155 * @script: the install script
2156 *
2157 * Whether install script can install drivers at the very end of installation
2158 * This can be used for installing devices which the OS in question does not
2159 * have out of the box support.
2160 *
2161 * Returns: TRUE if install script supports post-installable drivers, FALSE otherwise.
2162 *
2163 * Since: 0.2.2
2164 */
osinfo_install_script_get_can_post_install_drivers(OsinfoInstallScript * script)2165 gboolean osinfo_install_script_get_can_post_install_drivers(OsinfoInstallScript *script)
2166 {
2167 return osinfo_entity_get_param_value_boolean
2168 (OSINFO_ENTITY(script),
2169 OSINFO_INSTALL_SCRIPT_PROP_CAN_POST_INSTALL_DRIVERS);
2170 }
2171
2172 /**
2173 * osinfo_install_script_get_pre_install_drivers_signing_req:
2174 * @script: the install script
2175 *
2176 * If install script can install drivers at the very beginning of installation,
2177 * this function retrieves the requirement about signed status of drivers.
2178 *
2179 * Returns: (type OsinfoDeviceDriverSigningReq):
2180 *
2181 * Since: 0.2.6
2182 */
osinfo_install_script_get_pre_install_drivers_signing_req(OsinfoInstallScript * script)2183 int osinfo_install_script_get_pre_install_drivers_signing_req(OsinfoInstallScript *script)
2184 {
2185 return osinfo_entity_get_param_value_enum
2186 (OSINFO_ENTITY(script),
2187 OSINFO_INSTALL_SCRIPT_PROP_PRE_INSTALL_DRIVERS_SIGNING_REQ,
2188 OSINFO_TYPE_DEVICE_DRIVER_SIGNING_REQ,
2189 OSINFO_DEVICE_DRIVER_SIGNING_REQ_NONE);
2190 }
2191
2192 /**
2193 * osinfo_install_script_get_post_install_drivers_signing_req:
2194 * @script: the install script
2195 *
2196 * If install script can install drivers at the end of installation, this
2197 * function retrieves the requirement about signed status of drivers.
2198 *
2199 * Returns: (type OsinfoDeviceDriverSigningReq):
2200 *
2201 * Since: 0.2.6
2202 */
osinfo_install_script_get_post_install_drivers_signing_req(OsinfoInstallScript * script)2203 int osinfo_install_script_get_post_install_drivers_signing_req(OsinfoInstallScript *script)
2204 {
2205 return osinfo_entity_get_param_value_enum
2206 (OSINFO_ENTITY(script),
2207 OSINFO_INSTALL_SCRIPT_PROP_POST_INSTALL_DRIVERS_SIGNING_REQ,
2208 OSINFO_TYPE_DEVICE_DRIVER_SIGNING_REQ,
2209 OSINFO_DEVICE_DRIVER_SIGNING_REQ_NONE);
2210 }
2211
2212 /**
2213 * osinfo_install_script_get_injection_methods:
2214 * @script: the install script
2215 *
2216 * Retrieve the supported method to inject the script in to the installation process.
2217 *
2218 * Returns: (type OsinfoInstallScriptInjectionMethod): bitwise-or of
2219 * supported methods for install script injection.
2220 *
2221 * Since: 0.2.10
2222 */
osinfo_install_script_get_injection_methods(OsinfoInstallScript * script)2223 unsigned int osinfo_install_script_get_injection_methods(OsinfoInstallScript *script)
2224 {
2225 return osinfo_entity_get_param_value_int64_with_default
2226 (OSINFO_ENTITY(script),
2227 OSINFO_INSTALL_SCRIPT_PROP_INJECTION_METHOD,
2228 OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK);
2229 }
2230
2231 /**
2232 * osinfo_install_script_get_needs_internet:
2233 * @script: the install script
2234 *
2235 * Some install scripts cannot ensure that they work without an internet connection.
2236 *
2237 * Returns: TRUE if script needs an internet connection, FALSE otherwise
2238 * internet connection.
2239 *
2240 * Since: 0.2.11
2241 */
osinfo_install_script_get_needs_internet(OsinfoInstallScript * script)2242 gboolean osinfo_install_script_get_needs_internet(OsinfoInstallScript *script)
2243 {
2244 return osinfo_entity_get_param_value_boolean_with_default
2245 (OSINFO_ENTITY(script),
2246 OSINFO_INSTALL_SCRIPT_PROP_NEEDS_INTERNET,
2247 FALSE);
2248 }
2249
2250 /**
2251 * osinfo_install_script_set_preferred_injection_method:
2252 * @script: the install script
2253 * @method: one of the injection methods:
2254 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_CDROM,
2255 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK,
2256 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_FLOPPY,
2257 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD,
2258 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_WEB
2259 *
2260 * Set the preferred injection method to be used with the @script
2261 *
2262 * Since: 1.3.0
2263 */
osinfo_install_script_set_preferred_injection_method(OsinfoInstallScript * script,OsinfoInstallScriptInjectionMethod method)2264 void osinfo_install_script_set_preferred_injection_method(OsinfoInstallScript *script,
2265 OsinfoInstallScriptInjectionMethod method)
2266 {
2267 GFlagsClass *flags_class;
2268 guint i;
2269
2270 flags_class = g_type_class_ref(OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD);
2271 for (i = 0; i < flags_class->n_values; i++) {
2272 if ((flags_class->values[i].value & method) != 0) {
2273 osinfo_entity_set_param(OSINFO_ENTITY(script),
2274 OSINFO_INSTALL_SCRIPT_PROP_PREFERRED_INJECTION_METHOD,
2275 flags_class->values[i].value_nick);
2276 break;
2277 }
2278 }
2279 g_type_class_unref(flags_class);
2280 }
2281
2282 /**
2283 * osinfo_install_script_get_preferred_injection_method:
2284 * @script: the install script
2285 *
2286 * Returns: the preferred injection method for the script. If none is set and
2287 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK is supported,
2288 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK is returned, otherwise
2289 * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD is returned.
2290 *
2291 * Since: 1.3.0
2292 */
2293 OsinfoInstallScriptInjectionMethod
osinfo_install_script_get_preferred_injection_method(OsinfoInstallScript * script)2294 osinfo_install_script_get_preferred_injection_method(OsinfoInstallScript *script)
2295 {
2296 GFlagsClass *flags_class;
2297 GFlagsValue *value;
2298 const gchar *nick;
2299 guint supported_methods;
2300
2301 nick = osinfo_entity_get_param_value(OSINFO_ENTITY(script),
2302 OSINFO_INSTALL_SCRIPT_PROP_PREFERRED_INJECTION_METHOD);
2303
2304 if (nick == NULL) {
2305 supported_methods = osinfo_install_script_get_injection_methods(script);
2306 if ((supported_methods & OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK) != 0)
2307 return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK;
2308 else if ((supported_methods & OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD) != 0)
2309 return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD;
2310 else
2311 return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK;
2312 }
2313
2314 flags_class = g_type_class_ref(OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD);
2315 value = g_flags_get_value_by_nick(flags_class, nick);
2316 g_type_class_unref(flags_class);
2317
2318 return value->value;
2319 }
2320
2321 /**
2322 * osinfo_install_script_set_installation_source:
2323 * @script: the install script
2324 * @source: one of the installation sources:
2325 * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA,
2326 * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_NETWORK
2327 *
2328 * Set the installation source to be used with the @script.
2329 *
2330 * Since: 1.3.0
2331 */
osinfo_install_script_set_installation_source(OsinfoInstallScript * script,OsinfoInstallScriptInstallationSource source)2332 void osinfo_install_script_set_installation_source(OsinfoInstallScript *script,
2333 OsinfoInstallScriptInstallationSource source)
2334 {
2335 osinfo_entity_set_param_enum(OSINFO_ENTITY(script),
2336 OSINFO_INSTALL_SCRIPT_PROP_INSTALLATION_SOURCE,
2337 source,
2338 OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE);
2339 }
2340
2341 /**
2342 * osinfo_install_script_get_installation_source:
2343 * @script: the install script
2344 *
2345 * Returns: the installation source to be used with the script. If none is set, it defaults to
2346 * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA.
2347 *
2348 * Since: 1.3.0
2349 */
2350 OsinfoInstallScriptInstallationSource
osinfo_install_script_get_installation_source(OsinfoInstallScript * script)2351 osinfo_install_script_get_installation_source(OsinfoInstallScript *script)
2352 {
2353 return osinfo_entity_get_param_value_enum(OSINFO_ENTITY(script),
2354 OSINFO_INSTALL_SCRIPT_PROP_INSTALLATION_SOURCE,
2355 OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE,
2356 OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA);
2357 }
2358