osinfo-db schema allows that, but libosinfo never really had an API to support it. https://gitlab.com/libosinfo/libosinfo/issues/16 Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> --- osinfo/osinfo_loader.c | 17 ++++++++- osinfo/osinfo_os.c | 2 ++ osinfo/osinfo_tree.c | 70 +++++++++++++++++++++++++++++++++++- osinfo/osinfo_tree.h | 2 ++ osinfo/osinfo_tree_private.h | 29 +++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 osinfo/osinfo_tree_private.h diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c index f71aea9..e30148b 100644 --- a/osinfo/osinfo_loader.c +++ b/osinfo/osinfo_loader.c @@ -1242,9 +1242,24 @@ static OsinfoTree *osinfo_loader_tree(OsinfoLoader *loader, OsinfoTree *tree = osinfo_tree_new(id, arch); xmlFree(arch); + gint nnodes = osinfo_loader_nodeset("./variant", loader, ctxt, &nodes, err); + if (error_is_set(err)) { + g_object_unref(tree); + return NULL; + } + + for (i = 0; i < nnodes; i++) { + gchar *variant_id = (gchar *)xmlGetProp(nodes[i], BAD_CAST "id"); + osinfo_entity_add_param(OSINFO_ENTITY(tree), + OSINFO_TREE_PROP_VARIANT, + variant_id); + xmlFree(variant_id); + } + g_free(nodes); + osinfo_loader_entity(loader, OSINFO_ENTITY(tree), keys, ctxt, root, err); - gint nnodes = osinfo_loader_nodeset("./treeinfo/*", loader, ctxt, &nodes, err); + nnodes = osinfo_loader_nodeset("./treeinfo/*", loader, ctxt, &nodes, err); if (error_is_set(err)) { g_object_unref(G_OBJECT(tree)); return NULL; diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c index dbea421..a406980 100644 --- a/osinfo/osinfo_os.c +++ b/osinfo/osinfo_os.c @@ -28,6 +28,7 @@ #include "osinfo_media_private.h" #include "osinfo/osinfo_product_private.h" #include "osinfo/osinfo_resources_private.h" +#include "osinfo/osinfo_tree_private.h" #include <glib/gi18n-lib.h> G_DEFINE_TYPE(OsinfoOs, osinfo_os, OSINFO_TYPE_PRODUCT); @@ -673,6 +674,7 @@ void osinfo_os_add_tree(OsinfoOs *os, OsinfoTree *tree) g_return_if_fail(OSINFO_IS_TREE(tree)); osinfo_list_add(OSINFO_LIST(os->priv->trees), OSINFO_ENTITY(tree)); + osinfo_tree_set_os(tree, os); } /** diff --git a/osinfo/osinfo_tree.c b/osinfo/osinfo_tree.c index 55c6aa1..1446f53 100644 --- a/osinfo/osinfo_tree.c +++ b/osinfo/osinfo_tree.c @@ -26,6 +26,7 @@ #include <config.h> #include <osinfo/osinfo.h> +#include "osinfo_tree_private.h" #include <gio/gio.h> #include <stdlib.h> #include <string.h> @@ -96,7 +97,7 @@ G_DEFINE_TYPE(OsinfoTree, osinfo_tree, OSINFO_TYPE_ENTITY); struct _OsinfoTreePrivate { - gboolean unused; + GWeakRef os; }; enum { @@ -264,6 +265,15 @@ osinfo_tree_finalize(GObject *object) G_OBJECT_CLASS(osinfo_tree_parent_class)->finalize(object); } +static void osinfo_tree_dispose(GObject *obj) +{ + OsinfoTree *tree = OSINFO_TREE(obj); + + g_weak_ref_clear(&tree->priv->os); + + G_OBJECT_CLASS(osinfo_tree_parent_class)->dispose(obj); +} + /* Init functions */ static void osinfo_tree_class_init(OsinfoTreeClass *klass) @@ -271,6 +281,7 @@ osinfo_tree_class_init(OsinfoTreeClass *klass) GObjectClass *g_klass = G_OBJECT_CLASS(klass); GParamSpec *pspec; + g_klass->dispose = osinfo_tree_dispose; g_klass->finalize = osinfo_tree_finalize; g_klass->get_property = osinfo_tree_get_property; g_klass->set_property = osinfo_tree_set_property; @@ -411,6 +422,8 @@ static void osinfo_tree_init(OsinfoTree *tree) { tree->priv = OSINFO_TREE_GET_PRIVATE(tree); + + g_weak_ref_init(&tree->priv->os, NULL); } OsinfoTree *osinfo_tree_new(const gchar *id, @@ -918,3 +931,58 @@ gboolean osinfo_tree_has_treeinfo(OsinfoTree *tree) return osinfo_entity_get_param_value_boolean(OSINFO_ENTITY(tree), OSINFO_TREE_PROP_HAS_TREEINFO); } + +OsinfoOs *osinfo_tree_get_os(OsinfoTree *tree) +{ + g_return_val_if_fail(OSINFO_IS_TREE(tree), NULL); + + return g_weak_ref_get(&tree->priv->os); +} + +void osinfo_tree_set_os(OsinfoTree *tree, OsinfoOs *os) +{ + g_return_if_fail(OSINFO_IS_TREE(tree)); + + g_object_ref(os); + g_weak_ref_set(&tree->priv->os, os); + g_object_unref(os); +} + +/** + * osinfo_tree_get_os_variant_list: + * @tree: an #OsinfoTree instance + * + * Gets the variants of the associated operating system. + * + * Returns: (transfer full): the operating system variant, or NULL + */ +OsinfoOsVariantList *osinfo_tree_get_os_variants(OsinfoTree *tree) +{ + OsinfoOs *os; + OsinfoOsVariantList *os_variants; + OsinfoOsVariantList *tree_variants; + GList *ids, *node; + OsinfoFilter *filter; + + g_return_val_if_fail(OSINFO_IS_TREE(tree), NULL); + os = osinfo_tree_get_os(tree); + os_variants = osinfo_os_get_variant_list(os); + g_object_unref(os); + + ids = osinfo_entity_get_param_value_list(OSINFO_ENTITY(tree), + OSINFO_TREE_PROP_VARIANT); + filter = osinfo_filter_new(); + tree_variants = osinfo_os_variantlist_new(); + for (node = ids; node != NULL; node = node->next) { + osinfo_filter_clear_constraints(filter); + osinfo_filter_add_constraint(filter, + OSINFO_ENTITY_PROP_ID, + (const char *) node->data); + osinfo_list_add_filtered(OSINFO_LIST(tree_variants), + OSINFO_LIST(os_variants), + filter); + } + g_object_unref(os_variants); + + return tree_variants; +} diff --git a/osinfo/osinfo_tree.h b/osinfo/osinfo_tree.h index 40a2a29..7ff1840 100644 --- a/osinfo/osinfo_tree.h +++ b/osinfo/osinfo_tree.h @@ -62,6 +62,7 @@ typedef struct _OsinfoTreePrivate OsinfoTreePrivate; #define OSINFO_TREE_PROP_KERNEL "kernel" #define OSINFO_TREE_PROP_INITRD "initrd" #define OSINFO_TREE_PROP_HAS_TREEINFO "has-treeinfo" +#define OSINFO_TREE_PROP_VARIANT "variant" /* object */ @@ -109,6 +110,7 @@ const gchar *osinfo_tree_get_treeinfo_arch(OsinfoTree *tree); const gchar *osinfo_tree_get_boot_iso_path(OsinfoTree *tree); const gchar *osinfo_tree_get_kernel_path(OsinfoTree *tree); const gchar *osinfo_tree_get_initrd_path(OsinfoTree *tree); +OsinfoOsVariantList *osinfo_tree_get_os_variants(OsinfoTree *tree); /* XXX Xen kernel/initrd paths ? */ #endif /* __OSINFO_TREE_H__ */ diff --git a/osinfo/osinfo_tree_private.h b/osinfo/osinfo_tree_private.h new file mode 100644 index 0000000..7113f98 --- /dev/null +++ b/osinfo/osinfo_tree_private.h @@ -0,0 +1,29 @@ +/* + * libosinfo: An installation tree for a (guest) OS + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <osinfo/osinfo_tree.h> + +#ifndef __OSINFO_TREE_PRIVATE_H__ +#define __OSINFO_TREE_PRIVATE_H__ + +OsinfoOs *osinfo_tree_get_os(OsinfoTree *tree); +void osinfo_tree_set_os(OsinfoTree *tree, OsinfoOs *os); + +#endif /* __OSINFO_TREE_PRIVATE_H__ */ -- 2.20.1 _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo