[virt-tools-list] [PATCH 3/6] Change install script output (tool)

Fabiano Fidêncio fabiano at fidencio.org
Tue Jul 24 20:05:15 UTC 2012


Now, instead of return a string, the osinfo-install-script tool writes
that string in a file, passed as argument, that will be into a dir,
also passed as argument.

If the filename argument is NULL, the output files will be written as
set in data/install-scripts/*.xml (in filename attribute from template
element):
    - Linuxes: fedora.ks
    - Windows 2k3r2 and older: windows.sif
    - Windows 2k8 and newer: windows.xml

If the dirname argument is NULL, the output files will be written in the
current directory.

It will be used to create, easily, multiple scripts, as used in:
http://bugzilla-attachments.gnome.org/attachment.cgi?id=214681
---
 data/install-scripts/fedora.xml           |    2 +-
 data/install-scripts/windows-sif.xml      |    2 +-
 data/install-scripts/windows-unattend.xml |    2 +-
 data/schemas/libosinfo.rng                |    1 +
 osinfo/libosinfo.syms                     |    4 +
 osinfo/osinfo_install_script.c            |  189 ++++++++++++++++++++++++++++-
 osinfo/osinfo_install_script.h            |   25 ++++
 osinfo/osinfo_install_scriptlist.c        |   15 +++
 osinfo/osinfo_install_scriptlist.h        |    1 +
 osinfo/osinfo_loader.c                    |    9 ++
 tools/osinfo-install-script.c             |   54 +++++----
 11 files changed, 273 insertions(+), 31 deletions(-)

diff --git a/data/install-scripts/fedora.xml b/data/install-scripts/fedora.xml
index b4ad72d..338a570 100644
--- a/data/install-scripts/fedora.xml
+++ b/data/install-scripts/fedora.xml
@@ -1,7 +1,7 @@
 <libosinfo version="0.0.1">
   <install-script id='http://fedoraproject.org/scripts/fedora/jeos'>
     <profile>jeos</profile>
-    <template>
+    <template filename="fedora.ks">
       <xsl:stylesheet
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         version="1.0">
diff --git a/data/install-scripts/windows-sif.xml b/data/install-scripts/windows-sif.xml
index 29a0eae..46b24ae 100644
--- a/data/install-scripts/windows-sif.xml
+++ b/data/install-scripts/windows-sif.xml
@@ -1,7 +1,7 @@
 <libosinfo version="0.0.1">
   <install-script id='http://microsoft.com/windows/sif'>
     <profile>jeos</profile>
-    <template>
+    <template filename="windows.sif">
       <xsl:stylesheet
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         version="1.0">
diff --git a/data/install-scripts/windows-unattend.xml b/data/install-scripts/windows-unattend.xml
index 9828b34..20e3e23 100644
--- a/data/install-scripts/windows-unattend.xml
+++ b/data/install-scripts/windows-unattend.xml
@@ -1,7 +1,7 @@
 <libosinfo version="0.0.1">
   <install-script id='http://microsoft.com/windows/unattend'>
     <profile>jeos</profile>
-    <template>
+    <template filename="windows.xml">
       <xsl:stylesheet
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         version="1.0">
diff --git a/data/schemas/libosinfo.rng b/data/schemas/libosinfo.rng
index a5f527d..7c8d7f7 100644
--- a/data/schemas/libosinfo.rng
+++ b/data/schemas/libosinfo.rng
@@ -414,6 +414,7 @@
         <text/>
       </element>
       <element name='template'>
+        <attribute name="filename"/>
         <choice>
           <group>
             <attribute name="uri"/>
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 2f90183..5a7de7b 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -264,6 +264,7 @@ LIBOSINFO_0.2.0 {
 	osinfo_install_config_set_user_administrator;
 	osinfo_install_config_set_user_autologin;
 	osinfo_install_config_set_hostname;
+	osinfo_install_script_set_output_filename;
 	osinfo_install_script_get_type;
 	osinfo_install_script_new;
 	osinfo_install_script_new_data;
@@ -271,6 +272,8 @@ LIBOSINFO_0.2.0 {
 	osinfo_install_script_generate;
 	osinfo_install_script_generate_async;
 	osinfo_install_script_generate_finish;
+	osinfo_install_script_generate_output;
+	osinfo_install_script_generate_output_async;
 	osinfo_install_script_get_profile;
 	osinfo_install_script_get_uri;
 	osinfo_install_scriptlist_new;
@@ -279,6 +282,7 @@ LIBOSINFO_0.2.0 {
 	osinfo_install_scriptlist_new_intersection;
 	osinfo_install_scriptlist_new_copy;
 	osinfo_install_scriptlist_get_type;
+	osinfo_install_scriptlist_get_by_profile;
 	osinfo_db_get_install_script;
 	osinfo_db_add_install_script;
 	osinfo_db_get_install_script_list;
diff --git a/osinfo/osinfo_install_script.c b/osinfo/osinfo_install_script.c
index 1f437a1..b2d7351 100644
--- a/osinfo/osinfo_install_script.c
+++ b/osinfo/osinfo_install_script.c
@@ -56,6 +56,7 @@ enum {
     PROP_TEMPLATE_DATA,
     PROP_PROFILE,
     PROP_PRODUCT_KEY_FORMAT,
+    PROP_OUTPUT_FILENAME,
 };
 
 
@@ -93,6 +94,14 @@ osinfo_os_set_property(GObject    *object,
                                     data);
         break;
 
+    case PROP_OUTPUT_FILENAME:
+        data = g_value_get_string(value);
+        if (data)
+            osinfo_entity_set_param(OSINFO_ENTITY(script),
+                                    OSINFO_INSTALL_SCRIPT_PROP_OUTPUT_FILENAME,
+                                    data);
+        break;
+
     default:
         /* We don't have any other property... */
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -129,6 +138,11 @@ osinfo_os_get_property(GObject    *object,
                            osinfo_install_script_get_product_key_format(script));
         break;
 
+    case PROP_OUTPUT_FILENAME:
+        g_value_set_string(value,
+                           osinfo_install_script_get_output_filename(script));
+        break;
+
     default:
         /* We don't have any other property... */
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -210,6 +224,19 @@ osinfo_install_script_class_init (OsinfoInstallScriptClass *klass)
                                     PROP_PROFILE,
                                     pspec);
 
+    pspec = g_param_spec_string("output-filename",
+                                "Output Filename",
+                                "Output filename for the script",
+                                NULL /* default value */,
+                                G_PARAM_READABLE |
+                                G_PARAM_WRITABLE |
+                                G_PARAM_STATIC_NAME |
+                                G_PARAM_STATIC_NICK |
+                                G_PARAM_STATIC_BLURB);
+    g_object_class_install_property(g_klass,
+                                    PROP_OUTPUT_FILENAME,
+                                    pspec);
+
     g_type_class_add_private (klass, sizeof (OsinfoInstallScriptPrivate));
 }
 
@@ -218,7 +245,6 @@ osinfo_install_script_init (OsinfoInstallScript *list)
 {
     OsinfoInstallScriptPrivate *priv;
     list->priv = priv = OSINFO_INSTALL_SCRIPT_GET_PRIVATE(list);
-
 }
 
 
@@ -291,6 +317,25 @@ const gchar *osinfo_install_script_get_product_key_format(OsinfoInstallScript *s
                                          OSINFO_INSTALL_SCRIPT_PROP_PRODUCT_KEY_FORMAT);
 }
 
+void osinfo_install_script_set_output_filename(OsinfoInstallScript *script,
+                                               const gchar *filename)
+{
+    GValue value = G_VALUE_INIT;
+    g_value_init(&value, G_TYPE_STRING);
+    g_value_set_string(&value, filename);
+
+    osinfo_os_set_property(G_OBJECT (script),
+                           PROP_OUTPUT_FILENAME,
+                           &value,
+                           NULL);
+}
+
+const gchar *osinfo_install_script_get_output_filename(OsinfoInstallScript *script)
+{
+    return osinfo_entity_get_param_value(OSINFO_ENTITY(script),
+                                         OSINFO_INSTALL_SCRIPT_PROP_OUTPUT_FILENAME);
+}
+
 struct OsinfoInstallScriptGenerate {
     GSimpleAsyncResult *res;
     OsinfoOs *os;
@@ -635,11 +680,18 @@ gchar *osinfo_install_script_generate_finish(OsinfoInstallScript *script,
     return g_simple_async_result_get_op_res_gpointer(simple);
 }
 
-
 struct OsinfoInstallScriptGenerateSync {
     GMainLoop *loop;
+    GCancellable *cancellable;
     GError *error;
+    OsinfoInstallScript *script;
+    OsinfoOs *os;
+    GFile *dir;
+    GFile *file;
     gchar *output;
+    gssize output_len;
+    gssize output_pos;
+    GFileOutputStream *stream;
 };
 
 static void osinfo_install_script_generate_done(GObject *src,
@@ -655,7 +707,6 @@ static void osinfo_install_script_generate_done(GObject *src,
     g_main_loop_quit(data->loop);
 }
 
-
 gchar *osinfo_install_script_generate(OsinfoInstallScript *script,
                                       OsinfoOs *os,
                                       OsinfoInstallConfig *config,
@@ -665,7 +716,7 @@ gchar *osinfo_install_script_generate(OsinfoInstallScript *script,
     GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
                                       TRUE);
     struct OsinfoInstallScriptGenerateSync data = {
-        loop, NULL, NULL
+        loop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL
     };
 
     osinfo_install_script_generate_async(script,
@@ -686,6 +737,136 @@ gchar *osinfo_install_script_generate(OsinfoInstallScript *script,
     return data.output;
 }
 
+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_async(script,
+                                         os,
+                                         config,
+                                         cancellable,
+                                         callback,
+                                         user_data);
+}
+
+gboolean osinfo_install_script_generate_output_finish(GFileOutputStream *stream,
+                                                      GAsyncResult *res,
+                                                      GError **error)
+{
+    return g_output_stream_close_finish (G_OUTPUT_STREAM (stream), res, error);
+}
+
+static void osinfo_install_script_generate_output_done(GObject *src,
+                                                       GAsyncResult *res,
+                                                       gpointer user_data)
+{
+    struct OsinfoInstallScriptGenerateSync *data = user_data;
+
+    osinfo_install_script_generate_output_finish(data->stream,
+                                                 res,
+                                                 &data->error);
+    g_main_loop_quit(data->loop);
+}
+
+static void osinfo_install_script_generate_output_write_file(GObject *src,
+                                                             GAsyncResult *res,
+                                                             gpointer user_data)
+{
+    struct OsinfoInstallScriptGenerateSync *data = user_data;
+    gssize size = 0;
+
+    if (data->stream == NULL)
+        data->stream = g_file_replace_finish(G_FILE (src), res, &data->error);
+    else
+        size = g_output_stream_write_finish(G_OUTPUT_STREAM (data->stream),
+                                                             res,
+                                                             &data->error);
+
+    g_assert_no_error(data->error);
+
+    data->output_pos += size;
+    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,
+                                    data->cancellable,
+                                    osinfo_install_script_generate_output_write_file,
+                                    data);
+
+    } else {
+        g_output_stream_close_async(G_OUTPUT_STREAM (data->stream),
+                                    G_PRIORITY_DEFAULT,
+                                    data->cancellable,
+                                    osinfo_install_script_generate_output_done,
+                                    data);
+    }
+}
+
+static void osinfo_install_script_generate_create_output_file(GObject *src,
+                                                              GAsyncResult *res,
+                                                              gpointer user_data)
+{
+    struct OsinfoInstallScriptGenerateSync *data = user_data;
+    const gchar *filename;
+
+    data->output =
+        osinfo_install_script_generate_finish(OSINFO_INSTALL_SCRIPT(src),
+                                              res,
+                                              &data->error);
+    data->output_len = strlen(data->output);
+
+    filename =
+        osinfo_install_script_get_output_filename(OSINFO_INSTALL_SCRIPT(src));
+
+    data->file = g_file_get_child(data->dir, filename);
+
+    g_file_replace_async(data->file,
+                         NULL,
+                         TRUE,
+                         G_FILE_CREATE_NONE,
+                         G_PRIORITY_DEFAULT,
+                         data->cancellable,
+                         osinfo_install_script_generate_output_write_file,
+                         data);
+
+}
+
+const GFile *osinfo_install_script_generate_output(OsinfoInstallScript *script,
+                                                   OsinfoOs *os,
+                                                   OsinfoInstallConfig *config,
+                                                   GFile *output_dir,
+                                                   GCancellable *cancellable,
+                                                   GError **error)
+{
+    GMainLoop *loop = g_main_loop_new(g_main_context_get_thread_default(),
+                                      TRUE);
+    struct OsinfoInstallScriptGenerateSync data = {
+        loop, cancellable, NULL, script, os, output_dir, NULL, NULL, 0, 0, NULL
+    };
+
+    osinfo_install_script_generate_output_async(script,
+                                                os,
+                                                config,
+                                                output_dir,
+                                                cancellable,
+                                                osinfo_install_script_generate_create_output_file,
+                                                &data);
+
+    if (g_main_loop_is_running(loop))
+        g_main_loop_run(loop);
+
+    if (data.error)
+        g_propagate_error(error, data.error);
+
+    g_main_loop_unref(loop);
+
+    return data.file;
+}
 
 /*
  * Local variables:
diff --git a/osinfo/osinfo_install_script.h b/osinfo/osinfo_install_script.h
index 00740c2..d75ec93 100644
--- a/osinfo/osinfo_install_script.h
+++ b/osinfo/osinfo_install_script.h
@@ -49,6 +49,8 @@ typedef struct _OsinfoInstallScriptPrivate OsinfoInstallScriptPrivate;
 #define OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA      "template-data"
 #define OSINFO_INSTALL_SCRIPT_PROP_PROFILE            "profile"
 #define OSINFO_INSTALL_SCRIPT_PROP_PRODUCT_KEY_FORMAT "product-key-format"
+#define OSINFO_INSTALL_SCRIPT_PROP_OUTPUT_FILENAME    "output-filename"
+
 
 /* object */
 struct _OsinfoInstallScript
@@ -85,6 +87,11 @@ const gchar *osinfo_install_script_get_profile(OsinfoInstallScript *script);
 
 const gchar *osinfo_install_script_get_product_key_format(OsinfoInstallScript *script);
 
+void osinfo_install_script_set_output_filename(OsinfoInstallScript *script,
+                                               const gchar *filename);
+
+const gchar *osinfo_install_script_get_output_filename(OsinfoInstallScript *script);
+
 void osinfo_install_script_generate_async(OsinfoInstallScript *script,
                                           OsinfoOs *os,
                                           OsinfoInstallConfig *config,
@@ -102,6 +109,24 @@ gchar *osinfo_install_script_generate(OsinfoInstallScript *script,
                                       GCancellable *cancellable,
                                       GError **error);
 
+void osinfo_install_script_generate_output_async(OsinfoInstallScript *script,
+                                                 OsinfoOs *os,
+                                                 OsinfoInstallConfig *config,
+                                                 GFile *output_dir,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+
+gboolean osinfo_install_script_generate_output_finish(GFileOutputStream *stream,
+                                                      GAsyncResult *res,
+                                                      GError **error);
+
+const GFile *osinfo_install_script_generate_output(OsinfoInstallScript *script,
+                                                   OsinfoOs *os,
+                                                   OsinfoInstallConfig *config,
+                                                   GFile *output_dir,
+                                                   GCancellable *cancellable,
+                                                   GError **error);
 
 #endif /* __OSINFO_INSTALL_SCRIPT_H__ */
 /*
diff --git a/osinfo/osinfo_install_scriptlist.c b/osinfo/osinfo_install_scriptlist.c
index e5309b5..dfc830b 100644
--- a/osinfo/osinfo_install_scriptlist.c
+++ b/osinfo/osinfo_install_scriptlist.c
@@ -160,6 +160,21 @@ OsinfoInstallScriptList *osinfo_install_scriptlist_new_union(OsinfoInstallScript
     return newList;
 }
 
+OsinfoInstallScriptList *osinfo_install_scriptlist_get_by_profile(OsinfoInstallScriptList *source,
+                                                                  const gchar *profile)
+{
+    OsinfoInstallScriptList *newList;
+    OsinfoFilter *filter;
+
+    filter = osinfo_filter_new();
+    osinfo_filter_add_constraint(filter,
+                                 OSINFO_INSTALL_SCRIPT_PROP_PROFILE,
+                                 profile);
+
+    newList = osinfo_install_scriptlist_new_filtered(source, filter);
+    return newList;
+}
+
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff --git a/osinfo/osinfo_install_scriptlist.h b/osinfo/osinfo_install_scriptlist.h
index 39544d2..6407304 100644
--- a/osinfo/osinfo_install_scriptlist.h
+++ b/osinfo/osinfo_install_scriptlist.h
@@ -71,6 +71,7 @@ OsinfoInstallScriptList *osinfo_install_scriptlist_new_copy(OsinfoInstallScriptL
 OsinfoInstallScriptList *osinfo_install_scriptlist_new_filtered(OsinfoInstallScriptList *source, OsinfoFilter *filter);
 OsinfoInstallScriptList *osinfo_install_scriptlist_new_intersection(OsinfoInstallScriptList *sourceOne, OsinfoInstallScriptList *sourceTwo);
 OsinfoInstallScriptList *osinfo_install_scriptlist_new_union(OsinfoInstallScriptList *sourceOne, OsinfoInstallScriptList *sourceTwo);
+OsinfoInstallScriptList *osinfo_install_scriptlist_get_by_profile(OsinfoInstallScriptList *source, const gchar *profile);
 
 #endif /* __OSINFO_INSTALL_SCRIPTLIST_H__ */
 /*
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index f89dee0..31e442e 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -585,6 +585,15 @@ static void osinfo_loader_install_script(OsinfoLoader *loader,
                                 value);
     g_free(value);
 
+    value = osinfo_loader_string("string(./template/@filename)", ctxt, err);
+    if (error_is_set(err))
+        goto error;
+    if (value)
+        osinfo_entity_set_param(OSINFO_ENTITY(installScript),
+                                OSINFO_INSTALL_SCRIPT_PROP_OUTPUT_FILENAME,
+                                value);
+    g_free(value);
+
     osinfo_db_add_install_script(loader->priv->db, installScript);
 
     return;
diff --git a/tools/osinfo-install-script.c b/tools/osinfo-install-script.c
index c6aeae6..8ea69c0 100644
--- a/tools/osinfo-install-script.c
+++ b/tools/osinfo-install-script.c
@@ -26,7 +26,9 @@
 #include <osinfo/osinfo.h>
 #include <string.h>
 
-static gchar *profile;
+static const gchar *profile;
+static const gchar *output_dir;
+static const gchar *output_file;
 
 static OsinfoInstallConfig *config;
 
@@ -60,6 +62,14 @@ static GOptionEntry entries[] =
 {
     { "profile", 'p', 0, G_OPTION_ARG_STRING, (void*)&profile,
       "Install script profile", NULL, },
+    { "dir", 'd', 0, G_OPTION_ARG_STRING, (void*)&output_dir,
+      "Install script output directory", NULL, },
+    { "file", 'f', 0, G_OPTION_ARG_STRING, (void*)&output_file,
+      "Install script output filename\n"
+      "\t\t\t     The extension expected for each type of OS is:\n"
+      "\t\t\t       .ks: for linuxes\n"
+      "\t\t\t       .sif: for older windows, up to win2k3r2\n"
+      "\t\t\t       .xml: for newer windows", NULL, },
     { "config", 'c', 0, G_OPTION_ARG_CALLBACK,
       handle_config,
       "Set configuration parameter", "key=value" },
@@ -103,48 +113,45 @@ static OsinfoOs *find_os(OsinfoDb *db,
 static gboolean generate_script(OsinfoOs *os)
 {
     OsinfoInstallScriptList *scripts = osinfo_os_get_install_script_list(os);
-    OsinfoInstallScriptList *jeosScripts;
-    OsinfoFilter *filter;
+    OsinfoInstallScriptList *profileScripts;
     OsinfoInstallScript *script;
     gboolean ret = FALSE;
     GError *error = NULL;
-    gchar *data;
+    GFile *dir = g_file_new_for_commandline_arg(output_dir ? output_dir : ".");
 
-    filter = osinfo_filter_new();
-    osinfo_filter_add_constraint(filter,
-                                 OSINFO_INSTALL_SCRIPT_PROP_PROFILE,
-                                 profile ? profile :
-                                 OSINFO_INSTALL_SCRIPT_PROFILE_JEOS);
+    profileScripts =
+        osinfo_install_scriptlist_get_by_profile(scripts,
+                                                 profile ? profile:
+                                                 OSINFO_INSTALL_SCRIPT_PROFILE_JEOS);
 
-    jeosScripts = osinfo_install_scriptlist_new_filtered(scripts,
-                                                         filter);
-    if (osinfo_list_get_length(OSINFO_LIST(jeosScripts)) != 1) {
+    if (osinfo_list_get_length(OSINFO_LIST(profileScripts)) != 1) {
         g_printerr("Cannot find any install script for profile '%s'\n",
                    profile ? profile :
                    OSINFO_INSTALL_SCRIPT_PROFILE_JEOS);
         goto cleanup;
     }
 
-    script = OSINFO_INSTALL_SCRIPT(osinfo_list_get_nth(OSINFO_LIST(jeosScripts), 0));
-    if (!(data = osinfo_install_script_generate(script,
-                                                os,
-                                                config,
-                                                NULL,
-                                                &error))) {
+    script = OSINFO_INSTALL_SCRIPT(osinfo_list_get_nth(OSINFO_LIST(profileScripts), 0));
+
+    if (output_file)
+        osinfo_install_script_set_output_filename(script, output_file);
+
+    if (osinfo_install_script_generate_output(script,
+                                              os,
+                                              config,
+                                              dir,
+                                              NULL,
+                                              &error) == NULL) {
         g_printerr("Unable to generate install script: %s\n",
                    error ? error->message : "unknown");
         goto cleanup;
     }
 
-    g_print("%s\n", data);
-
     ret = TRUE;
 
  cleanup:
-    g_free(data);
     g_object_unref(scripts);
-    g_object_unref(jeosScripts);
-    g_object_unref(filter);
+    g_object_unref(profileScripts);
     return ret;
 }
 
@@ -197,7 +204,6 @@ gint main(gint argc, gchar **argv)
         goto EXIT;
     }
 
-
     if (!generate_script(os)) {
         ret = -5;
         goto EXIT;
-- 
1.7.10.4




More information about the virt-tools-list mailing list