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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list