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