[libvirt] [libvirt-designer][PATCH 3/4] examples: Create an example of usage program

Michal Privoznik mprivozn at redhat.com
Wed Sep 5 09:27:46 UTC 2012


---
 .gitignore           |    1 +
 Makefile.am          |    2 +-
 configure.ac         |    6 +-
 examples/Makefile.am |   23 ++++
 examples/virtxml.c   |  334 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 364 insertions(+), 2 deletions(-)
 create mode 100644 examples/Makefile.am
 create mode 100644 examples/virtxml.c

diff --git a/.gitignore b/.gitignore
index b7ba45a..d570af8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ Makefile.in
 /config.log
 /config.status
 /configure
+/examples/virtxml
 /libtool
 /libvirt-designer-1.0.pc
 /libvirt-designer.spec
diff --git a/Makefile.am b/Makefile.am
index b0f68c0..ab06626 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
 
-SUBDIRS = libvirt-designer
+SUBDIRS = libvirt-designer examples
 
 ACLOCAL_AMFLAGS = -I m4
 
diff --git a/configure.ac b/configure.ac
index 795990f..ebe7b35 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,6 +13,7 @@ AM_SILENT_RULES([yes])
 LIBOSINFO_REQUIRED=0.0.5
 LIBVIRT_GCONFIG_REQUIRED=0.0.9
 GOBJECT_INTROSPECTION_REQUIRED=0.10.8
+LIBVIRT_REQUIRED=0.9.0
 
 LIBVIRT_DESIGNER_MAJOR_VERSION=`echo $VERSION | awk -F. '{print $1}'`
 LIBVIRT_DESIGNER_MINOR_VERSION=`echo $VERSION | awk -F. '{print $2}'`
@@ -40,6 +41,7 @@ LIBVIRT_DESIGNER_COMPILE_WARNINGS
 
 PKG_CHECK_MODULES(LIBOSINFO, libosinfo-1.0 >= $LIBOSINFO_REQUIRED)
 PKG_CHECK_MODULES(LIBVIRT_GCONFIG, libvirt-gconfig-1.0 >= $LIBVIRT_GCONFIG_REQUIRED)
+PKG_CHECK_MODULES(LIBVIRT, libvirt >= $LIBVIRT_REQUIRED)
 
 LIBVIRT_DESIGNER_GETTEXT
 LIBVIRT_DESIGNER_GTK_MISC
@@ -51,7 +53,8 @@ LIBVIRT_DESIGNER_INTROSPECTION
 AC_OUTPUT(Makefile
           libvirt-designer/Makefile
           libvirt-designer.spec
-          libvirt-designer-1.0.pc)
+          libvirt-designer-1.0.pc
+          examples/Makefile)
 
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Configuration summary])
@@ -62,4 +65,5 @@ AC_MSG_NOTICE([ Libraries:])
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([       LIBOSINFO: $LIBOSINFO_CFLAGS $LIBOSINFO_LIBS])
 AC_MSG_NOTICE([ LIBVIRT_GCONFIG: $LIBVIRT_GCONFIG_CFLAGS $LIBVIRT_GCONFIG_LIBS])
+AC_MSG_NOTICE([         LIBVIRT: $LIBVIRT_CFLAGS $LIBVIRT_LIBS])
 AC_MSG_NOTICE([])
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..cc2b997
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,23 @@
+INCLUDES = \
+		-I$(top_builddir)/libvirt-designer	\
+		-I$(top_srcdir)
+
+virtxml_LDADD = \
+		$(top_builddir)/libvirt-designer/libvirt-designer-1.0.la
+
+virtxml_CFLAGS = \
+		-I$(top_srcdir) \
+		$(COVERAGE_CFLAGS) \
+		-I$(top_srcdir) \
+		$(LIBOSINFO_CFLAGS) \
+		$(LIBVIRT_GCONFIG_CFLAGS) \
+		$(WARN_CFLAGS2) \
+		$(LIBVIRT_CFLAGS) \
+		$(NULL)
+
+virtxml_LDFLAGS = \
+		$(LIBOSINFO_LIBS) \
+		$(LIBVIRT_GCONFIG_LIBS) \
+		$(LIBVIRT_LIBS)
+
+bin_PROGRAMS = virtxml
diff --git a/examples/virtxml.c b/examples/virtxml.c
new file mode 100644
index 0000000..36bc3bb
--- /dev/null
+++ b/examples/virtxml.c
@@ -0,0 +1,334 @@
+/*
+ * virtxml.c: produce an domain XML
+ *
+ * Copyright (C) 2012 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
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn at redhat.com>
+ */
+
+#include <config.h>
+#include <libvirt-designer/libvirt-designer.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define print_error(...) \
+    print_error_impl(__FUNCTION__, __LINE__, __VA_ARGS__)
+
+static void
+print_error_impl(const char *funcname,
+                 size_t linenr,
+                 const char *fmt, ...)
+{
+    va_list args;
+
+    fprintf(stderr, "Error in %s:%zu ", funcname, linenr);
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args);
+    va_end(args);
+    fprintf(stderr,"\n");
+}
+
+static void
+print_usage(const char *progname)
+{
+    printf("\nUsage: %s options ...\n"
+           " options:\n"
+           "  -h | --help                 print this help\n"
+           "  -c | --connect=URI          libvirt connection URI used \n"
+           "                              for querying capabilities\n"
+           "       --list-os              list IDs of known OSes\n"
+           "       --list-platform        list IDs of known hypervisors\n"
+           "  -o | --os=OS                set domain OS\n"
+           "  -p | --platform=PLATFORM    set hypervisor under which \n"
+           "                              domain will be running\n"
+           "  -a | --architecture=ARCH    set domain architecture\n"
+           "  -d | --disk=PATH[,FORMAT]   add disk to domain with PATH being \n"
+           "                              source and FORMAT is its format\n",
+           progname);
+}
+
+static OsinfoDb *
+get_default_osinfo_db(void)
+{
+    GError *err = NULL;
+    OsinfoLoader *loader = NULL;
+    OsinfoDb *ret = NULL;
+
+    loader = osinfo_loader_new();
+    osinfo_loader_process_default_path(loader, &err);
+    if (err) {
+        print_error("Unable to load default libosinfo DB: %s", err->message);
+        goto cleanup;
+    }
+
+    ret = osinfo_loader_get_db(loader);
+    g_object_ref(ret);
+
+cleanup:
+    g_object_unref(loader);
+    return ret;
+}
+
+static int
+print_oses(void)
+{
+    OsinfoDb *db = get_default_osinfo_db();
+    OsinfoOsList *list;
+    int i;
+
+    if (!db)
+        return EXIT_FAILURE;
+
+    list = osinfo_db_get_os_list(db);
+
+    printf("  Operating System ID\n"
+           "-----------------------\n");
+    for (i = 0 ; i < osinfo_list_get_length(OSINFO_LIST(list)) ; i++) {
+        OsinfoOs *ent = OSINFO_OS(osinfo_list_get_nth(OSINFO_LIST(list), i));
+        const char *id = osinfo_entity_get_param_value(OSINFO_ENTITY(ent),
+                                                       "short-id");
+        if (!id)
+            id = osinfo_entity_get_param_value(OSINFO_ENTITY(ent),
+                                               OSINFO_ENTITY_PROP_ID);
+        printf("%s\n", id);
+    }
+
+    g_object_unref(list);
+    g_object_unref(db);
+
+    return EXIT_SUCCESS;
+}
+
+static int
+print_platforms(void)
+{
+    OsinfoDb *db = get_default_osinfo_db();
+    OsinfoPlatformList *list;
+    int i;
+
+    if (!db)
+        return EXIT_FAILURE;
+
+    list = osinfo_db_get_platform_list(db);
+
+    printf("  Platform ID\n"
+           "---------------\n");
+    for (i = 0; i < osinfo_list_get_length(OSINFO_LIST(list)); i++) {
+        OsinfoPlatform *ent = OSINFO_PLATFORM(osinfo_list_get_nth(OSINFO_LIST(list), i));
+        const char *id = osinfo_entity_get_param_value(OSINFO_ENTITY(ent),
+                                                       "short-id");
+        if (!id)
+            id = osinfo_entity_get_param_value(OSINFO_ENTITY(ent),
+                                               OSINFO_ENTITY_PROP_ID);
+
+        printf("%s\n", id);
+    }
+
+    g_object_unref(list);
+    g_object_unref(db);
+
+    return EXIT_SUCCESS;
+}
+
+static void
+add_disk(gpointer data,
+         gpointer user_data)
+{
+    GVirDesignerDomain *domain = (GVirDesignerDomain *) user_data;
+    char *path = (char *) data;
+    char *format = NULL;
+    struct stat buf;
+    GError *error = NULL;
+
+    format = strchr(path, ',');
+    if (format) {
+        *format = '\0';
+        format++;
+    }
+
+    if (!path || !strlen(path)) {
+        print_error("No path provided");
+        return;
+    }
+
+    if (!stat(path, &buf) &&
+        !S_ISREG(buf.st_mode)) {
+        gvir_designer_domain_add_disk_device(domain, path, &error);
+    } else {
+        gvir_designer_domain_add_disk_file(domain, path, format, &error);
+    }
+
+    if (error)
+        print_error("%s", error->message);
+
+}
+
+#define CHECK_ERROR \
+    if (error) {                            \
+        print_error("%s", error->message);  \
+        goto cleanup;                       \
+    }
+
+int
+main(int argc, char *argv[])
+{
+    int ret = EXIT_FAILURE;
+    GError *error = NULL;
+    OsinfoOs *os = NULL;
+    OsinfoPlatform *platform = NULL;
+    GVirConfigCapabilities *caps = NULL;
+    GVirConfigDomain *config = NULL;
+    GVirDesignerDomain *domain = NULL;
+    virConnectPtr conn = NULL;
+    char *caps_str = NULL;
+    gchar *xml = NULL;
+    char *os_str = NULL;
+    char *platform_str = NULL;
+    char *arch_str = NULL;
+    char *connect_uri = NULL;
+    GList *disk_str_list = NULL;
+    int arg;
+
+    struct option opt[] = {
+        {"help", no_argument, NULL, 'h'},
+        {"connect", required_argument, NULL, 'c'},
+        {"list-os", no_argument, NULL, 'O'},
+        {"list-platform", no_argument, NULL, 'P'},
+        {"os", required_argument, NULL, 'o'},
+        {"platform", required_argument, NULL, 'p'},
+        {"architecture", required_argument, NULL, 'a'},
+        {"disk", required_argument, NULL, 'd'},
+        {NULL, 0, NULL, 0}
+    };
+
+    if (!gvir_designer_init_check(&argc, &argv, NULL))
+        return EXIT_FAILURE;
+
+    /* Standard (non-command) options. The leading + ensures that no
+     * argument reordering takes place, so that command options are
+     * not confused with top-level virsh options. */
+    while ((arg = getopt_long(argc, argv, "+hc:o:p:a:d:", opt, NULL)) != -1) {
+        char *progname;
+        switch (arg) {
+        case 'h':
+            if (!(progname = strrchr(argv[0], '/')))
+                progname = argv[0];
+            else
+                progname++;
+
+            print_usage(progname);
+            exit(EXIT_SUCCESS);
+            break;
+        case 'c':
+            connect_uri = optarg;
+            break;
+        case 'O':
+            ret = print_oses();
+            exit(ret);
+            break;
+        case 'P':
+            ret = print_platforms();
+            exit(ret);
+            break;
+        case 'o':
+            if (os_str) {
+                print_error("Os already set to '%s'", os_str);
+                exit(EXIT_FAILURE);
+            }
+            os_str = optarg;
+            break;
+        case 'p':
+            if (platform_str) {
+                print_error("Platform already set to '%s'", platform_str);
+                exit(EXIT_FAILURE);
+            }
+            platform_str = optarg;
+            break;
+        case 'a':
+            if (arch_str) {
+                print_error("Architecture already set to '%s'", arch_str);
+                exit(EXIT_FAILURE);
+            }
+            arch_str = optarg;
+            break;
+        case 'd':
+            disk_str_list = g_list_append(disk_str_list, optarg);
+            break;
+        default:
+            print_error("Something has gone tragically wrong");
+        case '?':
+            /* getopt_long already reported error */
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    if (!os_str) {
+        print_error("Operating system was not specified");
+        exit(EXIT_FAILURE);
+    }
+    if (!platform_str) {
+        print_error("Platform was not specified");
+        exit(EXIT_FAILURE);
+    }
+
+    conn = virConnectOpenAuth(connect_uri, virConnectAuthPtrDefault, VIR_CONNECT_RO);
+    if (!conn) {
+        print_error("Unable to connect to libvirt");
+        return EXIT_FAILURE;
+    }
+
+    if ((caps_str = virConnectGetCapabilities(conn)) == NULL) {
+        print_error("failed to get capabilities");
+        goto cleanup;
+    }
+
+    os = osinfo_os_new(os_str);
+    platform = osinfo_platform_new(platform_str);
+    caps = gvir_config_capabilities_new_from_xml(caps_str, NULL);
+
+    domain = gvir_designer_domain_new(os, platform, caps);
+
+    gvir_designer_domain_setup_machine(domain, &error);
+    CHECK_ERROR;
+
+    if (arch_str) {
+        gvir_designer_domain_setup_container_full(domain, arch_str, &error);
+        CHECK_ERROR;
+    }
+
+    g_list_foreach(disk_str_list, add_disk, domain);
+
+    config = gvir_designer_domain_get_config(domain);
+    xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(config));
+
+    g_printf("%s\n", xml);
+
+    ret = EXIT_SUCCESS;
+
+cleanup:
+    virConnectClose(conn);
+    return ret;
+}
-- 
1.7.8.6




More information about the libvir-list mailing list