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
commitce63f883174a942c94251726f4720823918eb976 (patch)
treecaf8d14f117c548185ee984809741ea7c3c2e4b5
parentbb443417b3c1aaa98bdf39d6bff7e95fc8a88ccf (diff)
downloadlibosinfo-ce63f883174a942c94251726f4720823918eb976.tar.gz
osinfo: pull media matching logic into public API
The logic for matching an unidentified media against a reference media 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.c32
-rw-r--r--osinfo/osinfo_media.c54
-rw-r--r--osinfo/osinfo_media.h1
-rw-r--r--tests/test-media.c93
5 files changed, 150 insertions, 31 deletions
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index a561788..724ea15 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -639,6 +639,7 @@ LIBOSINFO_1.8.0 {
LIBOSINFO_1.10.0 {
global:
+ osinfo_media_matches;
osinfo_os_get_complete_firmware_list;
} LIBOSINFO_1.8.0;
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index 5b60fc5..4002915 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -552,17 +552,6 @@ static gboolean compare_media(OsinfoMedia *media,
GList **fallback_oss)
{
GList *os_iter;
- const gchar *media_volume;
- const gchar *media_system;
- const gchar *media_publisher;
- const gchar *media_application;
- gint64 media_vol_size;
-
- media_volume = osinfo_media_get_volume_id(media);
- media_system = osinfo_media_get_system_id(media);
- media_publisher = osinfo_media_get_publisher_id(media);
- media_application = osinfo_media_get_application_id(media);
- media_vol_size = osinfo_media_get_volume_size(media);
for (os_iter = oss; os_iter; os_iter = os_iter->next) {
OsinfoOs *os = OSINFO_OS(os_iter->data);
@@ -576,18 +565,6 @@ static gboolean compare_media(OsinfoMedia *media,
for (media_iter = medias; media_iter; media_iter = media_iter->next) {
OsinfoMedia *os_media = OSINFO_MEDIA(media_iter->data);
const gchar *os_arch = osinfo_media_get_architecture(os_media);
- const gchar *os_volume = osinfo_media_get_volume_id(os_media);
- const gchar *os_system = osinfo_media_get_system_id(os_media);
- const gchar *os_publisher = osinfo_media_get_publisher_id(os_media);
- const gchar *os_application = osinfo_media_get_application_id(os_media);
- gint64 os_vol_size = osinfo_media_get_volume_size(os_media);
-
- if (os_volume == NULL &&
- os_system == NULL &&
- os_publisher == NULL &&
- os_application == NULL &&
- os_vol_size <= 0)
- continue;
if (fallback_oss != NULL) {
if (g_str_equal(os_arch, "all")) {
@@ -601,14 +578,7 @@ static gboolean compare_media(OsinfoMedia *media,
}
}
- if (os_vol_size <= 0)
- os_vol_size = media_vol_size;
-
- 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) &&
- os_vol_size == media_vol_size) {
+ if (osinfo_media_matches(media, os_media)) {
*ret_os = os;
if (matched != NULL)
*matched = os_media;
diff --git a/osinfo/osinfo_media.c b/osinfo/osinfo_media.c
index cb859a3..87c91a4 100644
--- a/osinfo/osinfo_media.c
+++ b/osinfo/osinfo_media.c
@@ -1857,3 +1857,57 @@ gboolean osinfo_media_is_bootable(OsinfoMedia *media)
return osinfo_entity_get_param_value_boolean(OSINFO_ENTITY(media),
OSINFO_MEDIA_PROP_BOOTABLE);
}
+
+#define match_regex(pattern, str) \
+ (((pattern) == NULL) || \
+ (((str) != NULL) && \
+ g_regex_match_simple((pattern), (str), 0, 0)))
+
+/**
+ * osinfo_media_matches:
+ * @media: an unidentified #OsinfoMedia instance
+ * @reference: a reference #OsinfoMedia instance
+ *
+ * Determines whether the metadata for the unidentified @media is a match
+ * for the @reference media.
+ *
+ * The metadata in the unidentified @media must be literal strings,
+ * while the metadata in the @reference media must be regular expressions.
+ *
+ * Returns: #TRUE if @media is a match for @reference. #FALSE otherwise
+ *
+ * Since: 1.10.0
+ */
+gboolean osinfo_media_matches(OsinfoMedia *media, OsinfoMedia *reference)
+{
+ const gchar *media_volume = osinfo_media_get_volume_id(media);
+ const gchar *media_system = osinfo_media_get_system_id(media);
+ const gchar *media_publisher = osinfo_media_get_publisher_id(media);
+ const gchar *media_application = osinfo_media_get_application_id(media);
+ gint64 media_vol_size = osinfo_media_get_volume_size(media);
+
+ const gchar *reference_volume = osinfo_media_get_volume_id(reference);
+ const gchar *reference_system = osinfo_media_get_system_id(reference);
+ const gchar *reference_publisher = osinfo_media_get_publisher_id(reference);
+ const gchar *reference_application = osinfo_media_get_application_id(reference);
+ gint64 reference_vol_size = osinfo_media_get_volume_size(reference);
+
+ if (reference_volume == NULL &&
+ reference_system == NULL &&
+ reference_publisher == NULL &&
+ reference_application == NULL &&
+ reference_vol_size <= 0)
+ return FALSE;
+
+ if (reference_vol_size <= 0)
+ reference_vol_size = media_vol_size;
+
+ if (match_regex(reference_volume, media_volume) &&
+ match_regex(reference_application, media_application) &&
+ match_regex(reference_system, media_system) &&
+ match_regex(reference_publisher, media_publisher) &&
+ reference_vol_size == media_vol_size)
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/osinfo/osinfo_media.h b/osinfo/osinfo_media.h
index f0369de..e20e248 100644
--- a/osinfo/osinfo_media.h
+++ b/osinfo/osinfo_media.h
@@ -138,3 +138,4 @@ gboolean osinfo_media_get_eject_after_install(OsinfoMedia *media);
gboolean osinfo_media_supports_installer_script(OsinfoMedia *media);
void osinfo_media_add_install_script(OsinfoMedia *media, OsinfoInstallScript *script);
OsinfoInstallScriptList *osinfo_media_get_install_script_list(OsinfoMedia *media);
+gboolean osinfo_media_matches(OsinfoMedia *media, OsinfoMedia *reference);
diff --git a/tests/test-media.c b/tests/test-media.c
index 0dc3d55..53a6124 100644
--- a/tests/test-media.c
+++ b/tests/test-media.c
@@ -139,6 +139,98 @@ test_loaded_installer_script(void)
g_object_unref(loader);
}
+static OsinfoMedia *
+test_create_media(const char *id,
+ const char *arch,
+ const char *volume,
+ const char *system,
+ const char *publisher,
+ const char *application,
+ guint64 size)
+{
+ OsinfoMedia *media = osinfo_media_new(id, arch);
+
+ if (volume)
+ osinfo_entity_set_param(OSINFO_ENTITY(media),
+ OSINFO_MEDIA_PROP_VOLUME_ID,
+ volume);
+ if (system)
+ osinfo_entity_set_param(OSINFO_ENTITY(media),
+ OSINFO_MEDIA_PROP_SYSTEM_ID,
+ system);
+ if (publisher)
+ osinfo_entity_set_param(OSINFO_ENTITY(media),
+ OSINFO_MEDIA_PROP_PUBLISHER_ID,
+ publisher);
+ if (application)
+ osinfo_entity_set_param(OSINFO_ENTITY(media),
+ OSINFO_MEDIA_PROP_APPLICATION_ID,
+ application);
+ if (size != 0)
+ osinfo_entity_set_param_int64(OSINFO_ENTITY(media),
+ OSINFO_MEDIA_PROP_VOLUME_SIZE,
+ size);
+
+ return media;
+}
+
+static void
+test_matching(void)
+{
+ OsinfoMedia *unknown = test_create_media("https://libosinfo.org/test/",
+ "x86_64",
+ "Fedora 35",
+ "LINUX",
+ "Fedora",
+ "Fedora OS",
+ 1234567);
+ /* Match with several optional fields */
+ OsinfoMedia *reference1 = test_create_media("https://fedoraproject.org/fedora/35/media1",
+ "x86_64",
+ "Fedora 35",
+ NULL,
+ NULL,
+ NULL,
+ 0);
+ /* Mis-match on volume */
+ OsinfoMedia *reference2 = test_create_media("https://fedoraproject.org/fedora/34/media2",
+ "x86_64",
+ "Fedora 34",
+ "LINUX",
+ NULL,
+ NULL,
+ 0);
+ /* Match with all fields with some regexes */
+ OsinfoMedia *reference3 = test_create_media("https://fedoraproject.org/fedora/unknown/media3",
+ "x86_64",
+ "Fedora [0-9]+",
+ "LINUX",
+ "Fedora",
+ "Fedora OS",
+ 0);
+ /* Match including vol size */
+ OsinfoMedia *reference4 = test_create_media("https://fedoraproject.org/fedora/35/media4",
+ "x86_64",
+ "Fedora 35",
+ "LINUX",
+ NULL,
+ NULL,
+ 1234567);
+ /* Mis-match on vol size */
+ OsinfoMedia *reference5 = test_create_media("https://fedoraproject.org/fedora/35/media5",
+ "x86_64",
+ "Fedora 35",
+ "LINUX",
+ NULL,
+ NULL,
+ 1234568);
+ g_assert(osinfo_media_matches(unknown, reference1));
+ g_assert(!osinfo_media_matches(unknown, reference2));
+ g_assert(osinfo_media_matches(unknown, reference3));
+ g_assert(osinfo_media_matches(unknown, reference4));
+ g_assert(!osinfo_media_matches(unknown, reference5));
+}
+
int
main(int argc, char *argv[])
{
@@ -148,6 +240,7 @@ main(int argc, char *argv[])
g_test_add_func("/media/loaded/attributes", test_loaded_attributes);
g_test_add_func("/media/loaded/no-installer", test_loaded_no_installer);
g_test_add_func("/media/loaded/installer-script", test_loaded_installer_script);
+ g_test_add_func("/media/matching", test_matching);
/* Upfront so we don't confuse valgrind */
osinfo_media_get_type();