[virt-tools-list] [PATCH libosinfo 1/3] Add support for install tree metadata
Daniel P. Berrange
berrange at redhat.com
Thu Feb 23 12:23:59 UTC 2012
From: "Daniel P. Berrange" <berrange at redhat.com>
The <media> element and OsinfoMedia class can be used to identify
install media, ie ISO images.
The <tree> element and OsinfoTree class are the same concept but
used to identify installation trees.
---
docs/reference/Libosinfo.types | 2 +
osinfo/Makefile.am | 10 +-
osinfo/libosinfo.syms | 28 ++
osinfo/osinfo.h | 2 +
osinfo/osinfo_db.c | 81 ++++-
osinfo/osinfo_db.h | 4 +
osinfo/osinfo_loader.c | 77 ++++
osinfo/osinfo_os.c | 38 ++
osinfo/osinfo_os.h | 4 +
osinfo/osinfo_tree.c | 870 ++++++++++++++++++++++++++++++++++++++++
osinfo/osinfo_tree.h | 117 ++++++
osinfo/osinfo_treelist.c | 167 ++++++++
osinfo/osinfo_treelist.h | 82 ++++
tools/osinfo-detect.c | 127 +++++-
14 files changed, 1585 insertions(+), 24 deletions(-)
create mode 100644 osinfo/osinfo_tree.c
create mode 100644 osinfo/osinfo_tree.h
create mode 100644 osinfo/osinfo_treelist.c
create mode 100644 osinfo/osinfo_treelist.h
diff --git a/docs/reference/Libosinfo.types b/docs/reference/Libosinfo.types
index 2342f68..2cf0934 100644
--- a/docs/reference/Libosinfo.types
+++ b/docs/reference/Libosinfo.types
@@ -21,3 +21,5 @@ osinfo_productfilter_get_type
osinfo_productlist_get_type
osinfo_resources_get_type
osinfo_resourceslist_get_type
+osinfo_tree_get_type
+osinfo_treelist_get_type
diff --git a/osinfo/Makefile.am b/osinfo/Makefile.am
index 4bf12ed..98e2365 100644
--- a/osinfo/Makefile.am
+++ b/osinfo/Makefile.am
@@ -65,7 +65,10 @@ libosinfo_1_0_include_HEADERS = \
osinfo_media.h \
osinfo_medialist.h \
osinfo_resources.h \
- osinfo_resourceslist.h
+ osinfo_resourceslist.h \
+ osinfo_tree.h \
+ osinfo_treelist.h \
+ $(NULL)
libosinfo_1_0_la_SOURCES = \
osinfo_entity.c \
@@ -89,8 +92,11 @@ libosinfo_1_0_la_SOURCES = \
osinfo_medialist.c \
osinfo_resources.c \
osinfo_resourceslist.c \
+ osinfo_tree.c \
+ osinfo_treelist.c \
osinfo_db.c \
- osinfo_loader.c
+ osinfo_loader.c \
+ $(NULL)
if WITH_GOBJECT_INTROSPECTION
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 2f801af..1f1a161 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -16,6 +16,7 @@ LIBOSINFO_0.0.1 {
osinfo_db_add_device;
osinfo_db_add_deployment;
osinfo_db_guess_os_from_media;
+ osinfo_db_guess_os_from_tree;
osinfo_db_unique_values_for_property_in_os;
osinfo_db_unique_values_for_property_in_platform;
osinfo_db_unique_values_for_property_in_device;
@@ -115,6 +116,8 @@ LIBOSINFO_0.0.1 {
osinfo_os_get_family;
osinfo_os_get_media_list;
osinfo_os_add_media;
+ osinfo_os_get_tree_list;
+ osinfo_os_add_tree;
osinfo_os_get_minimum_resources;
osinfo_os_get_recommended_resources;
osinfo_os_add_minimum_resources;
@@ -204,6 +207,31 @@ LIBOSINFO_0.0.6 {
osinfo_os_get_devices_by_property;
} LIBOSINFO_0.0.5;
+LIBOSINFO_0.1.0 {
+ global:
+ osinfo_tree_new;
+ osinfo_tree_create_from_location;
+ osinfo_tree_create_from_location_async;
+ osinfo_tree_create_from_location_finish;
+ osinfo_tree_error_quark;
+ osinfo_tree_get_architecture;
+ osinfo_tree_get_boot_iso_path;
+ osinfo_tree_get_initrd_path;
+ osinfo_tree_get_kernel_path;
+ osinfo_tree_get_treeinfo_family;
+ osinfo_tree_get_treeinfo_variant;
+ osinfo_tree_get_treeinfo_version;
+ osinfo_tree_get_treeinfo_arch;
+ osinfo_tree_get_type;
+ osinfo_tree_get_url;
+ osinfo_treelist_get_type;
+ osinfo_treelist_new;
+ osinfo_treelist_new_copy;
+ osinfo_treelist_new_filtered;
+ osinfo_treelist_new_intersection;
+ osinfo_treelist_new_union;
+} LIBOSINFO_0.0.6;
+
/* Symbols in next release...
LIBOSINFO_0.0.2 {
diff --git a/osinfo/osinfo.h b/osinfo/osinfo.h
index 3d2acfe..0ec055b 100644
--- a/osinfo/osinfo.h
+++ b/osinfo/osinfo.h
@@ -46,6 +46,8 @@
#include <osinfo/osinfo_medialist.h>
#include <osinfo/osinfo_resources.h>
#include <osinfo/osinfo_resourceslist.h>
+#include <osinfo/osinfo_tree.h>
+#include <osinfo/osinfo_treelist.h>
#include <osinfo/osinfo_db.h>
#include <osinfo/osinfo_loader.h>
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index ecc8fbd..986e7c9 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -31,6 +31,7 @@ G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
#define OSINFO_DB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DB, OsinfoDbPrivate))
#define match_regex(pattern, str) (((pattern) == NULL && (str) == NULL) || \
+ ((pattern) == NULL) || \
((pattern) != NULL && (str) != NULL && \
g_regex_match_simple((pattern), (str), 0, 0)))
@@ -386,11 +387,10 @@ OsinfoOs *osinfo_db_guess_os_from_media(OsinfoDb *db,
const gchar *os_publisher = osinfo_media_get_publisher_id(os_media);
const gchar *os_application = osinfo_media_get_application_id(os_media);
- if ((match_regex (os_volume, media_volume) ||
- match_regex (os_application, media_application))
- &&
- (match_regex (os_system, media_system) ||
- match_regex (os_publisher, media_publisher))) {
+ if (match_regex (os_volume, media_volume) &&
+ match_regex (os_application, media_application) &&
+ match_regex (os_system, media_system) &&
+ match_regex (os_publisher, media_publisher)) {
ret = os;
if (matched_media != NULL)
*matched_media = os_media;
@@ -410,6 +410,77 @@ OsinfoOs *osinfo_db_guess_os_from_media(OsinfoDb *db,
return ret;
}
+
+/**
+ * osinfo_db_guess_os_from_tree:
+ * @db: the database
+ * @tree: the installation tree
+ * @matched_tree: (out) (transfer none) (allow-none): the matched operating
+ * system tree
+ *
+ * Guess operating system given a #OsinfoTree object.
+ *
+ * Returns: (transfer none): the operating system, or NULL if guessing failed
+ */
+OsinfoOs *osinfo_db_guess_os_from_tree(OsinfoDb *db,
+ OsinfoTree *tree,
+ OsinfoTree **matched_tree)
+{
+ OsinfoOs *ret = NULL;
+ GList *oss = NULL;
+ GList *os_iter;
+ const gchar *tree_family;
+ const gchar *tree_variant;
+ const gchar *tree_version;
+ const gchar *tree_arch;
+
+ g_return_val_if_fail(OSINFO_IS_DB(db), NULL);
+ g_return_val_if_fail(tree != NULL, NULL);
+
+ tree_family = osinfo_tree_get_treeinfo_family(tree);
+ tree_variant = osinfo_tree_get_treeinfo_variant(tree);
+ tree_version = osinfo_tree_get_treeinfo_version(tree);
+ tree_arch = osinfo_tree_get_treeinfo_arch(tree);
+
+ oss = osinfo_list_get_elements(OSINFO_LIST(db->priv->oses));
+ for (os_iter = oss; os_iter; os_iter = os_iter->next) {
+ OsinfoOs *os = OSINFO_OS(os_iter->data);
+ OsinfoTreeList *tree_list = osinfo_os_get_tree_list(os);
+ GList *trees = osinfo_list_get_elements(OSINFO_LIST(tree_list));
+ GList *tree_iter;
+
+ //trees = g_list_sort(trees, tree_family_compare);
+
+ for (tree_iter = trees; tree_iter; tree_iter = tree_iter->next) {
+ OsinfoTree *os_tree = OSINFO_TREE(tree_iter->data);
+ const gchar *os_family = osinfo_tree_get_treeinfo_family(os_tree);
+ const gchar *os_variant = osinfo_tree_get_treeinfo_variant(os_tree);
+ const gchar *os_version = osinfo_tree_get_treeinfo_version(os_tree);
+ const gchar *os_arch = osinfo_tree_get_treeinfo_arch(os_tree);
+
+ if (match_regex (os_family, tree_family) &&
+ match_regex (os_variant, tree_variant) &&
+ match_regex (os_version, tree_version) &&
+ match_regex (os_arch, tree_arch)) {
+ ret = os;
+ if (matched_tree != NULL)
+ *matched_tree = os_tree;
+ break;
+ }
+ }
+
+ g_list_free(trees);
+ g_object_unref(tree_list);
+
+ if (ret)
+ break;
+ }
+
+ g_list_free(oss);
+
+ return ret;
+}
+
struct osinfo_db_populate_values_args {
GHashTable *values;
const gchar *property;
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
index 79075d0..2edfee0 100644
--- a/osinfo/osinfo_db.h
+++ b/osinfo/osinfo_db.h
@@ -97,6 +97,10 @@ OsinfoOs *osinfo_db_guess_os_from_media(OsinfoDb *db,
OsinfoMedia *media,
OsinfoMedia **matched_media);
+OsinfoOs *osinfo_db_guess_os_from_tree(OsinfoDb *db,
+ OsinfoTree *tree,
+ OsinfoTree **matched_tree);
+
// Get me all unique values for property "vendor" among operating systems
GList *osinfo_db_unique_values_for_property_in_os(OsinfoDb *db, const gchar *propName);
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index cb3f19e..9517ec9 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -548,6 +548,64 @@ static OsinfoMedia *osinfo_loader_media (OsinfoLoader *loader,
return media;
}
+static OsinfoTree *osinfo_loader_tree (OsinfoLoader *loader,
+ xmlXPathContextPtr ctxt,
+ xmlNodePtr root,
+ const gchar *id,
+ GError **err)
+{
+ xmlNodePtr *nodes = NULL;
+ guint i;
+
+ gchar *arch = (gchar *)xmlGetProp(root, BAD_CAST "arch");
+ const gchar *const keys[] = {
+ OSINFO_TREE_PROP_URL,
+ OSINFO_TREE_PROP_KERNEL,
+ OSINFO_TREE_PROP_INITRD,
+ OSINFO_TREE_PROP_BOOT_ISO,
+ NULL
+ };
+
+ OsinfoTree *tree = osinfo_tree_new(id, arch);
+
+ osinfo_loader_entity(loader, OSINFO_ENTITY(tree), keys, ctxt, root, err);
+
+ gint nnodes = osinfo_loader_nodeset("./treeinfo/*", ctxt, &nodes, err);
+ if (error_is_set(err))
+ return NULL;
+
+ for (i = 0 ; i < nnodes ; i++) {
+ if (!nodes[i]->children ||
+ nodes[i]->children->type != XML_TEXT_NODE)
+ continue;
+
+ if (strcmp((const gchar *)nodes[i]->name,
+ OSINFO_TREE_PROP_TREEINFO_FAMILY + 9) == 0)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_FAMILY,
+ (const gchar *)nodes[i]->children->content);
+ else if (strcmp((const gchar *)nodes[i]->name,
+ OSINFO_TREE_PROP_TREEINFO_VARIANT + 9) == 0)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VARIANT,
+ (const gchar *)nodes[i]->children->content);
+ else if (strcmp((const gchar *)nodes[i]->name,
+ OSINFO_TREE_PROP_TREEINFO_VERSION + 9) == 0)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VERSION,
+ (const gchar *)nodes[i]->children->content);
+ else if (strcmp((const gchar *)nodes[i]->name,
+ OSINFO_TREE_PROP_TREEINFO_ARCH + 9) == 0)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_ARCH,
+ (const gchar *)nodes[i]->children->content);
+ }
+
+ g_free(nodes);
+
+ return tree;
+}
+
static OsinfoResources *osinfo_loader_resources(OsinfoLoader *loader,
xmlXPathContextPtr ctxt,
xmlNodePtr root,
@@ -672,6 +730,25 @@ static void osinfo_loader_os(OsinfoLoader *loader,
g_free(nodes);
+ nnodes = osinfo_loader_nodeset("./tree", ctxt, &nodes, err);
+ if (error_is_set(err))
+ goto cleanup;
+
+ for (i = 0 ; i < nnodes ; i++) {
+ xmlNodePtr saved = ctxt->node;
+ ctxt->node = nodes[i];
+ gchar *tree_id = g_strdup_printf ("%s:%u", id, i);
+ OsinfoTree *tree = osinfo_loader_tree(loader, ctxt, nodes[i], tree_id, err);
+ g_free (tree_id);
+ ctxt->node = saved;
+ if (error_is_set(err))
+ break;
+
+ osinfo_os_add_tree (os, tree);
+ }
+
+ g_free(nodes);
+
nnodes = osinfo_loader_nodeset("./resources", ctxt, &nodes, err);
if (error_is_set(err))
goto cleanup;
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index 39806d9..4954024 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -46,6 +46,7 @@ struct _OsinfoOsPrivate
GList *deviceLinks;
OsinfoMediaList *medias;
+ OsinfoTreeList *trees;
OsinfoResourcesList *minimum;
OsinfoResourcesList *recommended;
};
@@ -97,6 +98,8 @@ osinfo_os_finalize (GObject *object)
g_list_foreach(os->priv->deviceLinks, osinfo_device_link_free, NULL);
g_list_free(os->priv->deviceLinks);
+ g_object_unref(os->priv->medias);
+ g_object_unref(os->priv->trees);
/* Chain up to the parent class */
G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
@@ -141,6 +144,7 @@ osinfo_os_init (OsinfoOs *os)
os->priv->deviceLinks = NULL;
os->priv->medias = osinfo_medialist_new ();
+ os->priv->trees = osinfo_treelist_new ();
os->priv->minimum = osinfo_resourceslist_new ();
os->priv->recommended = osinfo_resourceslist_new ();
}
@@ -377,6 +381,40 @@ void osinfo_os_add_media(OsinfoOs *os, OsinfoMedia *media)
}
/**
+ * osinfo_os_get_tree_list:
+ * @os: an operating system
+ *
+ * Get all installation trees associated with operating system @os.
+ *
+ * Returns: (transfer full): A list of trees
+ */
+OsinfoTreeList *osinfo_os_get_tree_list(OsinfoOs *os)
+{
+ g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
+
+ OsinfoTreeList *newList = osinfo_treelist_new();
+
+ osinfo_list_add_all(OSINFO_LIST(newList), OSINFO_LIST(os->priv->trees));
+
+ return newList;
+}
+
+/**
+ * osinfo_os_add_tree:
+ * @os: an operating system
+ * @tree: (transfer none): the tree to add
+ *
+ * Adds installation tree @tree to operating system @os.
+ */
+void osinfo_os_add_tree(OsinfoOs *os, OsinfoTree *tree)
+{
+ g_return_if_fail(OSINFO_IS_OS(os));
+ g_return_if_fail(OSINFO_IS_TREE(tree));
+
+ osinfo_list_add(OSINFO_LIST(os->priv->trees), OSINFO_ENTITY(tree));
+}
+
+/**
* osinfo_os_get_minimum_resources:
* @os: an operating system
*
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
index 13c1aba..d4af9e8 100644
--- a/osinfo/osinfo_os.h
+++ b/osinfo/osinfo_os.h
@@ -28,6 +28,8 @@
#include <osinfo/osinfo_devicelist.h>
#include <osinfo/osinfo_medialist.h>
#include <osinfo/osinfo_media.h>
+#include <osinfo/osinfo_treelist.h>
+#include <osinfo/osinfo_tree.h>
#include <osinfo/osinfo_resources.h>
#include <osinfo/osinfo_resourceslist.h>
@@ -87,6 +89,8 @@ OsinfoDeviceLink *osinfo_os_add_device(OsinfoOs *os, OsinfoDevice *dev);
const gchar *osinfo_os_get_family(OsinfoOs *os);
OsinfoMediaList *osinfo_os_get_media_list(OsinfoOs *os);
void osinfo_os_add_media(OsinfoOs *os, OsinfoMedia *media);
+OsinfoTreeList *osinfo_os_get_tree_list(OsinfoOs *os);
+void osinfo_os_add_tree(OsinfoOs *os, OsinfoTree *tree);
OsinfoResourcesList *osinfo_os_get_minimum_resources(OsinfoOs *os);
OsinfoResourcesList *osinfo_os_get_recommended_resources(OsinfoOs *os);
void osinfo_os_add_minimum_resources(OsinfoOs *os, OsinfoResources *resources);
diff --git a/osinfo/osinfo_tree.c b/osinfo/osinfo_tree.c
new file mode 100644
index 0000000..0ec4f5b
--- /dev/null
+++ b/osinfo/osinfo_tree.c
@@ -0,0 +1,870 @@
+/*
+ * libosinfo: An installation tree for a (guest) OS
+ *
+ * Copyright (C) 2009-2011 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Zeeshan Ali <zeenix at redhat.com>
+ * Arjun Roy <arroy at redhat.com>
+ * Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <osinfo/osinfo.h>
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct _CreateFromLocationAsyncData CreateFromLocationAsyncData;
+struct _CreateFromLocationAsyncData {
+ GFile *file;
+ gchar *location;
+
+ gint priority;
+ GCancellable *cancellable;
+
+ GSimpleAsyncResult *res;
+
+ OsinfoTree *tree;
+};
+
+static void create_from_location_async_data_free(CreateFromLocationAsyncData *data)
+{
+ if (data->tree)
+ g_object_unref(data->tree);
+ g_object_unref(data->file);
+ g_clear_object(&data->cancellable);
+ g_object_unref(data->res);
+
+ g_slice_free(CreateFromLocationAsyncData, data);
+}
+
+typedef struct _CreateFromLocationData CreateFromLocationData;
+struct _CreateFromLocationData {
+ GMainLoop *main_loop;
+
+ GAsyncResult *res;
+};
+
+static void create_from_location_data_free(CreateFromLocationData *data)
+{
+ g_object_unref(data->res);
+ g_main_loop_unref(data->main_loop);
+
+ g_slice_free(CreateFromLocationData, data);
+}
+
+GQuark
+osinfo_tree_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (!quark)
+ quark = g_quark_from_static_string ("osinfo-tree-error");
+
+ return quark;
+}
+
+G_DEFINE_TYPE (OsinfoTree, osinfo_tree, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_TREE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ OSINFO_TYPE_TREE, \
+ OsinfoTreePrivate))
+
+/**
+ * SECTION:osinfo_tree
+ * @short_description: An installation tree for a (guest) OS
+ * @see_also: #OsinfoOs
+ *
+ * #OsinfoTree is an entity representing an installation tree
+ * a (guest) operating system.
+ */
+
+struct _OsinfoTreePrivate
+{
+ gboolean unused;
+};
+
+enum {
+ PROP_0,
+
+ PROP_ARCHITECTURE,
+ PROP_URL,
+ PROP_TREEINFO_FAMILY,
+ PROP_TREEINFO_VARIANT,
+ PROP_TREEINFO_VERSION,
+ PROP_TREEINFO_ARCH,
+ PROP_KERNEL_PATH,
+ PROP_INITRD_PATH,
+ PROP_BOOT_ISO_PATH,
+};
+
+static void
+osinfo_tree_get_property(GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoTree *tree = OSINFO_TREE(object);
+
+ switch (property_id) {
+ case PROP_ARCHITECTURE:
+ g_value_set_string(value,
+ osinfo_tree_get_architecture(tree));
+ break;
+
+ case PROP_URL:
+ g_value_set_string(value,
+ osinfo_tree_get_url(tree));
+ break;
+
+ case PROP_TREEINFO_FAMILY:
+ g_value_set_string(value,
+ osinfo_tree_get_treeinfo_family(tree));
+ break;
+
+ case PROP_TREEINFO_VARIANT:
+ g_value_set_string(value,
+ osinfo_tree_get_treeinfo_variant(tree));
+ break;
+
+ case PROP_TREEINFO_VERSION:
+ g_value_set_string(value,
+ osinfo_tree_get_treeinfo_version(tree));
+ break;
+
+ case PROP_TREEINFO_ARCH:
+ g_value_set_string(value,
+ osinfo_tree_get_treeinfo_arch(tree));
+ break;
+
+ case PROP_KERNEL_PATH:
+ g_value_set_string(value,
+ osinfo_tree_get_kernel_path(tree));
+ break;
+
+ case PROP_INITRD_PATH:
+ g_value_set_string(value,
+ osinfo_tree_get_initrd_path(tree));
+ break;
+
+ case PROP_BOOT_ISO_PATH:
+ g_value_set_string(value,
+ osinfo_tree_get_boot_iso_path(tree));
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+osinfo_tree_set_property(GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoTree *tree = OSINFO_TREE(object);
+
+ switch (property_id) {
+ case PROP_ARCHITECTURE:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_ARCHITECTURE,
+ g_value_get_string(value));
+ break;
+
+ case PROP_URL:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_URL,
+ g_value_get_string(value));
+ break;
+
+ case PROP_TREEINFO_FAMILY:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_FAMILY,
+ g_value_get_string(value));
+ break;
+
+ case PROP_TREEINFO_VARIANT:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VARIANT,
+ g_value_get_string(value));
+ break;
+
+ case PROP_TREEINFO_VERSION:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VERSION,
+ g_value_get_string(value));
+ break;
+
+ case PROP_TREEINFO_ARCH:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_ARCH,
+ g_value_get_string(value));
+ break;
+
+ case PROP_KERNEL_PATH:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_KERNEL,
+ g_value_get_string(value));
+ break;
+
+ case PROP_INITRD_PATH:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_INITRD,
+ g_value_get_string(value));
+ break;
+
+ case PROP_BOOT_ISO_PATH:
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_BOOT_ISO,
+ g_value_get_string(value));
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+osinfo_tree_finalize(GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(osinfo_tree_parent_class)->finalize(object);
+}
+
+/* Init functions */
+static void
+osinfo_tree_class_init(OsinfoTreeClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS(klass);
+ GParamSpec *pspec;
+
+ g_klass->finalize = osinfo_tree_finalize;
+ g_klass->get_property = osinfo_tree_get_property;
+ g_klass->set_property = osinfo_tree_set_property;
+ g_type_class_add_private(klass, sizeof(OsinfoTreePrivate));
+
+ /**
+ * OsinfoTree::architecture:
+ *
+ * The target hardware architecture of this tree.
+ */
+ pspec = g_param_spec_string("architecture",
+ "ARCHITECTURE",
+ "CPU Architecture",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_ARCHITECTURE, pspec);
+
+ /**
+ * OsinfoTree::url
+ *
+ * The URL to this tree.
+ */
+ pspec = g_param_spec_string("url",
+ "URL",
+ "The URL to this tree",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_URL, pspec);
+
+ /**
+ * OsinfoTree::volume-id
+ *
+ * Expected volume ID (regular expression) for ISO9660 image/device.
+ */
+ pspec = g_param_spec_string("volume-id",
+ "VolumeID",
+ "Expected ISO9660 volume ID",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_TREEINFO_FAMILY, pspec);
+
+ /**
+ * OsinfoTree::publisher-id
+ *
+ * Expected publisher ID (regular expression) for ISO9660 image/device.
+ */
+ pspec = g_param_spec_string("publisher-id",
+ "PublisherID",
+ "Expected ISO9660 publisher ID",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_TREEINFO_VARIANT, pspec);
+
+ /**
+ * OsinfoTree::application-id
+ *
+ * Expected application ID (regular expression) for ISO9660 image/device.
+ */
+ pspec = g_param_spec_string("application-id",
+ "ApplicationID",
+ "Expected ISO9660 application ID",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_TREEINFO_VERSION, pspec);
+
+ /**
+ * OsinfoTree::system-id
+ *
+ * Expected system ID (regular expression) for ISO9660 image/device.
+ */
+ pspec = g_param_spec_string("system-id",
+ "SystemID",
+ "Expected ISO9660 system ID",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_TREEINFO_ARCH, pspec);
+
+ /**
+ * OsinfoTree::kernel-path
+ *
+ * The path to the kernel image in the install tree.
+ */
+ pspec = g_param_spec_string("kernel-path",
+ "KernelPath",
+ "The path to the kernel image",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_KERNEL_PATH, pspec);
+
+ /**
+ * OsinfoTree::initrd-path
+ *
+ * The path to the initrd image in the install tree.
+ */
+ pspec = g_param_spec_string("initrd-path",
+ "InitrdPath",
+ "The path to the inirtd image",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_INITRD_PATH, pspec);
+
+ /**
+ * OsinfoTree::boot-iso-path
+ *
+ * The path to the boot ISO in the install tree
+ */
+ pspec = g_param_spec_string("boot-iso-path",
+ "BootISOPath",
+ "The path to the bootable ISO image",
+ NULL /* default value */,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+ g_object_class_install_property(g_klass, PROP_BOOT_ISO_PATH, pspec);
+
+}
+
+static void
+osinfo_tree_init(OsinfoTree *tree)
+{
+ OsinfoTreePrivate *priv;
+ tree->priv = priv = OSINFO_TREE_GET_PRIVATE(tree);
+}
+
+OsinfoTree *osinfo_tree_new(const gchar *id,
+ const gchar *architecture)
+{
+ OsinfoTree *tree;
+
+ tree = g_object_new(OSINFO_TYPE_TREE,
+ "id", id,
+ NULL);
+
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_ARCHITECTURE,
+ architecture);
+
+ return tree;
+}
+
+static void on_tree_create_from_location_ready(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CreateFromLocationData *data = (CreateFromLocationData *)user_data;
+
+ data->res = g_object_ref(res);
+
+ g_main_loop_quit(data->main_loop);
+}
+
+/**
+ * osinfo_tree_create_from_location:
+ * @location: the location of an installation tree
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: The location where to store any error, or %NULL
+ *
+ * Creates a new #OsinfoTree for installation tree at @location. The @location
+ * could be any URI that GIO can handle or a local path.
+ *
+ * NOTE: Currently this only works for trees with a .treeinfo file
+ *
+ * Returns: (transfer full): a new #OsinfoTree , or NULL on error
+ */
+OsinfoTree *osinfo_tree_create_from_location(const gchar *location,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CreateFromLocationData *data;
+ OsinfoTree *ret;
+
+ data = g_slice_new0(CreateFromLocationData);
+ data->main_loop = g_main_loop_new(g_main_context_get_thread_default(),
+ TRUE);
+
+ osinfo_tree_create_from_location_async(location,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ on_tree_create_from_location_ready,
+ data);
+
+ /* Loop till we get a reply (or time out) */
+ if (g_main_loop_is_running(data->main_loop))
+ g_main_loop_run(data->main_loop);
+
+ ret = osinfo_tree_create_from_location_finish(data->res, error);
+ create_from_location_data_free(data);
+
+ return ret;
+}
+
+static gboolean is_str_empty(const gchar *str) {
+ guint8 i;
+ gboolean ret = TRUE;
+
+ if ((str == NULL) || (*str == 0))
+ return TRUE;
+
+ for (i = 0; i < strlen(str); i++)
+ if (!g_ascii_isspace(str[i])) {
+ ret = FALSE;
+
+ break;
+ }
+
+ return ret;
+}
+
+
+static OsinfoTree *load_keyinfo(const gchar *location,
+ const gchar *content,
+ gsize length,
+ GError **error)
+{
+ GKeyFile *file = g_key_file_new();
+ OsinfoTree *tree = NULL;
+ gchar *family = NULL;
+ gchar *variant = NULL;
+ gchar *version = NULL;
+ gchar *arch = NULL;
+ gchar *kernel = NULL;
+ gchar *initrd = NULL;
+ gchar *bootiso = NULL;
+ gchar *group = NULL;
+
+ if (!g_key_file_load_from_data(file, content, length,
+ G_KEY_FILE_NONE, error))
+ goto cleanup;
+
+ if (!(family = g_key_file_get_string(file, "general", "family", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+ if (!(variant = g_key_file_get_string(file, "general", "variant", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+ if (!(version = g_key_file_get_string(file, "general", "version", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+ if (!(arch = g_key_file_get_string(file, "general", "arch", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+
+ if (arch) {
+ group = g_strdup_printf("images-%s", arch);
+
+ if (!(kernel = g_key_file_get_string(file, group, "kernel", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+ if (!(initrd = g_key_file_get_string(file, group, "initrd", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+
+ if (!(bootiso = g_key_file_get_string(file, group, "boot.iso", error)) &&
+ (*error && (*error)->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND &&
+ (*error)->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
+ goto cleanup;
+ }
+
+ tree = osinfo_tree_new(location, arch ? arch : "i386");
+
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_URL,
+ location);
+
+ if (!is_str_empty(family))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_FAMILY,
+ family);
+ if (!is_str_empty(variant))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VARIANT,
+ variant);
+ if (!is_str_empty(version))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VERSION,
+ version);
+ if (!is_str_empty(arch))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_ARCH,
+ arch);
+ if (!is_str_empty(kernel))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_KERNEL,
+ kernel);
+ if (!is_str_empty(initrd))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_INITRD,
+ initrd);
+ if (!is_str_empty(bootiso))
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_BOOT_ISO,
+ bootiso);
+
+ cleanup:
+ g_free(family);
+ g_free(variant);
+ g_free(version);
+ g_free(arch);
+ g_free(kernel);
+ g_free(initrd);
+ g_free(bootiso);
+ g_key_file_free(file);
+ return tree;
+}
+
+
+static void on_location_read(GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CreateFromLocationAsyncData *data;
+ GError *error = NULL;
+ gchar *content = NULL;
+ gsize length = 0;
+ OsinfoTree *ret = NULL;
+
+ data = (CreateFromLocationAsyncData *)user_data;
+
+ if (!g_file_load_contents_finish(G_FILE(source),
+ res,
+ &content,
+ &length,
+ NULL,
+ &error)) {
+ g_prefix_error(&error, "Failed to load .treeinfo file: ");
+ g_simple_async_result_take_error(data->res, error);
+ g_simple_async_result_complete(data->res);
+ create_from_location_async_data_free(data);
+ return;
+ }
+
+ if (!(ret = load_keyinfo(data->location,
+ content,
+ length,
+ &error))) {
+ g_prefix_error(&error, "Failed to process keyinfo file: ");
+ g_simple_async_result_take_error(data->res, error);
+ goto cleanup;
+ }
+
+ g_simple_async_result_set_op_res_gpointer(data->res, ret, NULL);
+
+ cleanup:
+ g_simple_async_result_complete (data->res);
+ create_from_location_async_data_free(data);
+ g_free(content);
+}
+
+/**
+ * osinfo_tree_create_from_location_async:
+ * @location: the location of an installation tree
+ * @priority: the I/O priority of the request
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: Function to call when result of this call is ready
+ * @user_data: The user data to pass to @callback, or %NULL
+ *
+ * Asynchronous variant of #osinfo_tree_create_from_location.
+ */
+void osinfo_tree_create_from_location_async(const gchar *location,
+ gint priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CreateFromLocationAsyncData *data;
+ gchar *treeinfo;
+
+ g_return_if_fail(location != NULL);
+
+ treeinfo = g_strdup_printf("%s/.treeinfo", location);
+
+ data = g_slice_new0(CreateFromLocationAsyncData);
+ data->res = g_simple_async_result_new
+ (NULL,
+ callback,
+ user_data,
+ osinfo_tree_create_from_location_async);
+ data->file = g_file_new_for_uri(treeinfo);
+ data->location = g_strdup(location);
+ data->priority = priority;
+ data->cancellable = cancellable;
+
+ /* XXX priority ? */
+ /* XXX probe other things besides just tree info */
+ g_file_load_contents_async(data->file,
+ cancellable,
+ on_location_read,
+ data);
+
+ g_free(treeinfo);
+}
+
+
+/**
+ * osinfo_tree_create_from_location_finish:
+ * @res: a #GAsyncResult
+ * @error: The location where to store any error, or %NULL
+ *
+ * Finishes an asynchronous tree object creation process started with
+ * #osinfo_tree_create_from_location_async.
+ *
+ * Returns: (transfer full): a new #OsinfoTree , or NULL on error
+ */
+OsinfoTree *osinfo_tree_create_from_location_finish(GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT(res);
+
+ g_return_val_if_fail(error == NULL || *error == NULL, NULL);
+
+ if (g_simple_async_result_propagate_error(simple, error))
+ return NULL;
+
+ return g_simple_async_result_get_op_res_gpointer(simple);
+}
+
+/**
+ * osinfo_tree_get_architecture:
+ * @tree: a #OsinfoTree instance
+ *
+ * Retrieves the target hardware architecture of the OS @tree provides.
+ *
+ * Returns: (transfer none): the hardware architecture, or NULL
+ */
+const gchar *osinfo_tree_get_architecture(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_ARCHITECTURE);
+}
+
+/**
+ * osinfo_tree_get_url:
+ * @tree: a #OsinfoTree instance
+ *
+ * The URL to the @tree
+ *
+ * Returns: (transfer none): the URL, or NULL
+ */
+const gchar *osinfo_tree_get_url(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_URL);
+}
+
+/**
+ * osinfo_tree_get_treeinfo_family:
+ * @tree: a #OsinfoTree instance
+ *
+ * If @tree is an ISO9660 image/device, this function retrieves the expected
+ * volume ID.
+ *
+ * Note: In practice, this will usually not be the exact copy of the volume ID
+ * string on the ISO image/device but rather a regular expression that matches
+ * it.
+ *
+ * Returns: (transfer none): the volume id, or NULL
+ */
+const gchar *osinfo_tree_get_treeinfo_family(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_FAMILY);
+}
+
+/**
+ * osinfo_tree_get_treeinfo_arch:
+ * @tree: a #OsinfoTree instance
+ *
+ * If @tree is an ISO9660 image/device, this function retrieves the expected
+ * system ID.
+ *
+ * Note: In practice, this will usually not be the exact copy of the system ID
+ * string on the ISO image/device but rather a regular expression that matches
+ * it.
+ *
+ * Returns: (transfer none): the system id, or NULL
+ */
+const gchar *osinfo_tree_get_treeinfo_arch(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_ARCH);
+}
+
+/**
+ * osinfo_tree_get_treeinfo_variant:
+ * @tree: a #OsinfoTree instance
+ *
+ * If @tree is an ISO9660 image/device, this function retrieves the expected
+ * publisher ID.
+ *
+ * Note: In practice, this will usually not be the exact copy of the publisher
+ * ID string on the ISO image/device but rather a regular expression that
+ * matches it.
+ *
+ * Returns: (transfer none): the publisher id, or NULL
+ */
+const gchar *osinfo_tree_get_treeinfo_variant(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VARIANT);
+}
+
+/**
+ * osinfo_tree_get_treeinfo_version:
+ * @tree: a #OsinfoTree instance
+ *
+ * If @tree is an ISO9660 image/device, this function retrieves the expected
+ * application ID.
+ *
+ * Note: In practice, this will usually not be the exact copy of the application
+ * ID string on the ISO image/device but rather a regular expression that
+ * matches it.
+ *
+ * Returns: (transfer none): the application id, or NULL
+ */
+const gchar *osinfo_tree_get_treeinfo_version(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VERSION);
+}
+
+/**
+ * osinfo_tree_get_boot_iso_path:
+ * @tree: a #OsinfoTree instance
+ *
+ * Retrieves the path to the boot_iso image in the install tree.
+ *
+ * Returns: (transfer none): the path to boot_iso image, or NULL
+ */
+const gchar *osinfo_tree_get_boot_iso_path(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_BOOT_ISO);
+}
+
+/**
+ * osinfo_tree_get_kernel_path:
+ * @tree: a #OsinfoTree instance
+ *
+ * Retrieves the path to the kernel image in the install tree.
+ *
+ * Note: This only applies to installer trees of 'Linux' OS family.
+ *
+ * Returns: (transfer none): the path to kernel image, or NULL
+ */
+const gchar *osinfo_tree_get_kernel_path(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_KERNEL);
+}
+
+/**
+ * osinfo_tree_get_initrd_path:
+ * @tree: a #OsinfoTree instance
+ *
+ * Retrieves the path to the initrd image in the install tree.
+ *
+ * Note: This only applies to installer trees of 'Linux' OS family.
+ *
+ * Returns: (transfer none): the path to initrd image, or NULL
+ */
+const gchar *osinfo_tree_get_initrd_path(OsinfoTree *tree)
+{
+ return osinfo_entity_get_param_value(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_INITRD);
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/osinfo/osinfo_tree.h b/osinfo/osinfo_tree.h
new file mode 100644
index 0000000..2cbdca8
--- /dev/null
+++ b/osinfo/osinfo_tree.h
@@ -0,0 +1,117 @@
+/*
+ * libosinfo: An installation tree for a (guest) OS
+ *
+ * Copyright (C) 2009-2011 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Zeeshan Ali <zeenix at redhat.com>
+ * Arjun Roy <arroy at redhat.com>
+ * Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <osinfo/osinfo_entity.h>
+
+#ifndef __OSINFO_TREE_H__
+#define __OSINFO_TREE_H__
+
+GQuark
+osinfo_tree_error_quark (void) G_GNUC_CONST;
+
+#define OSINFO_TREE_ERROR (osinfo_tree_error_quark ())
+
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_TREE (osinfo_tree_get_type ())
+#define OSINFO_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_TREE, OsinfoTree))
+#define OSINFO_IS_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_TREE))
+#define OSINFO_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_TREE, OsinfoTreeClass))
+#define OSINFO_IS_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_TREE))
+#define OSINFO_TREE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_TREE, OsinfoTreeClass))
+
+typedef struct _OsinfoTree OsinfoTree;
+
+typedef struct _OsinfoTreeClass OsinfoTreeClass;
+
+typedef struct _OsinfoTreePrivate OsinfoTreePrivate;
+
+#define OSINFO_TREE_PROP_ARCHITECTURE "architecture"
+#define OSINFO_TREE_PROP_URL "url"
+#define OSINFO_TREE_PROP_TREEINFO_FAMILY "treeinfo-family"
+#define OSINFO_TREE_PROP_TREEINFO_VARIANT "treeinfo-variant"
+#define OSINFO_TREE_PROP_TREEINFO_VERSION "treeinfo-version"
+#define OSINFO_TREE_PROP_TREEINFO_ARCH "treeinfo-arch"
+#define OSINFO_TREE_PROP_BOOT_ISO "boot-iso"
+#define OSINFO_TREE_PROP_KERNEL "kernel"
+#define OSINFO_TREE_PROP_INITRD "initrd"
+
+/* object */
+struct _OsinfoTree
+{
+ OsinfoEntity parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoTreePrivate *priv;
+};
+
+/* class */
+struct _OsinfoTreeClass
+{
+ OsinfoEntityClass parent_class;
+
+ /* class members */
+};
+
+GType osinfo_tree_get_type(void);
+
+OsinfoTree *osinfo_tree_new(const gchar *id, const gchar *architecture);
+OsinfoTree *osinfo_tree_create_from_location(const gchar *location,
+ GCancellable *cancellable,
+ GError **error);
+void osinfo_tree_create_from_location_async(const gchar *location,
+ gint priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+OsinfoTree *osinfo_tree_create_from_location_finish(GAsyncResult *res,
+ GError **error);
+
+const gchar *osinfo_tree_get_architecture(OsinfoTree *tree);
+const gchar *osinfo_tree_get_url(OsinfoTree *tree);
+const gchar *osinfo_tree_get_treeinfo_family(OsinfoTree *tree);
+const gchar *osinfo_tree_get_treeinfo_variant(OsinfoTree *tree);
+const gchar *osinfo_tree_get_treeinfo_version(OsinfoTree *tree);
+const gchar *osinfo_tree_get_treeinfo_arch(OsinfoTree *tree);
+/* XXX list of files to probe for in absence of treeinfo ? see virtinst isValidStore */
+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);
+/* XXX Xen kernel/initrd paths ? */
+
+#endif /* __OSINFO_TREE_H__ */
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/osinfo/osinfo_treelist.c b/osinfo/osinfo_treelist.c
new file mode 100644
index 0000000..22dda16
--- /dev/null
+++ b/osinfo/osinfo_treelist.c
@@ -0,0 +1,167 @@
+/*
+ * libosinfo:
+ *
+ * Copyright (C) 2009-2011 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Arjun Roy <arroy at redhat.com>
+ * Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoTreeList, osinfo_treelist, OSINFO_TYPE_LIST);
+
+#define OSINFO_TREELIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_TREELIST, OsinfoTreeListPrivate))
+
+/**
+ * SECTION:osinfo_treelist
+ * @short_description: A list of installation tree
+ * @see_also: #OsinfoList, #OsinfoTree
+ *
+ * #OsinfoTreeList is a list specialization that stores
+ * only #OsinfoTree objects.
+ */
+
+struct _OsinfoTreeListPrivate
+{
+ gboolean unused;
+};
+
+static void
+osinfo_treelist_finalize (GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_treelist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_treelist_class_init (OsinfoTreeListClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_treelist_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoTreeListPrivate));
+}
+
+static void
+osinfo_treelist_init (OsinfoTreeList *list)
+{
+ OsinfoTreeListPrivate *priv;
+ list->priv = priv = OSINFO_TREELIST_GET_PRIVATE(list);
+
+}
+
+/**
+ * osinfo_treelist_new:
+ *
+ * Construct a new tree list that is initially empty.
+ *
+ * Returns: (transfer full): an empty tree list
+ */
+OsinfoTreeList *osinfo_treelist_new(void)
+{
+ return g_object_new(OSINFO_TYPE_TREELIST,
+ "element-type", OSINFO_TYPE_TREE,
+ NULL);
+}
+
+/**
+ * osinfo_treelist_new_copy:
+ * @source: the tree list to copy
+ *
+ * Construct a new tree list that is filled with trees
+ * from @source
+ *
+ * Returns: (transfer full): a copy of the tree list
+ */
+OsinfoTreeList *osinfo_treelist_new_copy(OsinfoTreeList *source)
+{
+ OsinfoTreeList *newList = osinfo_treelist_new();
+ osinfo_list_add_all(OSINFO_LIST(newList),
+ OSINFO_LIST(source));
+ return newList;
+}
+
+/**
+ * osinfo_treelist_new_filtered:
+ * @source: the tree list to copy
+ * @filter: the filter to apply
+ *
+ * Construct a new tree list that is filled with trees
+ * from @source that match @filter
+ *
+ * Returns: (transfer full): a filtered copy of the tree list
+ */
+OsinfoTreeList *osinfo_treelist_new_filtered(OsinfoTreeList *source,
+ OsinfoFilter *filter)
+{
+ OsinfoTreeList *newList = osinfo_treelist_new();
+ osinfo_list_add_filtered(OSINFO_LIST(newList),
+ OSINFO_LIST(source),
+ filter);
+ return newList;
+}
+
+/**
+ * osinfo_treelist_new_intersection:
+ * @sourceOne: the first tree list to copy
+ * @sourceTwo: the second tree list to copy
+ *
+ * Construct a new tree list that is filled with only the
+ * trees that are present in both @sourceOne and @sourceTwo.
+ *
+ * Returns: (transfer full): an intersection of the two tree lists
+ */
+OsinfoTreeList *osinfo_treelist_new_intersection(OsinfoTreeList *sourceOne,
+ OsinfoTreeList *sourceTwo)
+{
+ OsinfoTreeList *newList = osinfo_treelist_new();
+ osinfo_list_add_intersection(OSINFO_LIST(newList),
+ OSINFO_LIST(sourceOne),
+ OSINFO_LIST(sourceTwo));
+ return newList;
+}
+
+/**
+ * osinfo_treelist_new_union:
+ * @sourceOne: the first tree list to copy
+ * @sourceTwo: the second tree list to copy
+ *
+ * Construct a new tree list that is filled with all the
+ * trees that are present in either @sourceOne and @sourceTwo.
+ *
+ * Returns: (transfer full): a union of the two tree lists
+ */
+OsinfoTreeList *osinfo_treelist_new_union(OsinfoTreeList *sourceOne,
+ OsinfoTreeList *sourceTwo)
+{
+ OsinfoTreeList *newList = osinfo_treelist_new();
+ osinfo_list_add_union(OSINFO_LIST(newList),
+ OSINFO_LIST(sourceOne),
+ OSINFO_LIST(sourceTwo));
+ return newList;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/osinfo/osinfo_treelist.h b/osinfo/osinfo_treelist.h
new file mode 100644
index 0000000..702c4aa
--- /dev/null
+++ b/osinfo/osinfo_treelist.h
@@ -0,0 +1,82 @@
+/*
+ * libosinfo: a list of installation tree
+ *
+ * Copyright (C) 2009-2011 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Zeeshan Ali <zeenix at redhat.com>
+ * Arjun Roy <arroy at redhat.com>
+ * Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <glib-object.h>
+#include <osinfo/osinfo_list.h>
+
+#ifndef __OSINFO_TREELIST_H__
+#define __OSINFO_TREELIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_TREELIST (osinfo_treelist_get_type ())
+#define OSINFO_TREELIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_TREELIST, OsinfoTreeList))
+#define OSINFO_IS_TREELIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_TREELIST))
+#define OSINFO_TREELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_TREELIST, OsinfoTreeListClass))
+#define OSINFO_IS_TREELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_TREELIST))
+#define OSINFO_TREELIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_TREELIST, OsinfoTreeListClass))
+
+typedef struct _OsinfoTreeList OsinfoTreeList;
+
+typedef struct _OsinfoTreeListClass OsinfoTreeListClass;
+
+typedef struct _OsinfoTreeListPrivate OsinfoTreeListPrivate;
+
+/* object */
+struct _OsinfoTreeList
+{
+ OsinfoList parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoTreeListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoTreeListClass
+{
+ OsinfoListClass parent_class;
+
+ /* class members */
+};
+
+GType osinfo_treelist_get_type(void);
+
+OsinfoTreeList *osinfo_treelist_new(void);
+OsinfoTreeList *osinfo_treelist_new_copy(OsinfoTreeList *source);
+OsinfoTreeList *osinfo_treelist_new_filtered(OsinfoTreeList *source, OsinfoFilter *filter);
+OsinfoTreeList *osinfo_treelist_new_intersection(OsinfoTreeList *sourceOne, OsinfoTreeList *sourceTwo);
+OsinfoTreeList *osinfo_treelist_new_union(OsinfoTreeList *sourceOne, OsinfoTreeList *sourceTwo);
+
+#endif /* __OSINFO_TREELIST_H__ */
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/tools/osinfo-detect.c b/tools/osinfo-detect.c
index 5413dec..b9ce7ba 100644
--- a/tools/osinfo-detect.c
+++ b/tools/osinfo-detect.c
@@ -35,6 +35,16 @@ typedef enum {
static OutputFormat format = OUTPUT_FORMAT_PLAIN;
+#define TYPE_STR_MEDIA "media"
+#define TYPE_STR_TREE "tree"
+
+typedef enum {
+ URL_TYPE_MEDIA,
+ URL_TYPE_TREE
+} OutputType;
+
+static OutputType type = URL_TYPE_MEDIA;
+
static gboolean parse_format_str(const gchar *option_name,
const gchar *value,
gpointer data,
@@ -56,12 +66,37 @@ static gboolean parse_format_str(const gchar *option_name,
return TRUE;
}
+static gboolean parse_type_str(const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ if (strcmp(value, TYPE_STR_MEDIA) == 0)
+ type = URL_TYPE_MEDIA;
+ else if (strcmp(value, TYPE_STR_TREE) == 0)
+ type = URL_TYPE_TREE;
+ else {
+ g_set_error(error,
+ G_OPTION_ERROR,
+ G_OPTION_ERROR_FAILED,
+ "Invalid value '%s'", value);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static GOptionEntry entries[] =
{
{ "format", 'f', 0,
G_OPTION_ARG_CALLBACK, parse_format_str,
"Output format. Default: plain",
"plain|env." },
+ { "type", 't', 0,
+ G_OPTION_ARG_CALLBACK, parse_type_str,
+ "URL type. Default: media",
+ "media|tree." },
{ NULL }
};
@@ -79,7 +114,7 @@ static void print_bootable(gboolean bootable)
g_print("Media is not bootable.\n");
}
-static void print_os(OsinfoOs *os, OsinfoMedia *media)
+static void print_os_media(OsinfoOs *os, OsinfoMedia *media)
{
if (os == NULL)
return;
@@ -103,12 +138,44 @@ static void print_os(OsinfoOs *os, OsinfoMedia *media)
}
}
+static void print_os_tree(OsinfoOs *os, OsinfoTree *tree, OsinfoTree *matched_tree)
+{
+ if (os == NULL)
+ return;
+
+ if (format == OUTPUT_FORMAT_ENV) {
+ const gchar *id = osinfo_entity_get_id(OSINFO_ENTITY(os));
+ const gchar *kernel = osinfo_tree_get_kernel_path(tree);
+ const gchar *initrd = osinfo_tree_get_initrd_path(tree);
+ const gchar *bootiso = osinfo_tree_get_boot_iso_path(tree);
+
+ if (!kernel)
+ kernel = osinfo_tree_get_kernel_path(matched_tree);
+ if (!initrd)
+ initrd = osinfo_tree_get_initrd_path(matched_tree);
+ if (!bootiso)
+ bootiso = osinfo_tree_get_boot_iso_path(matched_tree);
+
+ g_print("OSINFO_INSTALLER=%s\n", id);
+ g_print("OSINFO_TREE=%s\n",
+ osinfo_entity_get_id(OSINFO_ENTITY(matched_tree)));
+ if (kernel)
+ g_print("OSINFO_TREE_KERNEL=%s\n", kernel);
+ if (initrd)
+ g_print("OSINFO_TREE_INITRD=%s\n", initrd);
+ if (bootiso)
+ g_print("OSINFO_TREE_BOOT_ISO=%s\n", bootiso);
+ } else {
+ const gchar *name = osinfo_product_get_name(OSINFO_PRODUCT(os));
+
+ g_print("Tree is an installer for OS '%s'\n", name);
+ }
+}
+
gint main(gint argc, gchar **argv)
{
GOptionContext *context;
GError *error = NULL;
- OsinfoMedia *media = NULL;
- OsinfoMedia *matched_media = NULL;
OsinfoLoader *loader = NULL;
OsinfoDb *db = NULL;
OsinfoOs *os = NULL;
@@ -135,18 +202,6 @@ gint main(gint argc, gchar **argv)
g_type_init();
- media = osinfo_media_create_from_location(argv[1], NULL, &error);
- if (error != NULL) {
- if (error->code != OSINFO_MEDIA_ERROR_NOT_BOOTABLE) {
- g_printerr("Error parsing media: %s\n", error->message);
-
- ret = -3;
- goto EXIT;
- } else
- print_bootable(FALSE);
- } else
- print_bootable(TRUE);
-
loader = osinfo_loader_new();
osinfo_loader_process_default_path(loader, &error);
if (error != NULL) {
@@ -157,9 +212,39 @@ gint main(gint argc, gchar **argv)
}
db = osinfo_loader_get_db(loader);
- os = osinfo_db_guess_os_from_media(db, media, &matched_media);
- print_os(os, matched_media);
+ if (type == URL_TYPE_MEDIA) {
+ OsinfoMedia *media = NULL;
+ OsinfoMedia *matched_media = NULL;
+ media = osinfo_media_create_from_location(argv[1], NULL, &error);
+ if (error != NULL) {
+ if (error->code != OSINFO_MEDIA_ERROR_NOT_BOOTABLE) {
+ g_printerr("Error parsing media: %s\n", error->message);
+
+ ret = -3;
+ goto EXIT;
+ } else {
+ print_bootable(FALSE);
+ }
+ } else {
+ print_bootable(TRUE);
+ }
+ os = osinfo_db_guess_os_from_media(db, media, &matched_media);
+ print_os_media(os, matched_media);
+ } else if (type == URL_TYPE_TREE) {
+ OsinfoTree *tree = NULL;
+ OsinfoTree *matched_tree = NULL;
+ tree = osinfo_tree_create_from_location(argv[1], NULL, &error);
+ if (error != NULL) {
+ g_printerr("Error parsing tree: %s\n", error->message);
+
+ ret = -3;
+ goto EXIT;
+ }
+ os = osinfo_db_guess_os_from_tree(db, tree, &matched_tree);
+ print_os_tree(os, tree, matched_tree);
+ }
+
EXIT:
g_clear_error(&error);
@@ -168,3 +253,11 @@ EXIT:
return ret;
}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ */
--
1.7.7.6
More information about the virt-tools-list
mailing list