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