[libvirt] [libvirt-designer][PATCH 4/4] domain: Introduce interface support

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


Let users add NICs to domains.
---
 examples/virtxml.c                         |   96 ++++++++++++++++++++++++----
 libvirt-designer/libvirt-designer-domain.c |   53 +++++++++++++++
 libvirt-designer/libvirt-designer-domain.h |    3 +
 libvirt-designer/libvirt-designer.sym      |    1 +
 4 files changed, 141 insertions(+), 12 deletions(-)

diff --git a/examples/virtxml.c b/examples/virtxml.c
index 36bc3bb..87929b2 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -56,17 +56,19 @@ 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",
+           "  -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"
+           "  -i | --interface=NETWORK[,ARG=VAL]    add interface with NETWORK source.\n"
+           "                                        Possible ARGs: mac,link={up,down}\n",
            progname);
 }
 
@@ -186,6 +188,69 @@ add_disk(gpointer data,
 
 }
 
+static void
+add_iface(gpointer data,
+          gpointer user_data)
+{
+    GVirDesignerDomain *domain = (GVirDesignerDomain *) user_data;
+    char *network = (char *) data;
+    char *param = NULL;
+    GVirConfigDomainInterface *iface = NULL;
+    GError *error = NULL;
+
+    param = strchr(network, ',');
+    if (param) {
+        *param = '\0';
+        param++;
+    }
+
+    iface = gvir_designer_domain_add_interface_network(domain, network, &error);
+    if (error) {
+        print_error("%s", error->message);
+        exit(EXIT_FAILURE);
+    }
+
+    while (param && *param) {
+        char *key = param;
+        char *val;
+        GVirConfigDomainInterfaceLinkState link;
+
+        /* move to next token */
+        param = strchr(param, ',');
+        if (param) {
+            *param = '\0';
+            param++;
+        }
+
+        /* parse token */
+        val = strchr(key, '=');
+        if (!val) {
+            print_error("Invalid format: %s", key);
+            exit(EXIT_FAILURE);
+        }
+
+        *val = '\0';
+        val++;
+
+        if (!strcmp(key, "mac")) {
+            gvir_config_domain_interface_set_mac(iface, val);
+        } else if (!strcmp(key, "link")) {
+            if (!strcmp(val, "up")) {
+                link = GVIR_CONFIG_DOMAIN_INTERFACE_LINK_STATE_UP;
+            } else if (!strcmp(val, "down")) {
+                link = GVIR_CONFIG_DOMAIN_INTERFACE_LINK_STATE_DOWN;
+            } else {
+                print_error("Unknown value: %s", val);
+                exit(EXIT_FAILURE);
+            }
+            gvir_config_domain_interface_set_link_state(iface, link);
+        } else {
+            print_error("Unknown key: %s", key);
+            exit(EXIT_FAILURE);
+        }
+    }
+}
+
 #define CHECK_ERROR \
     if (error) {                            \
         print_error("%s", error->message);  \
@@ -210,6 +275,7 @@ main(int argc, char *argv[])
     char *arch_str = NULL;
     char *connect_uri = NULL;
     GList *disk_str_list = NULL;
+    GList *iface_str_list = NULL;
     int arg;
 
     struct option opt[] = {
@@ -221,6 +287,7 @@ main(int argc, char *argv[])
         {"platform", required_argument, NULL, 'p'},
         {"architecture", required_argument, NULL, 'a'},
         {"disk", required_argument, NULL, 'd'},
+        {"interface", required_argument, NULL, 'i'},
         {NULL, 0, NULL, 0}
     };
 
@@ -230,7 +297,7 @@ main(int argc, char *argv[])
     /* 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) {
+    while ((arg = getopt_long(argc, argv, "+hc:o:p:a:d:i:", opt, NULL)) != -1) {
         char *progname;
         switch (arg) {
         case 'h':
@@ -277,6 +344,9 @@ main(int argc, char *argv[])
         case 'd':
             disk_str_list = g_list_append(disk_str_list, optarg);
             break;
+        case 'i':
+            iface_str_list = g_list_append(iface_str_list, optarg);
+            break;
         default:
             print_error("Something has gone tragically wrong");
         case '?':
@@ -321,6 +391,8 @@ main(int argc, char *argv[])
 
     g_list_foreach(disk_str_list, add_disk, domain);
 
+    g_list_foreach(iface_str_list, add_iface, domain);
+
     config = gvir_designer_domain_get_config(domain);
     xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(config));
 
diff --git a/libvirt-designer/libvirt-designer-domain.c b/libvirt-designer/libvirt-designer-domain.c
index 20611f2..5a10836 100644
--- a/libvirt-designer/libvirt-designer-domain.c
+++ b/libvirt-designer/libvirt-designer-domain.c
@@ -907,3 +907,56 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *d
                                              error);
     return ret;
 }
+
+static const gchar *
+gvir_designer_domain_get_preferred_nic_model(GVirDesignerDomain *design,
+                                             GError **error)
+{
+    const gchar *ret = NULL;
+    OsinfoDeviceLink *link = NULL;
+
+    link = gvir_designer_domain_get_preferred_device(design, "network", error);
+    if (!link)
+        goto cleanup;
+
+    ret = osinfo_devicelink_get_driver(link);
+
+cleanup:
+    if (link)
+        g_object_unref(link);
+    return ret;
+}
+
+/**
+ * gvir_designer_domain_add_interface_network:
+ * @design: (transfer none): the domain designer instance
+ * @network: (transfer none): network name
+ *
+ * Add new network interface card into @design. The interface is
+ * of 'network' type with @network used as the source network.
+ *
+ * Returns: (transfer none): the pointer to the new interface.
+ */
+GVirConfigDomainInterface *
+gvir_designer_domain_add_interface_network(GVirDesignerDomain *design,
+                                           const char *network,
+                                           GError **error)
+{
+    g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), NULL);
+
+    GVirConfigDomainInterface *ret;
+    const gchar *model = NULL;
+
+    model = gvir_designer_domain_get_preferred_nic_model(design, error);
+
+    ret = GVIR_CONFIG_DOMAIN_INTERFACE(gvir_config_domain_interface_network_new());
+
+    gvir_config_domain_interface_network_set_source(GVIR_CONFIG_DOMAIN_INTERFACE_NETWORK(ret),
+                                                    network);
+    if (model)
+        gvir_config_domain_interface_set_model(ret, model);
+
+    gvir_config_domain_add_device(design->priv->config, GVIR_CONFIG_DOMAIN_DEVICE(ret));
+
+    return ret;
+}
diff --git a/libvirt-designer/libvirt-designer-domain.h b/libvirt-designer/libvirt-designer-domain.h
index 06a5749..5097393 100644
--- a/libvirt-designer/libvirt-designer-domain.h
+++ b/libvirt-designer/libvirt-designer-domain.h
@@ -101,6 +101,9 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *d
                                                            const char *devpath,
                                                            GError **error);
 
+GVirConfigDomainInterface *gvir_designer_domain_add_interface_network(GVirDesignerDomain *design,
+                                                                      const char *network,
+                                                                      GError **error);
 G_END_DECLS
 
 #endif /* __LIBVIRT_DESIGNER_DOMAIN_H__ */
diff --git a/libvirt-designer/libvirt-designer.sym b/libvirt-designer/libvirt-designer.sym
index e67323a..77f76b4 100644
--- a/libvirt-designer/libvirt-designer.sym
+++ b/libvirt-designer/libvirt-designer.sym
@@ -12,6 +12,7 @@ LIBVIRT_DESIGNER_0.0.1 {
 
 	gvir_designer_domain_add_disk_file;
 	gvir_designer_domain_add_disk_device;
+    gvir_designer_domain_add_interface_network;
 
 	gvir_designer_domain_setup_machine;
 	gvir_designer_domain_setup_machine_full;
-- 
1.7.8.6




More information about the libvir-list mailing list