Users can choose between minimum and recommended values for VCPU count and amount of RAM. Moreover, recommended values should inherit defaults from the minimum. --- examples/virtxml.c | 27 +++++++- libvirt-designer/libvirt-designer-domain.c | 98 +++++++++++++++++++++++++++- libvirt-designer/libvirt-designer-domain.h | 8 ++ libvirt-designer/libvirt-designer.sym | 3 +- 4 files changed, 132 insertions(+), 4 deletions(-) diff --git a/examples/virtxml.c b/examples/virtxml.c index 87929b2..468bc2a 100644 --- a/examples/virtxml.c +++ b/examples/virtxml.c @@ -69,6 +69,8 @@ print_usage(const char *progname) " 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", + " -r | --resource={minimal|recommended} Set minimal or recommended values for\n" + " cpu count and RAM amount.\n", progname); } @@ -276,6 +278,7 @@ main(int argc, char *argv[]) char *connect_uri = NULL; GList *disk_str_list = NULL; GList *iface_str_list = NULL; + gchar *resources = NULL; int arg; struct option opt[] = { @@ -288,6 +291,7 @@ main(int argc, char *argv[]) {"architecture", required_argument, NULL, 'a'}, {"disk", required_argument, NULL, 'd'}, {"interface", required_argument, NULL, 'i'}, + {"resource", required_argument, NULL, 'r'}, {NULL, 0, NULL, 0} }; @@ -297,7 +301,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:i:", opt, NULL)) != -1) { + while ((arg = getopt_long(argc, argv, "+hc:o:p:a:d:i:r:", opt, NULL)) != -1) { char *progname; switch (arg) { case 'h': @@ -347,6 +351,18 @@ main(int argc, char *argv[]) case 'i': iface_str_list = g_list_append(iface_str_list, optarg); break; + case 'r': + if (!strcmp(optarg, "minimal") || + !strcmp(optarg, "min")) { + resources = GVIR_DESIGNER_DOMAIN_RESOURCES_MINIMAL; + } else if (!strcmp(optarg, "recommended") || + !strcmp(optarg, "rec")) { + resources = GVIR_DESIGNER_DOMAIN_RESOURCES_RECOMMENDED; + } else { + print_error("Unknown resources value: '%s'", optarg); + exit(EXIT_FAILURE); + } + break; default: print_error("Something has gone tragically wrong"); case '?': @@ -389,6 +405,15 @@ main(int argc, char *argv[]) CHECK_ERROR; } + if (resources) { + gvir_designer_domain_setup_resources(domain, resources, &error); + CHECK_ERROR; + } else { + gvir_designer_domain_setup_resources(domain, + GVIR_DESIGNER_DOMAIN_RESOURCES_RECOMMENDED, + NULL); + } + g_list_foreach(disk_str_list, add_disk, domain); g_list_foreach(iface_str_list, add_iface, domain); diff --git a/libvirt-designer/libvirt-designer-domain.c b/libvirt-designer/libvirt-designer-domain.c index 5a10836..0411da4 100644 --- a/libvirt-designer/libvirt-designer-domain.c +++ b/libvirt-designer/libvirt-designer-domain.c @@ -213,9 +213,15 @@ GVirDesignerDomain *gvir_designer_domain_new(OsinfoOs *os, OsinfoPlatform *platform, GVirConfigCapabilities *caps) { + OsinfoOs *os_found = NULL; + OsinfoPlatform *platform_found = NULL; + + os_found = osinfo_db_get_os(osinfo_db, osinfo_entity_get_id(OSINFO_ENTITY(os))); + platform_found = osinfo_db_get_platform(osinfo_db, osinfo_entity_get_id(OSINFO_ENTITY(platform))); + return GVIR_DESIGNER_DOMAIN(g_object_new(GVIR_DESIGNER_TYPE_DOMAIN, - "os", os, - "platform", platform, + "os", os_found, + "platform", platform_found, "capabilities", caps, NULL)); } @@ -960,3 +966,91 @@ gvir_designer_domain_add_interface_network(GVirDesignerDomain *design, return ret; } + +static void +gvir_designer_domain_get_resources(OsinfoResourcesList *list, + const gchar *design_arch, + gint *design_n_cpus, + gint64 *design_ram) +{ + int i; + + if (!list) + return; + + for (i = 0; i < osinfo_list_get_length(OSINFO_LIST(list)); i++) { + OsinfoResources *res = OSINFO_RESOURCES(osinfo_list_get_nth(OSINFO_LIST(list), i)); + const char *arch = osinfo_resources_get_architecture(res); + gint n_cpus = -1; + gint64 ram = -1; + + if (g_str_equal(arch, "all") || + g_str_equal(arch, design_arch)) { + n_cpus = osinfo_resources_get_n_cpus(res); + ram = osinfo_resources_get_ram(res); + if (n_cpus > 0) { + *design_n_cpus = n_cpus; + } + if (ram > 0) { + /* libosinfo returns RAM in B, libvirt-gconfig takes it in KB */ + *design_ram = ram / 1024; + } + break; + } + } +} + +/** + * gvir_designer_domain_setup_resources: + * @design: (transfer none): the domain designer intance + * @req: (transfer none): requirements to set + * + * Set minimal or recommended resources on @design. + * + * Returns: (transfer none): TRUE when successfully set, FALSE otherwise. + */ +gboolean gvir_designer_domain_setup_resources(GVirDesignerDomain *design, + const gchar *req, + GError **error) +{ + g_return_val_if_fail(GVIR_DESIGNER_IS_DOMAIN(design), FALSE); + gboolean ret = FALSE; + OsinfoResourcesList *res_list_min = NULL, *res_list_rec = NULL; + GVirConfigDomainOs *os = gvir_config_domain_get_os(design->priv->config); + const gchar *design_arch = os ? gvir_config_domain_os_get_arch(os) : ""; + gint n_cpus = -1; + gint64 ram = -1; + + /* If user request recommended settings those may just override + * only a few settings when compared to minimal. So we must implement + * inheritance here. */ + res_list_min = osinfo_os_get_minimum_resources(design->priv->os); + res_list_rec = osinfo_os_get_recommended_resources(design->priv->os); + if (g_str_equal(req, GVIR_DESIGNER_DOMAIN_RESOURCES_MINIMAL)) { + gvir_designer_domain_get_resources(res_list_min, design_arch, + &n_cpus, &ram); + } else if (g_str_equal(req, GVIR_DESIGNER_DOMAIN_RESOURCES_RECOMMENDED)) { + gvir_designer_domain_get_resources(res_list_min, design_arch, + &n_cpus, &ram); + gvir_designer_domain_get_resources(res_list_rec, design_arch, + &n_cpus, &ram); + } else { + g_set_error(error, GVIR_DESIGNER_DOMAIN_ERROR, 0, + "Unknown resources argument: '%s'", req); + goto cleanup; + } + + if ((n_cpus <= 0) && (ram <= 0)) { + g_set_error(error, GVIR_DESIGNER_DOMAIN_ERROR, 0, + "Unable to find resources in libosinfo database"); + goto cleanup; + } + + if (n_cpus > 0) + gvir_config_domain_set_vcpus(design->priv->config, n_cpus); + if (ram > 0) + gvir_config_domain_set_memory(design->priv->config, ram); + +cleanup: + return ret; +} diff --git a/libvirt-designer/libvirt-designer-domain.h b/libvirt-designer/libvirt-designer-domain.h index 5097393..28a1d06 100644 --- a/libvirt-designer/libvirt-designer-domain.h +++ b/libvirt-designer/libvirt-designer-domain.h @@ -39,6 +39,9 @@ G_BEGIN_DECLS #define GVIR_DESIGNER_IS_DOMAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_DESIGNER_TYPE_DOMAIN)) #define GVIR_DESIGNER_DOMAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_DESIGNER_TYPE_DOMAIN, GVirDesignerDomainClass)) +#define GVIR_DESIGNER_DOMAIN_RESOURCES_MINIMAL "minimal" +#define GVIR_DESIGNER_DOMAIN_RESOURCES_RECOMMENDED "recommended" + typedef struct _GVirDesignerDomain GVirDesignerDomain; typedef struct _GVirDesignerDomainPrivate GVirDesignerDomainPrivate; typedef struct _GVirDesignerDomainClass GVirDesignerDomainClass; @@ -104,6 +107,11 @@ GVirConfigDomainDisk *gvir_designer_domain_add_disk_device(GVirDesignerDomain *d GVirConfigDomainInterface *gvir_designer_domain_add_interface_network(GVirDesignerDomain *design, const char *network, GError **error); + +gboolean gvir_designer_domain_setup_resources(GVirDesignerDomain *design, + const gchar *req, + 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 77f76b4..0dde9a6 100644 --- a/libvirt-designer/libvirt-designer.sym +++ b/libvirt-designer/libvirt-designer.sym @@ -12,7 +12,8 @@ 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_add_interface_network; + gvir_designer_domain_setup_resources; 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