summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2021-11-30 10:28:24 +0000
committerDaniel P. Berrangé <berrange@redhat.com>2022-02-04 14:14:49 +0000
commit4a8c19a2bdc963a574bed5c0789ded36eda337da (patch)
tree3639297b752685781bc0464676ae58cd4d1e92f1
parentce63f883174a942c94251726f4720823918eb976 (diff)
downloadlibosinfo-4a8c19a2bdc963a574bed5c0789ded36eda337da.tar.gz
osinfo: pull tree matching logic into public API
The logic for matching an unidentified tree against a reference tree is potentially useful to applications and should be part of a public API, rather than hidden. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
-rw-r--r--osinfo/libosinfo.syms1
-rw-r--r--osinfo/osinfo_db.c26
-rw-r--r--osinfo/osinfo_tree.c44
-rw-r--r--osinfo/osinfo_tree.h1
-rw-r--r--tests/test-tree.c70
5 files changed, 117 insertions, 25 deletions
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 724ea15..a49678c 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -641,6 +641,7 @@ LIBOSINFO_1.10.0 {
osinfo_media_matches;
osinfo_os_get_complete_firmware_list;
+ osinfo_tree_matches;
} LIBOSINFO_1.8.0;
/* Symbols in next release...
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index 4002915..3781712 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -762,15 +762,6 @@ static gboolean compare_tree(OsinfoTree *tree,
GList **fallback_oss)
{
GList *os_iter;
- const gchar *treeinfo_family;
- const gchar *treeinfo_variant;
- const gchar *treeinfo_version;
- const gchar *treeinfo_arch;
-
- treeinfo_family = osinfo_tree_get_treeinfo_family(tree);
- treeinfo_variant = osinfo_tree_get_treeinfo_variant(tree);
- treeinfo_version = osinfo_tree_get_treeinfo_version(tree);
- treeinfo_arch = osinfo_tree_get_treeinfo_arch(tree);
for (os_iter = oss; os_iter; os_iter = os_iter->next) {
OsinfoOs *os = OSINFO_OS(os_iter->data);
@@ -782,13 +773,6 @@ static gboolean compare_tree(OsinfoTree *tree,
for (tree_iter = trees; tree_iter; tree_iter = tree_iter->next) {
OsinfoTree *os_tree = OSINFO_TREE(tree_iter->data);
const gchar *os_tree_arch = NULL;
- const gchar *os_treeinfo_family;
- const gchar *os_treeinfo_variant;
- const gchar *os_treeinfo_version;
- const gchar *os_treeinfo_arch;
-
- if (!osinfo_tree_has_treeinfo(os_tree))
- continue;
os_tree_arch = osinfo_tree_get_architecture(os_tree);
if (fallback_oss != NULL) {
@@ -798,15 +782,7 @@ static gboolean compare_tree(OsinfoTree *tree,
}
}
- os_treeinfo_family = osinfo_tree_get_treeinfo_family(os_tree);
- os_treeinfo_variant = osinfo_tree_get_treeinfo_variant(os_tree);
- os_treeinfo_version = osinfo_tree_get_treeinfo_version(os_tree);
- os_treeinfo_arch = osinfo_tree_get_treeinfo_arch(os_tree);
-
- if (match_regex(os_treeinfo_family, treeinfo_family) &&
- match_regex(os_treeinfo_variant, treeinfo_variant) &&
- match_regex(os_treeinfo_version, treeinfo_version) &&
- match_regex(os_treeinfo_arch, treeinfo_arch)) {
+ if (osinfo_tree_matches(tree, os_tree)) {
*ret_os = os;
if (matched != NULL) {
*matched = os_tree;
diff --git a/osinfo/osinfo_tree.c b/osinfo/osinfo_tree.c
index fcf71c0..cedeadc 100644
--- a/osinfo/osinfo_tree.c
+++ b/osinfo/osinfo_tree.c
@@ -1180,3 +1180,47 @@ OsinfoTree *osinfo_tree_create_from_treeinfo(const gchar *treeinfo,
return load_keyinfo(location, treeinfo, strlen(treeinfo), error);
}
+
+#define match_regex(pattern, str) \
+ (((pattern) == NULL) || \
+ (((str) != NULL) && \
+ g_regex_match_simple((pattern), (str), 0, 0)))
+
+/**
+ * osinfo_tree_matches:
+ * @tree: an unidentified #OsinfoTree instance
+ * @reference: a reference #OsinfoTree instance
+ *
+ * Determines whether the metadata for the unidentified @tree is a match
+ * for the @reference tree.
+ *
+ * The metadata in the unidentified @tree must be literal strings,
+ * while the metadata in the @reference tree must be regular expressions.
+ *
+ * Returns: #TRUE if @tree is a match for @reference. #FALSE otherwise
+ *
+ * Since: 1.10.0
+ */
+gboolean osinfo_tree_matches(OsinfoTree *tree, OsinfoTree *reference)
+{
+ const gchar *tree_treeinfo_family = osinfo_tree_get_treeinfo_family(tree);
+ const gchar *tree_treeinfo_variant = osinfo_tree_get_treeinfo_variant(tree);
+ const gchar *tree_treeinfo_version = osinfo_tree_get_treeinfo_version(tree);
+ const gchar *tree_treeinfo_arch = osinfo_tree_get_treeinfo_arch(tree);
+
+ const gchar *reference_treeinfo_family = osinfo_tree_get_treeinfo_family(reference);
+ const gchar *reference_treeinfo_variant = osinfo_tree_get_treeinfo_variant(reference);
+ const gchar *reference_treeinfo_version = osinfo_tree_get_treeinfo_version(reference);
+ const gchar *reference_treeinfo_arch = osinfo_tree_get_treeinfo_arch(reference);
+
+ if (!osinfo_tree_has_treeinfo(reference))
+ return FALSE;
+
+ if (match_regex(reference_treeinfo_family, tree_treeinfo_family) &&
+ match_regex(reference_treeinfo_variant, tree_treeinfo_variant) &&
+ match_regex(reference_treeinfo_version, tree_treeinfo_version) &&
+ match_regex(reference_treeinfo_arch, tree_treeinfo_arch))
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/osinfo/osinfo_tree.h b/osinfo/osinfo_tree.h
index 3d96f5a..5671893 100644
--- a/osinfo/osinfo_tree.h
+++ b/osinfo/osinfo_tree.h
@@ -95,4 +95,5 @@ const gchar *osinfo_tree_get_initrd_path(OsinfoTree *tree);
OsinfoOs *osinfo_tree_get_os(OsinfoTree *tree);
void osinfo_tree_set_os(OsinfoTree *tree, OsinfoOs *os);
OsinfoOsVariantList *osinfo_tree_get_os_variants(OsinfoTree *tree);
+gboolean osinfo_tree_matches(OsinfoTree *tree, OsinfoTree *reference);
/* XXX Xen kernel/initrd paths ? */
diff --git a/tests/test-tree.c b/tests/test-tree.c
index deee819..88adccd 100644
--- a/tests/test-tree.c
+++ b/tests/test-tree.c
@@ -108,6 +108,75 @@ test_create_from_treeinfo(void)
g_object_unref(loader);
}
+static OsinfoTree *
+test_create_tree(const char *id,
+ const char *arch,
+ const char *family,
+ const char *variant,
+ const char *version,
+ const char *treearch)
+{
+ OsinfoTree *tree = osinfo_tree_new(id, arch);
+
+ osinfo_entity_set_param_boolean(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_HAS_TREEINFO,
+ TRUE);
+
+ if (family)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_FAMILY,
+ family);
+ if (variant)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VARIANT,
+ variant);
+ if (version)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_VERSION,
+ version);
+ if (treearch)
+ osinfo_entity_set_param(OSINFO_ENTITY(tree),
+ OSINFO_TREE_PROP_TREEINFO_ARCH,
+ treearch);
+
+ return tree;
+}
+
+static void
+test_matching(void)
+{
+ OsinfoTree *unknown = test_create_tree("https://libosinfo.org/test/",
+ "x86_64",
+ "Fedora",
+ "Server",
+ "35",
+ "x86_64");
+ /* Match with several optional fields */
+ OsinfoTree *reference1 = test_create_tree("https://fedoraproject.org/fedora/35/tree1",
+ "x86_64",
+ "Fedora",
+ NULL,
+ NULL,
+ NULL);
+ /* Mis-match on version */
+ OsinfoTree *reference2 = test_create_tree("https://fedoraproject.org/fedora/34/tree2",
+ "x86_64",
+ "Fedora",
+ NULL,
+ "34",
+ "x86_64");
+ /* Match with all fields with some regexes */
+ OsinfoTree *reference3 = test_create_tree("https://fedoraproject.org/fedora/unknown/tree3",
+ "x86_64",
+ "Fedora",
+ "(Server|Workstation)",
+ "3[0-9]",
+ NULL);
+ g_assert(osinfo_tree_matches(unknown, reference1));
+ g_assert(!osinfo_tree_matches(unknown, reference2));
+ g_assert(osinfo_tree_matches(unknown, reference3));
+}
+
int
main(int argc, char *argv[])
{
@@ -116,6 +185,7 @@ main(int argc, char *argv[])
g_test_add_func("/tree/basic", test_basic);
g_test_add_func("/tree/os-variants", test_os_variants);
g_test_add_func("/tree/create-from-treeinfo", test_create_from_treeinfo);
+ g_test_add_func("/tree/matching", test_matching);
/* Upfront so we don't confuse valgrind */
osinfo_tree_get_type();