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

Michal Privoznik mprivozn at redhat.com
Mon Sep 10 13:58:28 UTC 2012


Let users add NICs to domains.
---
 examples/virtxml.c                         |   78 ++++++++++++++++++++++++++
 libvirt-designer/libvirt-designer-domain.c |   83 ++++++++++++++++++++++++++++
 libvirt-designer/libvirt-designer-domain.h |    3 +
 libvirt-designer/libvirt-designer.sym      |    1 +
 4 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/examples/virtxml.c b/examples/virtxml.c
index 20e3f3c..df83f57 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -35,6 +35,7 @@
 #include <unistd.h>
 
 GList *disk_str_list = NULL;
+GList *iface_str_list = NULL;
 
 #define print_error(...) \
     print_error_impl(__FUNCTION__, __LINE__, __VA_ARGS__)
@@ -215,6 +216,79 @@ add_disk_str(const gchar *option_name,
     return TRUE;
 }
 
+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);
+        }
+    }
+}
+
+static gboolean
+add_iface_str(const gchar *option_name,
+             const gchar *value,
+             gpointer data,
+             GError **error)
+{
+    iface_str_list = g_list_append(iface_str_list, g_strdup(value));
+    return TRUE;
+}
+
 #define CHECK_ERROR \
     if (error) {                            \
         print_error("%s", error->message);  \
@@ -256,6 +330,8 @@ main(int argc, char *argv[])
             "set domain architecture", "ARCH"},
         {"disk", 'd', 0, G_OPTION_ARG_CALLBACK, add_disk_str,
             "add disk to domain with PATH being source and FORMAT its format", "PATH[,FORMAT]"},
+        {"interface", 'i', 0, G_OPTION_ARG_CALLBACK, add_iface_str,
+            "add interface with NETWORK source. Possible ARGs: mac, link={up,down}", "NETWORK[,ARG=VAL]"},
         {NULL}
     };
 
@@ -304,6 +380,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 8e649d7..4af432b 100644
--- a/libvirt-designer/libvirt-designer-domain.c
+++ b/libvirt-designer/libvirt-designer-domain.c
@@ -49,6 +49,11 @@ G_DEFINE_TYPE(GVirDesignerDomain, gvir_designer_domain, G_TYPE_OBJECT);
 
 #define GVIR_DESIGNER_DOMAIN_ERROR gvir_designer_domain_error_quark()
 
+typedef enum {
+    GVIR_DESIGNER_DOMAIN_NIC_TYPE_NETWORK,
+    /* add new type here */
+} GVirDesignerDomainNICType;
+
 static GQuark
 gvir_designer_domain_error_quark(void)
 {
@@ -922,3 +927,81 @@ 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 *dev_link = NULL;
+
+    dev_link = gvir_designer_domain_get_preferred_device(design, "network", error);
+    if (!dev_link)
+        goto cleanup;
+
+    ret = osinfo_devicelink_get_driver(dev_link);
+
+cleanup:
+    if (dev_link)
+        g_object_unref(dev_link);
+    return ret;
+}
+
+static GVirConfigDomainInterface *
+gvir_designer_domain_add_interface_full(GVirDesignerDomain *design,
+                                        GVirDesignerDomainNICType type,
+                                        const char *network,
+                                        GError **error)
+{
+    GVirConfigDomainInterface *ret;
+    const gchar *model = NULL;
+
+    model = gvir_designer_domain_get_preferred_nic_model(design, error);
+
+    switch (type) {
+    case GVIR_DESIGNER_DOMAIN_NIC_TYPE_NETWORK:
+        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);
+        break;
+    default:
+        g_set_error(error, GVIR_DESIGNER_DOMAIN_ERROR, 0,
+                    "Unsupported interface type '%d'", type);
+        goto cleanup;
+    }
+
+    if (model)
+        gvir_config_domain_interface_set_model(ret, model);
+
+    gvir_config_domain_add_device(design->priv->config, GVIR_CONFIG_DOMAIN_DEVICE(ret));
+
+cleanup:
+    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 = NULL;
+
+    ret = gvir_designer_domain_add_interface_full(design,
+                                                  GVIR_DESIGNER_DOMAIN_NIC_TYPE_NETWORK,
+                                                  network,
+                                                  error);
+
+    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..317a07b 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