/* * libosinfo: * * Copyright (C) 2009-2020 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include #include #include #include #include "osinfo_install_script_private.h" /** * SECTION:osinfo_install_script * @short_description: OS install script generation * @see_also: #OsinfoInstallConfig * * #OsinfoInstallScript is an object used to generate an * automated installation script for an OS. The OS * configuration data (language, keyboard, timezone, ...) * comes from an #OsinfoInstallConfig object. */ struct _OsinfoInstallScriptPrivate { gchar *output_prefix; gchar *output_filename; OsinfoInstallConfigParamList *config_params; OsinfoAvatarFormat *avatar; }; G_DEFINE_TYPE_WITH_PRIVATE(OsinfoInstallScript, osinfo_install_script, OSINFO_TYPE_ENTITY); enum { PROP_0, PROP_TEMPLATE_URI, PROP_TEMPLATE_DATA, PROP_PROFILE, PROP_PRODUCT_KEY_FORMAT, PROP_PATH_FORMAT, PROP_AVATAR_FORMAT, PROP_PREFERRED_INJECTION_METHOD, PROP_INSTALLATION_SOURCE, LAST_PROP }; static GParamSpec *properties[LAST_PROP]; typedef struct _OsinfoInstallScriptGenerateData OsinfoInstallScriptGenerateData; typedef struct _OsinfoInstallScriptGenerateOutputData OsinfoInstallScriptGenerateOutputData; typedef struct _OsinfoInstallScriptGenerateSyncData OsinfoInstallScriptGenerateSyncData; static void osinfo_install_script_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object); const gchar *data; switch (property_id) { case PROP_TEMPLATE_URI: data = g_value_get_string(value); if (data) osinfo_entity_set_param(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_URI, data); break; case PROP_TEMPLATE_DATA: data = g_value_get_string(value); if (data) osinfo_entity_set_param(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA, data); break; case PROP_PROFILE: data = g_value_get_string(value); if (data) osinfo_entity_set_param(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PROFILE, data); break; case PROP_PREFERRED_INJECTION_METHOD: osinfo_install_script_set_preferred_injection_method(script, g_value_get_flags(value)); break; case PROP_INSTALLATION_SOURCE: osinfo_install_script_set_installation_source(script, g_value_get_enum(value)); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } static void osinfo_install_script_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object); switch (property_id) { case PROP_TEMPLATE_URI: g_value_set_string(value, osinfo_install_script_get_template_uri(script)); break; case PROP_TEMPLATE_DATA: g_value_set_string(value, osinfo_install_script_get_template_data(script)); break; case PROP_PROFILE: g_value_set_string(value, osinfo_install_script_get_profile(script)); break; case PROP_PRODUCT_KEY_FORMAT: g_value_set_string(value, osinfo_install_script_get_product_key_format(script)); break; case PROP_PATH_FORMAT: g_value_set_enum(value, osinfo_install_script_get_path_format(script)); break; case PROP_AVATAR_FORMAT: g_value_set_object(value, osinfo_install_script_get_avatar_format(script)); break; case PROP_PREFERRED_INJECTION_METHOD: g_value_set_flags(value, osinfo_install_script_get_preferred_injection_method(script)); break; case PROP_INSTALLATION_SOURCE: g_value_set_enum(value, osinfo_install_script_get_installation_source(script)); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } static void osinfo_install_script_finalize(GObject *object) { OsinfoInstallScript *script = OSINFO_INSTALL_SCRIPT(object); g_free(script->priv->output_prefix); g_free(script->priv->output_filename); if (script->priv->config_params) g_object_unref(script->priv->config_params); if (script->priv->avatar) g_object_unref(script->priv->avatar); /* Chain up to the parent class */ G_OBJECT_CLASS(osinfo_install_script_parent_class)->finalize(object); } /* Init functions */ static void osinfo_install_script_class_init(OsinfoInstallScriptClass *klass) { GObjectClass *g_klass = G_OBJECT_CLASS(klass); g_klass->get_property = osinfo_install_script_get_property; g_klass->set_property = osinfo_install_script_set_property; g_klass->finalize = osinfo_install_script_finalize; properties[PROP_TEMPLATE_URI] = g_param_spec_string("template-uri", "TemplateURI", _("URI for install script template"), NULL /* default value */, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); properties[PROP_TEMPLATE_DATA] = g_param_spec_string("template-data", "TemplateData", _("Data for install script template"), NULL /* default value */, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); properties[PROP_PROFILE] = g_param_spec_string("profile", "Profile", _("Install script profile name"), NULL /* default value */, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); properties[PROP_PRODUCT_KEY_FORMAT] = g_param_spec_string("product-key-format", "Product Key Format", _("Product key format mask"), NULL /* default value */, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); properties[PROP_PATH_FORMAT] = g_param_spec_enum("path-format", "Path Format", _("Expected path format"), OSINFO_TYPE_PATH_FORMAT, OSINFO_PATH_FORMAT_UNIX /* default value */, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); properties[PROP_AVATAR_FORMAT] = g_param_spec_object("avatar-format", "Avatar Format", _("Expected avatar format"), OSINFO_TYPE_AVATAR_FORMAT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); properties[PROP_PREFERRED_INJECTION_METHOD] = g_param_spec_flags("preferred-injection-method", "Preferred Injection Method", _("The preferred injection method"), OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD, OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK, /* default value */ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); properties[PROP_INSTALLATION_SOURCE] = g_param_spec_enum("installation-source", "Installation Source", _("The installation source to be used"), OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE, OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(g_klass, LAST_PROP, properties); } void osinfo_install_script_add_config_param(OsinfoInstallScript *script, OsinfoInstallConfigParam *param) { g_return_if_fail(OSINFO_IS_INSTALL_SCRIPT(script)); g_return_if_fail(OSINFO_IS_INSTALL_CONFIG_PARAM(param)); osinfo_list_add(OSINFO_LIST(script->priv->config_params), OSINFO_ENTITY(param)); } /** * osinfo_install_script_has_config_param: * @script: the install script * @config_param: an #OsinfoInstallConfigParam * * Returns whether the @script has the @config_param searched or not. * * This code assumes that the 'id' and 'name' entity properties are the same. * * Since: 0.2.0 */ gboolean osinfo_install_script_has_config_param(OsinfoInstallScript *script, OsinfoInstallConfigParam *config_param) { const char *name = osinfo_install_config_param_get_name(config_param); return osinfo_install_script_has_config_param_name(script, name); } /** * osinfo_install_script_has_config_param_name: * @script: the install script * @name: the configuration parameter name * * Returns whether the @script has a configuration parameter matching @name or not. * * Since: 0.2.0 */ gboolean osinfo_install_script_has_config_param_name(OsinfoInstallScript *script, const gchar *name) { OsinfoList *l = OSINFO_LIST(script->priv->config_params); return (osinfo_list_find_by_id(l, name) != NULL); } /** * osinfo_install_script_get_config_param_list: * @script: the install script * * Get the list of valid config parameters for @script. * * Returns: (transfer container) (element-type OsinfoInstallScript): the * list of valid #OsinfoInstallConfigParam parameters. Free with * g_list_free() when done. The elements are owned by libosinfo. * * Since: 0.2.0 */ GList *osinfo_install_script_get_config_param_list(OsinfoInstallScript *script) { return osinfo_list_get_elements(OSINFO_LIST(script->priv->config_params)); } /** * osinfo_install_script_get_config_params: * @script: the install script * * Get the list of valid config parameters for @script. * * Returns: (transfer none): the list of valid #OsinfoInstallConfigParam * parameters. * * Since: 0.2.3 */ OsinfoInstallConfigParamList *osinfo_install_script_get_config_params(OsinfoInstallScript *script) { return script->priv->config_params; } /** * osinfo_install_script_get_config_param: * @script: the install script * @name: name of the parameter * * Get a config param from the config param's list * * Returns: (transfer full): the sought config param, if exists. * NULL otherwise. * * This code assumes that the 'id' and 'name' entity properties are * the same. * * Since: 0.2.1 */ OsinfoInstallConfigParam * osinfo_install_script_get_config_param(OsinfoInstallScript *script, const gchar *name) { OsinfoInstallConfigParam *param; OsinfoList *l = OSINFO_LIST(script->priv->config_params); param = OSINFO_INSTALL_CONFIG_PARAM(osinfo_list_find_by_id(l, name)); if (param == NULL) return NULL; return g_object_ref(G_OBJECT(param)); } static void osinfo_install_script_init(OsinfoInstallScript *list) { list->priv = osinfo_install_script_get_instance_private(list); list->priv->config_params = osinfo_install_config_paramlist_new(); } /** * oisinfo_install_script_new: * @id: a unique identifier * * Construct an empty new install script. * * Returns: (transfer full): a new install script * * Since: 0.2.0 */ OsinfoInstallScript *osinfo_install_script_new(const gchar *id) { return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT, "id", id, NULL); } /** * osinfo_install_script_new_data: * @id: a unique identifier * @profile: the profile of script * @templateData: style sheet data * * Construct a new install script from stylesheet data * * Returns: (transfer full): an new install script * * Since: 0.2.0 */ OsinfoInstallScript *osinfo_install_script_new_data(const gchar *id, const gchar *profile, const gchar *templateData) { return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT, "id", id, "profile", profile, "template-data", templateData, NULL); } /** * osinfo_install_script_new_uri: * @id: a unique identifier * @profile: the profile of script * @templateUri: style sheet URI * * Construct a new install script from a stylesheet URI * * Returns: (transfer full): an new install script * * Since: 0.2.0 */ OsinfoInstallScript *osinfo_install_script_new_uri(const gchar *id, const gchar *profile, const gchar *templateUri) { return g_object_new(OSINFO_TYPE_INSTALL_SCRIPT, "id", id, "profile", profile, "template-uri", templateUri, NULL); } /** * osinfo_install_script_get_template_uri: * @script: the install script * * Returns the stylesheet URI used to construct the install script. * * Since: 0.2.0 */ const gchar *osinfo_install_script_get_template_uri(OsinfoInstallScript *script) { return osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_URI); } /** * osinfo_install_script_get_template_data: * @script: the install script * * Returns the stylesheet data used to construct the install script. * * Since: 0.2.0 */ const gchar *osinfo_install_script_get_template_data(OsinfoInstallScript *script) { return osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA); } /** * osinfo_install_script_get_profile: * @script: the install script * * Returns a string representing the install script profile that's going to be * used. * * The values supported are "jeos" for minimal installations and "desktop" for * workstation/desktop installations. * * Since: 0.2.0 */ const gchar *osinfo_install_script_get_profile(OsinfoInstallScript *script) { return osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PROFILE); } /** * osinfo_install_script_get_product_key_format: * @script: the install script * * If this function returns a non-NULL string, it means that the @script * requires you to specify product registration key through #OsinfoInstallConfig * instance passed to script generation methods. * * The returned string specifies the expected format of the product key like this: * * @ - any character * % - alphabet * # - numeric character * $ - alphanumeric character * * All other characters represent themselves. * * For example in case of installer for Microsoft Windows XP, you'll get * "$$$$$-$$$$$-$$$$$-$$$$$-$$$$$". That means a product key consists of 24 * alphanumeric characters and 4 '-' characters at (0-based) indices 5, 11, 17 * and 23. * * Returns: (transfer none): Product key format mask, or NULL. * * Since: 0.2.2 */ const gchar *osinfo_install_script_get_product_key_format(OsinfoInstallScript *script) { return osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PRODUCT_KEY_FORMAT); } /** * osinfo_install_script_set_output_prefix: * @script: the install script * @prefix: a prefix to be added to the file generated * * Mind that not all installers support any name for the installer scripts. * * Since: 0.2.0 */ void osinfo_install_script_set_output_prefix(OsinfoInstallScript *script, const gchar *prefix) { const char *output_filename = osinfo_install_script_get_expected_filename(script); g_free(script->priv->output_prefix); script->priv->output_prefix = g_strdup(prefix); /* update output_filename whenever output_prefix is changed */ g_free(script->priv->output_filename); script->priv->output_filename = g_strjoin("-", prefix, output_filename, NULL); } /** * osinfo_install_script_get_output_prefix: * @script: the install script * * Returns: the prefix of the file generated * * Since: 0.2.8 */ const gchar *osinfo_install_script_get_output_prefix(OsinfoInstallScript *script) { return script->priv->output_prefix; } /** * osinfo_install_script_get_expected_filename: * @script: the install script * * Some operating systems (as Windows) expect that script filename has * particular name to work. * * Returns: (transfer none): the expected script filename * * Since: 0.2.1 */ const gchar *osinfo_install_script_get_expected_filename(OsinfoInstallScript *script) { return osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_EXPECTED_FILENAME); } /** * osinfo_install_script_get_output_filename: * @script: the install script * * Some operating systems are able to use any script filename, allowing the * application to set the filename as desired. libosinfo provides this * functionality by set the expected filename's prefix using * osinfo_install_script_set_output_prefix() function. * * Returns: (transfer none): the output script filename * * Since: 0.2.0 */ const gchar *osinfo_install_script_get_output_filename(OsinfoInstallScript *script) { if (script->priv->output_filename == NULL) return osinfo_install_script_get_expected_filename(script); return script->priv->output_filename; } void osinfo_install_script_set_avatar_format(OsinfoInstallScript *script, OsinfoAvatarFormat *avatar) { g_return_if_fail(OSINFO_IS_INSTALL_SCRIPT(script)); g_return_if_fail(OSINFO_IS_AVATAR_FORMAT(avatar)); if (script->priv->avatar != NULL) g_object_unref(script->priv->avatar); script->priv->avatar = g_object_ref(avatar); } /** * osinfo_install_script_get_avatar_format: * @script: the install script * * Some install scripts have restrictions on the format of the user avatar. Use * this method to retrieve those restrictions in the form of an * #OsinfoAvatarFormat instance. * * Returns: (transfer none): The avatar format, or NULL if there is no restrictions on the * format of avatar * * Since: 0.2.2 */ OsinfoAvatarFormat *osinfo_install_script_get_avatar_format(OsinfoInstallScript *script) { g_return_val_if_fail(OSINFO_IS_INSTALL_SCRIPT(script), NULL); if (script->priv->avatar == NULL) return NULL; return script->priv->avatar; } struct _OsinfoInstallScriptGenerateData { GTask *res; OsinfoOs *os; OsinfoMedia *media; OsinfoTree *tree; OsinfoInstallConfig *config; OsinfoInstallScript *script; }; static void osinfo_install_script_generate_data_free(OsinfoInstallScriptGenerateData *data) { g_object_unref(data->os); if (data->media != NULL) g_object_unref(data->media); if (data->tree != NULL) g_object_unref(data->tree); g_object_unref(data->config); g_object_unref(data->script); g_object_unref(data->res); g_free(data); } struct _OsinfoInstallScriptGenerateOutputData { GTask *res; GError *error; GFile *file; GFileOutputStream *stream; gchar *output; gssize output_len; gssize output_pos; }; static void osinfo_install_script_generate_output_data_free(OsinfoInstallScriptGenerateOutputData *data) { g_object_unref(data->stream); g_object_unref(data->res); g_free(data); } static xsltStylesheetPtr osinfo_install_script_load_template(const gchar *uri, const gchar *template, GError **error) { xsltStylesheetPtr xslt = NULL; xmlDocPtr doc = NULL; xmlParserCtxtPtr pctxt; /* Set up a parser context so we can catch the details of XML errors. */ pctxt = xmlNewParserCtxt(); if (!pctxt || !pctxt->sax) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to create XML parser context")); goto cleanup; } if (!(doc = xmlCtxtReadDoc(pctxt, BAD_CAST template, uri, NULL, XML_PARSE_NONET | XML_PARSE_NOWARNING))) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to read XSL template")); goto cleanup; } if (!(xslt = xsltParseStylesheetDoc(doc))) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to parse XSL template")); goto cleanup; } cleanup: xmlFreeParserCtxt(pctxt); return xslt; } static OsinfoDatamap * osinfo_install_script_get_param_datamap(OsinfoInstallScript *script, const gchar *param_name) { OsinfoEntity *entity; OsinfoInstallConfigParam *param; if (!script->priv->config_params) return NULL; entity = osinfo_list_find_by_id(OSINFO_LIST(script->priv->config_params), param_name); if (entity == NULL) { g_debug("%s is not a known parameter for this config", param_name); return NULL; } param = OSINFO_INSTALL_CONFIG_PARAM(entity); return osinfo_install_config_param_get_value_map(param); } static GList * osinfo_install_script_get_param_value_list(OsinfoInstallScript *script, OsinfoInstallConfig *config, const gchar *key) { GList *values; GList *it; OsinfoDatamap *map; values = osinfo_entity_get_param_value_list(OSINFO_ENTITY(config), key); if (values == NULL) return NULL; map = osinfo_install_script_get_param_datamap(script, key); if (map != NULL) { for (it = values; it != NULL; it = it->next) { const char *transformed_value; transformed_value = osinfo_datamap_lookup(map, it->data); if (transformed_value == NULL) { continue; } it->data = (gpointer)transformed_value; } } return values; } static void propagate_libxml_error(GError **error, const char *format, ...) G_GNUC_PRINTF(2, 3); static void propagate_libxml_error(GError **error, const char *format, ...) { xmlErrorPtr err = xmlGetLastError(); char *prefix; va_list ap; va_start(ap, format); prefix = g_strdup_vprintf(format, ap); va_end(ap); if (err == NULL) { g_set_error_literal(error, OSINFO_ERROR, 0, prefix); } else { g_set_error(error, OSINFO_ERROR, 0, "%s: %s", prefix, err->message); } g_free(prefix); } static xmlNodePtr osinfo_install_script_generate_entity_xml(OsinfoInstallScript *script, OsinfoEntity *entity, const gchar *name, GError **error) { xmlNodePtr node = NULL; xmlNodePtr data = NULL; GList *keys = NULL; GList *tmp1; if (!(node = xmlNewDocNode(NULL, NULL, (xmlChar*)name, NULL))) { propagate_libxml_error(error, _("Unable to create XML node '%s'"), name); goto error; } if (!(data = xmlNewDocRawNode(NULL, NULL, (const xmlChar*)"id", (const xmlChar*)osinfo_entity_get_id(entity)))) { propagate_libxml_error(error, _("Unable to create XML node 'id'")); goto error; } if (!(xmlAddChild(node, data))) { propagate_libxml_error(error, _("Unable to add XML child")); goto error; } data = NULL; tmp1 = keys = osinfo_entity_get_param_keys(entity); while (tmp1) { GList *values; GList *tmp2; if (OSINFO_IS_INSTALL_CONFIG(entity)) values = osinfo_install_script_get_param_value_list(script, OSINFO_INSTALL_CONFIG(entity), tmp1->data); else values = osinfo_entity_get_param_value_list(entity, tmp1->data); tmp2 = values; while (tmp2) { if (!(data = xmlNewDocRawNode(NULL, NULL, (const xmlChar*)tmp1->data, (const xmlChar*)tmp2->data))) { propagate_libxml_error(error, _("Unable to create XML node '%s'"), (const gchar *)tmp1->data); goto error; } if (!(xmlAddChild(node, data))) { propagate_libxml_error(error, _("Unable to add XML child")); goto error; } data = NULL; tmp2 = tmp2->next; } g_list_free(values); tmp1 = tmp1->next; } g_list_free(keys); return node; error: g_list_free(keys); xmlFreeNode(data); xmlFreeNode(node); return NULL; } static xmlDocPtr osinfo_install_script_generate_config_xml(OsinfoInstallScript *script, OsinfoOs *os, OsinfoMedia *media, OsinfoTree *tree, OsinfoInstallConfig *config, const gchar *node_name, GError **error) { xmlDocPtr doc = xmlNewDoc((xmlChar *)"1.0"); xmlNodePtr root; xmlNodePtr node; root = xmlNewDocNode(NULL, NULL, (xmlChar*)node_name, NULL); xmlDocSetRootElement(doc, root); if (!(node = osinfo_install_script_generate_entity_xml(script, OSINFO_ENTITY(script), "script", error))) goto error; if (!(xmlAddChild(root, node))) { propagate_libxml_error(error, _("Unable to set XML root")); goto error; } if (!(node = osinfo_install_script_generate_entity_xml(script, OSINFO_ENTITY(os), "os", error))) goto error; if (!(xmlAddChild(root, node))) { propagate_libxml_error(error, _("Unable to set XML root")); goto error; } if (media != NULL) { if (!(node = osinfo_install_script_generate_entity_xml(script, OSINFO_ENTITY(media), "media", error))) goto error; if (!(xmlAddChild(root, node))) { propagate_libxml_error(error, _("Unable to set 'media' node")); goto error; } } if (tree != NULL) { if (!(node = osinfo_install_script_generate_entity_xml(script, OSINFO_ENTITY(tree), "tree", error))) goto error; if (!(xmlAddChild(root, node))) { propagate_libxml_error(error, _("Unable to set 'tree' node")); goto error; } } if (!(node = osinfo_install_script_generate_entity_xml(script, OSINFO_ENTITY(config), "config", error))) goto error; if (!(xmlAddChild(root, node))) { propagate_libxml_error(error, _("Unable to set XML root")); goto error; } return doc; error: xmlFreeDoc(doc); doc = NULL; return NULL; } static gchar *osinfo_install_script_apply_xslt(xsltStylesheetPtr ss, xmlDocPtr doc, GError **error) { xsltTransformContextPtr ctxt; xmlChar *xsltResult; gchar *ret = NULL; xmlDocPtr docOut = NULL; int len; if (!(ctxt = xsltNewTransformContext(ss, doc))) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to create XSL transform context")); goto cleanup; } if (!(docOut = xsltApplyStylesheetUser(ss, doc, NULL, NULL, NULL, ctxt))) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to apply XSL transform context")); goto cleanup; } if (xsltSaveResultToString(&xsltResult, &len, docOut, ss) < 0) { g_set_error_literal(error, OSINFO_ERROR, 0, _("Unable to convert XSL output to string")); goto cleanup; } ret = g_strdup((gchar *)xsltResult); xmlFree(xsltResult); cleanup: xmlFreeDoc(docOut); xsltFreeTransformContext(ctxt); return ret; } static gboolean 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) { gboolean ret = FALSE; xsltStylesheetPtr templateXsl = osinfo_install_script_load_template(templateUri, template, error); xmlDocPtr configXml = osinfo_install_script_generate_config_xml(script, os, media, tree, config, node_name, error); if (!templateXsl || !configXml) goto cleanup; if (!(*result = osinfo_install_script_apply_xslt(templateXsl, configXml, error))) goto cleanup; ret = TRUE; cleanup: xsltFreeStylesheet(templateXsl); xmlFreeDoc(configXml); return ret; } static void osinfo_install_script_template_loaded(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateData *data = user_data; GError *error = NULL; gchar *input = NULL; gchar *output = NULL; gsize length = 0; GFile *file = G_FILE(src); gchar *uri = g_file_get_uri(file); if (!g_file_load_contents_finish(file, res, &input, &length, NULL, &error)) { g_prefix_error(&error, _("Failed to load script template %s: "), uri); g_task_return_error(data->res, error); goto cleanup; } if (!osinfo_install_script_apply_template(data->script, data->os, data->media, data->tree, uri, input, "install-script-config", &output, data->config, &error)) { g_prefix_error(&error, _("Failed to apply script template %s: "), uri); g_task_return_error(data->res, error); goto cleanup; } g_task_return_pointer(data->res, output, g_free); cleanup: g_free(input); osinfo_install_script_generate_data_free(data); g_free(uri); } static void osinfo_install_script_generate_async_common(OsinfoInstallScript *script, OsinfoOs *os, OsinfoMedia *media, OsinfoTree *tree, OsinfoInstallConfig *config, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { OsinfoInstallScriptGenerateData *data; const gchar *templateData; const gchar *templateUri; g_return_if_fail(os != NULL); data = g_new0(OsinfoInstallScriptGenerateData, 1); templateData = osinfo_install_script_get_template_data(script); templateUri = osinfo_install_script_get_template_uri(script); data->os = g_object_ref(os); if (media != NULL) data->media = g_object_ref(media); if (tree != NULL) data->tree = g_object_ref(tree); data->config = g_object_ref(config); data->script = g_object_ref(script); data->res = g_task_new(G_OBJECT(script), cancellable, callback, user_data); if (templateData) { GError *error = NULL; gchar *output; if (!osinfo_install_script_apply_template(script, os, media, NULL, "", templateData, "install-script-config", &output, data->config, &error)) { g_prefix_error(&error, "%s", _("Failed to apply script template: ")); g_task_return_error(data->res, error); osinfo_install_script_generate_data_free(data); return; } g_task_return_pointer(data->res, output, g_free); osinfo_install_script_generate_data_free(data); } else { GFile *file = g_file_new_for_uri(templateUri); g_file_load_contents_async(file, cancellable, osinfo_install_script_template_loaded, data); g_object_unref(file); } } /** * osinfo_install_script_generate_async: * @script: the install script * @os: the os * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate(). From the callback, * call #osinfo_install_script_generate_finish() to conclude this call and get * the generated script. * * If you are generating the script for a specific media, it is recommended that * you use #osinfo_install_script_generate_for_media_async() instead. * * Since: 0.2.0 */ void osinfo_install_script_generate_async(OsinfoInstallScript *script, OsinfoOs *os, OsinfoInstallConfig *config, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { osinfo_install_script_generate_async_common(script, os, NULL, NULL, config, cancellable, callback, user_data); } static gpointer osinfo_install_script_generate_finish_common(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { GTask *task = G_TASK(res); g_return_val_if_fail(error == NULL || *error == NULL, NULL); return g_task_propagate_pointer(task, error); } /** * osinfo_install_script_generate_finish: * @script: the install script * @res: a #GAsyncResult * @error: The location where to store any error, or NULL * * Returns: (transfer full): the generated script, or NULL on error * * Since: 0.2.0 */ gchar *osinfo_install_script_generate_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } /** * osinfo_install_script_generate_for_media_finish: * @script: the install script * @res: a #GAsyncResult * @error: The location where to store any error, or NULL * * Returns: (transfer full): the generated script, or NULL on error * * Since: 0.2.12 */ gchar *osinfo_install_script_generate_for_media_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } /** * osinfo_install_script_generate_for_tree_finish: * @script: the install script * @res: a #GAsyncResult * @error: the location where to story any error, or NULL * * Returns: (transfer full): the generated script, or NULL or error * * Since: 1.6.0 */ gchar *osinfo_install_script_generate_for_tree_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } /** * osinfo_install_script_generate_output_finish: * @script: the install script * @res: a #GAsyncResult * @error: The location where to store any error, or NULL * * Returns: (transfer full): a file containing the script, or NULL on error * * Since: 0.2.3 */ GFile *osinfo_install_script_generate_output_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } /** * osinfo_install_script_generate_output_for_media_finish: * @script: the install script * @res: a #GAsyncResult * @error: the location where to store any error, or NULL * * Returns: (transfer full): a file containing the script, or NULL on error. * * Since: 0.2.12 */ GFile *osinfo_install_script_generate_output_for_media_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } /** * osinfo_install_script_generate_output_for_tree_finish: * @script: the install script * @res: a #GAsyncResult * @error: the location where to store any error, or NULL * * Returns: (transfer full): a file containing the script, or NULL on error. * * Since: 1.6.0 */ GFile *osinfo_install_script_generate_output_for_tree_finish(OsinfoInstallScript *script, GAsyncResult *res, GError **error) { return osinfo_install_script_generate_finish_common(script, res, error); } struct _OsinfoInstallScriptGenerateSyncData { GMainLoop *loop; GError *error; gchar *output; GFile *file; }; static void osinfo_install_script_generate_output_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->file = osinfo_install_script_generate_output_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } static void osinfo_install_script_generate_output_for_media_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->file = osinfo_install_script_generate_output_for_media_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } static void osinfo_install_script_generate_output_for_tree_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->file = osinfo_install_script_generate_output_for_tree_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } static void osinfo_install_script_generate_output_close_file(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateOutputData *data = user_data; g_output_stream_close_finish(G_OUTPUT_STREAM(src), res, &data->error); g_task_return_pointer(data->res, data->file, NULL); osinfo_install_script_generate_output_data_free(data); } static void osinfo_install_script_generate_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->output = osinfo_install_script_generate_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } /** * osinfo_install_script_generate: * @script: the install script * @os: the os * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script. * * Returns: (transfer full): the script as string. * * If you are generating the script for a specific media, it is recommended * that you use #osinfo_install_script_generate_for_media() instead. * * If you are generating the script for a specific tree, it is recommended * that you use #osinfo_install_script_generate_for_tree() in instead. * * Since: 0.2.0 */ gchar *osinfo_install_script_generate(OsinfoInstallScript *script, OsinfoOs *os, OsinfoInstallConfig *config, GCancellable *cancellable, GError **error) { GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); OsinfoInstallScriptGenerateSyncData data = { loop, NULL, NULL, NULL }; osinfo_install_script_generate_async(script, os, config, cancellable, osinfo_install_script_generate_done, &data); g_main_loop_run(loop); if (data.error) g_propagate_error(error, data.error); g_main_loop_unref(loop); return data.output; } /** * osinfo_install_script_generate_for_media_async: * @script: the install script * @media: the media * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate_for_media(). From the * callback, call #osinfo_install_script_generate_for_media_finish() to * conclude this call and get the generated script. * * Since: 0.2.12 */ void osinfo_install_script_generate_for_media_async(OsinfoInstallScript *script, OsinfoMedia *media, OsinfoInstallConfig *config, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { OsinfoOs *os; g_return_if_fail(media != NULL); os = osinfo_media_get_os(media); osinfo_install_script_generate_async_common(script, os, media, NULL, config, cancellable, callback, user_data); g_object_unref(os); } static void osinfo_install_script_generate_for_media_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->output = osinfo_install_script_generate_for_media_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } /** * osinfo_install_script_generate_for_media: * @script: the install script * @media: the media * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script. The media @media must have been identified * successfully using #osinfo_db_identify_media() before calling this function. * * Returns: (transfer full): the script as string. * * Since: 0.2.12 */ gchar *osinfo_install_script_generate_for_media(OsinfoInstallScript *script, OsinfoMedia *media, OsinfoInstallConfig *config, GCancellable *cancellable, GError **error) { GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); OsinfoInstallScriptGenerateSyncData data = { loop, NULL, NULL, NULL }; osinfo_install_script_generate_for_media_async(script, media, config, cancellable, osinfo_install_script_generate_for_media_done, &data); g_main_loop_run(loop); if (data.error) g_propagate_error(error, data.error); g_main_loop_unref(loop); return data.output; } /** * osinfo_install_script_generate_for_tree_async: * @script: the install script * @tree: the tree * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate_for_tree(). From the * callback, call #osinfo_install_script_generate_for_tree_finish() to * conclude this call and get the generated script. * * Since: 1.6.0 */ void osinfo_install_script_generate_for_tree_async(OsinfoInstallScript *script, OsinfoTree *tree, OsinfoInstallConfig *config, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { OsinfoOs *os; g_return_if_fail(tree != NULL); os = osinfo_tree_get_os(tree); osinfo_install_script_generate_async_common(script, os, NULL, tree, config, cancellable, callback, user_data); g_object_unref(os); } static void osinfo_install_script_generate_for_tree_done(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateSyncData *data = user_data; data->output = osinfo_install_script_generate_for_tree_finish(OSINFO_INSTALL_SCRIPT(src), res, &data->error); g_main_loop_quit(data->loop); } /** * osinfo_install_script_generate_for_tree: * @script: the install script * @tree: the tree * @config: the install script config * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script. The tree @tree must have been identified * successfully using #osinfo_db_identify_tree() before calling this function. * * Returns: (transfer full): the script as string. * * Since: 1.6.0 */ gchar *osinfo_install_script_generate_for_tree(OsinfoInstallScript *script, OsinfoTree *tree, OsinfoInstallConfig *config, GCancellable *cancellable, GError **error) { GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); OsinfoInstallScriptGenerateSyncData data = { loop, NULL, NULL, NULL }; osinfo_install_script_generate_for_tree_async(script, tree, config, cancellable, osinfo_install_script_generate_for_tree_done, &data); g_main_loop_run(loop); if (data.error) g_propagate_error(error, data.error); g_main_loop_unref(loop); return data.output; } static void osinfo_install_script_generate_output_write_file(GObject *src, GAsyncResult *res, gpointer user_data) { OsinfoInstallScriptGenerateOutputData *data = user_data; if (data->stream == NULL) data->stream = g_file_replace_finish(G_FILE(src), res, &data->error); else data->output_pos += g_output_stream_write_finish(G_OUTPUT_STREAM(data->stream), res, &data->error); if (data->output_pos < data->output_len) { g_output_stream_write_async(G_OUTPUT_STREAM(data->stream), data->output + data->output_pos, data->output_len - data->output_pos, G_PRIORITY_DEFAULT, g_task_get_cancellable(data->res), osinfo_install_script_generate_output_write_file, data); } else { g_output_stream_close_async(G_OUTPUT_STREAM(data->stream), G_PRIORITY_DEFAULT, g_task_get_cancellable(data->res), osinfo_install_script_generate_output_close_file, data); } } static void 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) { const gchar *filename; const gchar *prefix; OsinfoInstallScriptGenerateOutputData *data = g_new0(OsinfoInstallScriptGenerateOutputData, 1); OsinfoInstallScriptGenerateSyncData *data_sync = user_data; data->res = g_task_new(G_OBJECT(script), cancellable, callback, user_data); data->error = data_sync->error; if (media != NULL) { data->output = osinfo_install_script_generate_for_media(script, media, config, cancellable, &data->error); } else if (tree != NULL) { data->output = osinfo_install_script_generate_for_tree(script, tree, config, cancellable, &data->error); } else { data->output = osinfo_install_script_generate(script, os, config, cancellable, &data->error); } data->output_pos = 0; data->output_len = strlen(data->output); prefix = osinfo_install_script_get_output_prefix(script); filename = osinfo_install_script_get_output_filename(script); if (prefix) { gchar *output_filename = g_strdup_printf("%s-%s", prefix, filename); data->file = g_file_get_child(output_dir, output_filename); g_free(output_filename); } else { data->file = g_file_get_child(output_dir, filename); } g_file_replace_async(data->file, NULL, TRUE, G_FILE_CREATE_NONE, G_PRIORITY_DEFAULT, cancellable, osinfo_install_script_generate_output_write_file, data); } /** * osinfo_install_script_generate_output_async: * @script: the install script * @os: the os * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate_output(). From the * callback, call #osinfo_install_script_generate_output_finish() to conclude * this call and get the generated script. * * If you are generating the script for a specific media, it is recommended that * you use #osinfo_install_script_generate_output_for_media_async() instead. * * Since: 0.2.0 */ void osinfo_install_script_generate_output_async(OsinfoInstallScript *script, OsinfoOs *os, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { osinfo_install_script_generate_output_async_common(script, os, NULL, NULL, config, output_dir, cancellable, callback, user_data); } static GFile *osinfo_install_script_generate_output_common(OsinfoInstallScript *script, OsinfoOs *os, OsinfoMedia *media, OsinfoTree *tree, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GError **error) { GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); OsinfoInstallScriptGenerateSyncData data = { loop, NULL, NULL, NULL }; if (media != NULL) { osinfo_install_script_generate_output_for_media_async (script, media, config, output_dir, cancellable, osinfo_install_script_generate_output_for_media_done, &data); } else if (tree != NULL) { osinfo_install_script_generate_output_for_tree_async (script, tree, config, output_dir, cancellable, osinfo_install_script_generate_output_for_tree_done, &data); } else { osinfo_install_script_generate_output_async (script, os, config, output_dir, cancellable, osinfo_install_script_generate_output_done, &data); } g_main_loop_run(loop); if (data.error) g_propagate_error(error, data.error); g_main_loop_unref(loop); return data.file; } /** * osinfo_install_script_generate_output: * @script: the install script * @os: the os entity * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script that is written to the returned file. * * Returns: (transfer full): a file containing the script * * If you are generating the script for a specific media, it is recommended * that you use #osinfo_install_script_generate_output_for_media() instead. * * If you are generating the script for a specific tree, it is recommended * that you use #osinfo_install_script_generate_output_for_tree() instead. * * Since: 0.2.0 */ GFile *osinfo_install_script_generate_output(OsinfoInstallScript *script, OsinfoOs *os, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GError **error) { return osinfo_install_script_generate_output_common(script, os, NULL, NULL, config, output_dir, cancellable, error); } /** * osinfo_install_script_generate_output_for_media_async: * @script: the install script * @media: the media * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate_output_for_media(). * From the callback, call * #osinfo_install_script_generate_output_for_media_finish() to conclude this * call and get the generated file. * * Since: 0.2.12 */ void osinfo_install_script_generate_output_for_media_async(OsinfoInstallScript *script, OsinfoMedia *media, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { osinfo_install_script_generate_output_async_common(script, NULL, media, NULL, config, output_dir, cancellable, callback, user_data); } /** * osinfo_install_script_generate_output_for_media: * @script: the install script * @media: the media * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script that is written to the returned file. * * Returns: (transfer full): a file containing the script. * * Since: 0.2.12 */ GFile *osinfo_install_script_generate_output_for_media(OsinfoInstallScript *script, OsinfoMedia *media, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GError **error) { return osinfo_install_script_generate_output_common(script, NULL, media, NULL, config, output_dir, cancellable, error); } /** * osinfo_install_script_generate_output_for_tree_async: * @script: the install script * @tree: the tree * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: Function to call when result of this call is ready * @user_data: The user data to pass to @callback, or %NULL * * Asynchronous variant of #osinfo_install_script_generate_output_for_tree(). * From the callback, call * #osinfo_install_script_generate_output_for_tree_finish() to conclude this * call and get the generated file. * * Since: 1.6.0 */ void osinfo_install_script_generate_output_for_tree_async(OsinfoInstallScript *script, OsinfoTree *tree, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { osinfo_install_script_generate_output_async_common(script, NULL, NULL, tree, config, output_dir, cancellable, callback, user_data); } /** * osinfo_install_script_generate_output_for_tree: * @script: the install script * @tree: the tree * @config: the install script config * @output_dir: the directory where the file containing the output script * will be written * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: The location where to store any error, or %NULL * * Creates an install script that is written to the returned file. * * Returns: (transfer full): a file containing the script. * * Since: 1.6.0 */ GFile *osinfo_install_script_generate_output_for_tree(OsinfoInstallScript *script, OsinfoTree *tree, OsinfoInstallConfig *config, GFile *output_dir, GCancellable *cancellable, GError **error) { return osinfo_install_script_generate_output_common(script, NULL, NULL, tree, config, output_dir, cancellable, error); } /** * osinfo_install_script_generate_command_line: * @script: the install script * @os: the os entity * @config: the install script config * * Some install scripts need to pass a command line to the kernel, Such install * scripts belong to OSs that provide paths to the kernel and initrd files that * can be used to directly boot * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot) * the OS in order to pass the needed commandline to it. * * If you are generating the command line for a specific media, it is * recommended that you use * #osinfo_install_script_generate_command_line_for_media() instead. * * If you are generating the command line for a specific tree, it is * recommended that you use * #osinfo_install_script_generate_command_line_for_tree() instead. * * Returns: (transfer full): The generated command line string, NULL otherwise. * * Since: 0.2.7 */ gchar *osinfo_install_script_generate_command_line(OsinfoInstallScript *script, OsinfoOs *os, OsinfoInstallConfig *config) { const gchar *templateData = osinfo_install_script_get_template_data(script); gchar *output = NULL; if (templateData) { GError *error = NULL; if (!osinfo_install_script_apply_template(script, os, NULL, NULL, "", templateData, "command-line", &output, config, &error)) { g_prefix_error(&error, "%s", _("Failed to apply script template: ")); } } return output; } /** * osinfo_install_script_generate_command_line_for_media: * @script: the install script * @media: the media * @config: the install script config * * Some install scripts need to pass a command line to the kernel, Such install * scripts belong to OSs that provide paths to the kernel and initrd files that * can be used to directly boot * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot) * the OS in order to pass the needed commandline to it. * * The media @media must have been identified successfully using * #osinfo_db_identify_media() before calling this function. * * Returns: (transfer full): The generated command line string, NULL otherwise. * * Since: 0.2.12 */ gchar *osinfo_install_script_generate_command_line_for_media(OsinfoInstallScript *script, OsinfoMedia *media, OsinfoInstallConfig *config) { const gchar *templateData = osinfo_install_script_get_template_data(script); gchar *output = NULL; OsinfoOs *os; g_return_val_if_fail(media != NULL, NULL); os = osinfo_media_get_os(media); g_return_val_if_fail(os != NULL, NULL); if (templateData) { GError *error = NULL; if (!osinfo_install_script_apply_template(script, os, media, NULL, "", templateData, "command-line", &output, config, &error)) { g_prefix_error(&error, "%s", _("Failed to apply script template: ")); } } g_object_unref(os); return output; } /** * osinfo_install_script_generate_command_line_for_tree: * @script: the install script * @tree: the tree * @config: the install script config * * Some install scripts need to pass a command line to the kernel, Such install * scripts belong to OSs that provide paths to the kernel and initrd files that * can be used to directly boot * (http://wiki.qemu.org/download/qemu-doc.html#direct_005flinux_005fboot) * the OS in order to pass the needed commandline to it. * * The tree @tree must have been identified successfully using * #osinfo_db_identify_tree() before calling this function. * * Returns: (transfer full): The generated command line string, NULL otherwise. * * Since: 1.6.0 */ gchar *osinfo_install_script_generate_command_line_for_tree(OsinfoInstallScript *script, OsinfoTree *tree, OsinfoInstallConfig *config) { const gchar *templateData = osinfo_install_script_get_template_data(script); gchar *output = NULL; OsinfoOs *os; g_return_val_if_fail(tree != NULL, NULL); os = osinfo_tree_get_os(tree); g_return_val_if_fail(os != NULL, NULL); if (templateData) { GError *error = NULL; if (!osinfo_install_script_apply_template(script, os, NULL, tree, "", templateData, "command-line", &output, config, &error)) { g_prefix_error(&error, "%s", _("Failed to apply script template: ")); } } g_object_unref(os); return output; } /** * osinfo_install_script_get_path_format: * @script: the install script * * Returns the path format to be used for the files and disks which will * be used during the installation. * * Returns: the path format to be used. OSINFO_PATH_FORMAT_UNIX is the * default option. * * Since: 0.2.2 */ OsinfoPathFormat osinfo_install_script_get_path_format(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_enum (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PATH_FORMAT, OSINFO_TYPE_PATH_FORMAT, OSINFO_PATH_FORMAT_UNIX); } /** * osinfo_install_script_get_can_pre_install_drivers: * @script: the install script * * Whether install script can install drivers at the very beginning of * installation. This is needed for devices for which the OS in question does * not have out of the box support for and devices are required/preferred to be * available during actual installation. * * Returns: TRUE if install script supports pre-installable drivers, FALSE otherwise. * * Since: 0.2.2 */ gboolean osinfo_install_script_get_can_pre_install_drivers(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_boolean (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_CAN_PRE_INSTALL_DRIVERS); } /** * osinfo_install_script_get_can_post_install_drivers: * @script: the install script * * Whether install script can install drivers at the very end of installation * This can be used for installing devices which the OS in question does not * have out of the box support. * * Returns: TRUE if install script supports post-installable drivers, FALSE otherwise. * * Since: 0.2.2 */ gboolean osinfo_install_script_get_can_post_install_drivers(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_boolean (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_CAN_POST_INSTALL_DRIVERS); } /** * osinfo_install_script_get_pre_install_drivers_signing_req: * @script: the install script * * If install script can install drivers at the very beginning of installation, * this function retrieves the requirement about signed status of drivers. * * Returns: (type OsinfoDeviceDriverSigningReq): * * Since: 0.2.6 */ int osinfo_install_script_get_pre_install_drivers_signing_req(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_enum (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PRE_INSTALL_DRIVERS_SIGNING_REQ, OSINFO_TYPE_DEVICE_DRIVER_SIGNING_REQ, OSINFO_DEVICE_DRIVER_SIGNING_REQ_NONE); } /** * osinfo_install_script_get_post_install_drivers_signing_req: * @script: the install script * * If install script can install drivers at the end of installation, this * function retrieves the requirement about signed status of drivers. * * Returns: (type OsinfoDeviceDriverSigningReq): * * Since: 0.2.6 */ int osinfo_install_script_get_post_install_drivers_signing_req(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_enum (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_POST_INSTALL_DRIVERS_SIGNING_REQ, OSINFO_TYPE_DEVICE_DRIVER_SIGNING_REQ, OSINFO_DEVICE_DRIVER_SIGNING_REQ_NONE); } /** * osinfo_install_script_get_injection_methods: * @script: the install script * * Retrieve the supported method to inject the script in to the installation process. * * Returns: (type OsinfoInstallScriptInjectionMethod): bitwise-or of * supported methods for install script injection. * * Since: 0.2.10 */ unsigned int osinfo_install_script_get_injection_methods(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_int64_with_default (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_INJECTION_METHOD, OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK); } /** * osinfo_install_script_get_needs_internet: * @script: the install script * * Some install scripts cannot ensure that they work without an internet connection. * * Returns: TRUE if script needs an internet connection, FALSE otherwise * internet connection. * * Since: 0.2.11 */ gboolean osinfo_install_script_get_needs_internet(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_boolean_with_default (OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_NEEDS_INTERNET, FALSE); } /** * osinfo_install_script_set_preferred_injection_method: * @script: the install script * @method: one of the injection methods: * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_CDROM, * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK, * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_FLOPPY, * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD, * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_WEB * * Set the preferred injection method to be used with the @script * * Since: 1.3.0 */ void osinfo_install_script_set_preferred_injection_method(OsinfoInstallScript *script, OsinfoInstallScriptInjectionMethod method) { GFlagsClass *flags_class; guint i; flags_class = g_type_class_ref(OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD); for (i = 0; i < flags_class->n_values; i++) { if ((flags_class->values[i].value & method) != 0) { osinfo_entity_set_param(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PREFERRED_INJECTION_METHOD, flags_class->values[i].value_nick); break; } } g_type_class_unref(flags_class); } /** * osinfo_install_script_get_preferred_injection_method: * @script: the install script * * Returns: the preferred injection method for the script. If none is set and * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK is supported, * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK is returned, otherwise * OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD is returned. * * Since: 1.3.0 */ OsinfoInstallScriptInjectionMethod osinfo_install_script_get_preferred_injection_method(OsinfoInstallScript *script) { GFlagsClass *flags_class; GFlagsValue *value; const gchar *nick; guint supported_methods; nick = osinfo_entity_get_param_value(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_PREFERRED_INJECTION_METHOD); if (nick == NULL) { supported_methods = osinfo_install_script_get_injection_methods(script); if ((supported_methods & OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK) != 0) return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK; else if ((supported_methods & OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD) != 0) return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_INITRD; else return OSINFO_INSTALL_SCRIPT_INJECTION_METHOD_DISK; } flags_class = g_type_class_ref(OSINFO_TYPE_INSTALL_SCRIPT_INJECTION_METHOD); value = g_flags_get_value_by_nick(flags_class, nick); g_type_class_unref(flags_class); return value->value; } /** * osinfo_install_script_set_installation_source: * @script: the install script * @source: one of the installation sources: * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA, * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_NETWORK * * Set the installation source to be used with the @script. * * Since: 1.3.0 */ void osinfo_install_script_set_installation_source(OsinfoInstallScript *script, OsinfoInstallScriptInstallationSource source) { osinfo_entity_set_param_enum(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_INSTALLATION_SOURCE, source, OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE); } /** * osinfo_install_script_get_installation_source: * @script: the install script * * Returns: the installation source to be used with the script. If none is set, it defaults to * OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA. * * Since: 1.3.0 */ OsinfoInstallScriptInstallationSource osinfo_install_script_get_installation_source(OsinfoInstallScript *script) { return osinfo_entity_get_param_value_enum(OSINFO_ENTITY(script), OSINFO_INSTALL_SCRIPT_PROP_INSTALLATION_SOURCE, OSINFO_TYPE_INSTALL_SCRIPT_INSTALLATION_SOURCE, OSINFO_INSTALL_SCRIPT_INSTALLATION_SOURCE_MEDIA); }