|
|
9b3a95 |
From 774f36026f1d3a4215be67845c2873135ceab6e4 Mon Sep 17 00:00:00 2001
|
|
|
9b3a95 |
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
|
9b3a95 |
Date: Wed, 16 Jan 2019 13:21:44 -0500
|
|
|
9b3a95 |
Subject: [PATCH] Don't fail merges when default streams differ
|
|
|
9b3a95 |
|
|
|
9b3a95 |
Instead of failing the merge on a default stream conflict, we will
|
|
|
9b3a95 |
instead treat it as having no default set. This is safe because if
|
|
|
9b3a95 |
the module is not yet installed, then this just means its packages
|
|
|
9b3a95 |
aren't visible and it needs to be selected explicitly.
|
|
|
9b3a95 |
|
|
|
9b3a95 |
If some packages from it are already installed, then the module
|
|
|
9b3a95 |
stream is already set, and thus changing the default won't matter.
|
|
|
9b3a95 |
|
|
|
9b3a95 |
Update documentation to reflect modified field in Defaults
|
|
|
9b3a95 |
|
|
|
9b3a95 |
Resolves: rhbz#1666871
|
|
|
9b3a95 |
|
|
|
9b3a95 |
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
|
9b3a95 |
---
|
|
|
9b3a95 |
.../modulemd-1.0/private/modulemd-private.h | 2 +
|
|
|
9b3a95 |
modulemd/v1/modulemd-defaults.c | 39 +++++++----
|
|
|
9b3a95 |
modulemd/v1/tests/test-modulemd-defaults.c | 66 ++++++++++++++++++-
|
|
|
9b3a95 |
.../modulemd-module-index-merger.h | 18 +++--
|
|
|
9b3a95 |
.../private/modulemd-defaults-v1-private.h | 2 +
|
|
|
9b3a95 |
modulemd/v2/modulemd-defaults-v1.c | 59 +++++++++++------
|
|
|
9b3a95 |
modulemd/v2/tests/ModulemdTests/merger.py | 33 +++++++---
|
|
|
9b3a95 |
.../v2/tests/test_data/overriding-nodejs.yaml | 11 ++++
|
|
|
9b3a95 |
test_data/defaults/overriding-nodejs.yaml | 10 +++
|
|
|
9b3a95 |
9 files changed, 191 insertions(+), 49 deletions(-)
|
|
|
9b3a95 |
create mode 100644 modulemd/v2/tests/test_data/overriding-nodejs.yaml
|
|
|
9b3a95 |
create mode 100644 test_data/defaults/overriding-nodejs.yaml
|
|
|
9b3a95 |
|
|
|
9b3a95 |
diff --git a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
|
|
|
9b3a95 |
index 20604efab843de6ac64cd9e181ce93d7e3a798fe..e9a785aed0d38598ce08d58e7e507d01698788a0 100644
|
|
|
9b3a95 |
--- a/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
|
|
|
9b3a95 |
+++ b/modulemd/v1/include/modulemd-1.0/private/modulemd-private.h
|
|
|
9b3a95 |
@@ -24,10 +24,12 @@ enum
|
|
|
9b3a95 |
MD_VERSION_MAX = G_MAXUINT64
|
|
|
9b3a95 |
};
|
|
|
9b3a95 |
|
|
|
9b3a95 |
#define MD_VERSION_LATEST MD_VERSION_2
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+#define DEFAULT_MERGE_CONFLICT "__merge_conflict__"
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
ModulemdModule *
|
|
|
9b3a95 |
modulemd_module_new_from_modulestream (ModulemdModuleStream *stream);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
ModulemdModuleStream *
|
|
|
9b3a95 |
modulemd_module_peek_modulestream (ModulemdModule *self);
|
|
|
9b3a95 |
diff --git a/modulemd/v1/modulemd-defaults.c b/modulemd/v1/modulemd-defaults.c
|
|
|
9b3a95 |
index 77ce30733945e30ffb8368986fa8c54c45697b5a..d44076eef0ac3bffae05f74b852fb6b51c2aee64 100644
|
|
|
9b3a95 |
--- a/modulemd/v1/modulemd-defaults.c
|
|
|
9b3a95 |
+++ b/modulemd/v1/modulemd-defaults.c
|
|
|
9b3a95 |
@@ -12,10 +12,11 @@
|
|
|
9b3a95 |
*/
|
|
|
9b3a95 |
|
|
|
9b3a95 |
#include "modulemd.h"
|
|
|
9b3a95 |
#include "modulemd-defaults.h"
|
|
|
9b3a95 |
#include "modulemd-simpleset.h"
|
|
|
9b3a95 |
+#include "private/modulemd-private.h"
|
|
|
9b3a95 |
#include "private/modulemd-yaml.h"
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
GQuark
|
|
|
9b3a95 |
modulemd_defaults_error_quark (void)
|
|
|
9b3a95 |
@@ -146,19 +147,38 @@ modulemd_defaults_set_default_stream (ModulemdDefaults *self,
|
|
|
9b3a95 |
const gchar *
|
|
|
9b3a95 |
modulemd_defaults_peek_default_stream (ModulemdDefaults *self)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
g_return_val_if_fail (self, NULL);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+ if (self->default_stream &&
|
|
|
9b3a95 |
+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ /* During an index merge, we determined that this was in conflict
|
|
|
9b3a95 |
+ * with another set of ModulemdDefaults for the same module. If we
|
|
|
9b3a95 |
+ * see this, treat it as no default stream when querying for it.
|
|
|
9b3a95 |
+ */
|
|
|
9b3a95 |
+ return NULL;
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
return self->default_stream;
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
gchar *
|
|
|
9b3a95 |
modulemd_defaults_dup_default_stream (ModulemdDefaults *self)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
g_return_val_if_fail (self, NULL);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+ if (self->default_stream &&
|
|
|
9b3a95 |
+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ /* During an index merge, we determined that this was in conflict
|
|
|
9b3a95 |
+ * with another set of ModulemdDefaults for the same module. If we
|
|
|
9b3a95 |
+ * see this, treat it as no default stream when querying for it.
|
|
|
9b3a95 |
+ */
|
|
|
9b3a95 |
+ return NULL;
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
return g_strdup (self->default_stream);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
void
|
|
|
9b3a95 |
@@ -753,28 +773,25 @@ modulemd_defaults_merge (ModulemdDefaults *first,
|
|
|
9b3a95 |
/* They had the same 'modified' value (such as both zero, for
|
|
|
9b3a95 |
* backwards-compatibility with 1.7.x and older.
|
|
|
9b3a95 |
* Merge them as best we can.
|
|
|
9b3a95 |
*/
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+ defaults = modulemd_defaults_copy (first);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
/* First check for incompatibilities with the streams */
|
|
|
9b3a95 |
- if (g_strcmp0 (modulemd_defaults_peek_default_stream (first),
|
|
|
9b3a95 |
- modulemd_defaults_peek_default_stream (second)))
|
|
|
9b3a95 |
+ if (g_strcmp0 (first->default_stream, second->default_stream))
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
/* Default streams don't match and override is not set.
|
|
|
9b3a95 |
* Return an error
|
|
|
9b3a95 |
*/
|
|
|
9b3a95 |
- g_set_error (
|
|
|
9b3a95 |
- error,
|
|
|
9b3a95 |
- MODULEMD_DEFAULTS_ERROR,
|
|
|
9b3a95 |
- MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS,
|
|
|
9b3a95 |
- "Conflicting default streams when merging defaults for module %s",
|
|
|
9b3a95 |
- modulemd_defaults_peek_module_name (first));
|
|
|
9b3a95 |
- return NULL;
|
|
|
9b3a95 |
+ /* They have conflicting default streams */
|
|
|
9b3a95 |
+ g_info ("Module stream mismatch in merge: %s != %s",
|
|
|
9b3a95 |
+ first->default_stream,
|
|
|
9b3a95 |
+ second->default_stream);
|
|
|
9b3a95 |
+ modulemd_defaults_set_default_stream (defaults, DEFAULT_MERGE_CONFLICT);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
|
|
|
9b3a95 |
- defaults = modulemd_defaults_copy (first);
|
|
|
9b3a95 |
-
|
|
|
9b3a95 |
/* Merge the profile defaults */
|
|
|
9b3a95 |
profile_defaults = modulemd_defaults_peek_profile_defaults (defaults);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
g_hash_table_iter_init (&iter,
|
|
|
9b3a95 |
modulemd_defaults_peek_profile_defaults (second));
|
|
|
9b3a95 |
diff --git a/modulemd/v1/tests/test-modulemd-defaults.c b/modulemd/v1/tests/test-modulemd-defaults.c
|
|
|
9b3a95 |
index 5d032d83cbca4046af13719f68bdbc6778d6879e..35142b885b3ec30f5109d53befe17be3e08d7b5a 100644
|
|
|
9b3a95 |
--- a/modulemd/v1/tests/test-modulemd-defaults.c
|
|
|
9b3a95 |
+++ b/modulemd/v1/tests/test-modulemd-defaults.c
|
|
|
9b3a95 |
@@ -602,10 +602,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
g_autofree gchar *yaml_base_path = NULL;
|
|
|
9b3a95 |
g_autofree gchar *yaml_override_path = NULL;
|
|
|
9b3a95 |
g_autoptr (GPtrArray) base_objects = NULL;
|
|
|
9b3a95 |
g_autoptr (GPtrArray) override_objects = NULL;
|
|
|
9b3a95 |
+ g_autoptr (GPtrArray) override_nodejs_objects = NULL;
|
|
|
9b3a95 |
g_autoptr (GPtrArray) merged_objects = NULL;
|
|
|
9b3a95 |
g_autoptr (ModulemdPrioritizer) prioritizer = NULL;
|
|
|
9b3a95 |
g_autoptr (GError) error = NULL;
|
|
|
9b3a95 |
GHashTable *htable = NULL;
|
|
|
9b3a95 |
gint64 prio;
|
|
|
9b3a95 |
@@ -618,10 +619,22 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
|
|
|
9b3a95 |
|
|
|
9b3a95 |
base_objects = modulemd_objects_from_file (yaml_base_path, &error);
|
|
|
9b3a95 |
g_assert_nonnull (base_objects);
|
|
|
9b3a95 |
g_assert_cmpint (base_objects->len, ==, 7);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ yaml_override_path =
|
|
|
9b3a95 |
+ g_strdup_printf ("%s/test_data/defaults/overriding-nodejs.yaml",
|
|
|
9b3a95 |
+ g_getenv ("MESON_SOURCE_ROOT"));
|
|
|
9b3a95 |
+ g_assert_nonnull (yaml_override_path);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ override_nodejs_objects =
|
|
|
9b3a95 |
+ modulemd_objects_from_file (yaml_override_path, &error);
|
|
|
9b3a95 |
+ g_clear_pointer (&yaml_override_path, g_free);
|
|
|
9b3a95 |
+ g_assert_nonnull (override_nodejs_objects);
|
|
|
9b3a95 |
+ g_assert_cmpint (override_nodejs_objects->len, ==, 1);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
yaml_override_path = g_strdup_printf (
|
|
|
9b3a95 |
"%s/test_data/defaults/overriding.yaml", g_getenv ("MESON_SOURCE_ROOT"));
|
|
|
9b3a95 |
g_assert_nonnull (yaml_override_path);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
override_objects = modulemd_objects_from_file (yaml_override_path, &error);
|
|
|
9b3a95 |
@@ -659,10 +672,52 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
|
|
|
9b3a95 |
fprintf (stderr, "Merge error: %s", error->message);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
g_assert_true (result);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+ /*
|
|
|
9b3a95 |
+ * Test that importing the nodejs overrides at the same priority level fails.
|
|
|
9b3a95 |
+ *
|
|
|
9b3a95 |
+ * This YAML has a conflicting default stream which should be ignored and set
|
|
|
9b3a95 |
+ * to "no default stream".
|
|
|
9b3a95 |
+ */
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ result = modulemd_prioritizer_add (
|
|
|
9b3a95 |
+ prioritizer, override_nodejs_objects, prio, &error);
|
|
|
9b3a95 |
+ g_assert_true (result);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ merged_objects = modulemd_prioritizer_resolve (prioritizer, &error);
|
|
|
9b3a95 |
+ g_assert_nonnull (merged_objects);
|
|
|
9b3a95 |
+ g_assert_cmpint (merged_objects->len, ==, 3);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ for (gint i = 0; i < merged_objects->len; i++)
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ if (MODULEMD_IS_DEFAULTS (g_ptr_array_index (merged_objects, i)))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ defaults = g_ptr_array_index (merged_objects, i);
|
|
|
9b3a95 |
+ if (!g_strcmp0 (modulemd_defaults_peek_module_name (defaults),
|
|
|
9b3a95 |
+ "nodejs"))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ g_assert_null (modulemd_defaults_peek_default_stream (defaults));
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ g_clear_pointer (&merged_objects, g_ptr_array_unref);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ /* Start over and test profile conflicts */
|
|
|
9b3a95 |
+ g_clear_pointer (&prioritizer, g_object_unref);
|
|
|
9b3a95 |
+ prioritizer = modulemd_prioritizer_new ();
|
|
|
9b3a95 |
+ result = modulemd_prioritizer_add (prioritizer, base_objects, prio, &error);
|
|
|
9b3a95 |
+ if (!result)
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ fprintf (stderr, "Merge error: %s", error->message);
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ g_assert_true (result);
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
/*
|
|
|
9b3a95 |
* Test that importing the overrides at the same priority level fails.
|
|
|
9b3a95 |
*
|
|
|
9b3a95 |
* These objects have several conflicts with the base objects that cannot be
|
|
|
9b3a95 |
* merged.
|
|
|
9b3a95 |
@@ -671,11 +726,11 @@ modulemd_defaults_test_prioritizer (DefaultsFixture *fixture,
|
|
|
9b3a95 |
modulemd_prioritizer_add (prioritizer, override_objects, prio, &error);
|
|
|
9b3a95 |
g_assert_false (result);
|
|
|
9b3a95 |
g_assert_cmpstr (
|
|
|
9b3a95 |
g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark");
|
|
|
9b3a95 |
g_assert_cmpint (
|
|
|
9b3a95 |
- error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS);
|
|
|
9b3a95 |
+ error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES);
|
|
|
9b3a95 |
g_clear_pointer (&error, g_error_free);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
/* The object's internal state is undefined after an error, so delete it */
|
|
|
9b3a95 |
g_clear_pointer (&prioritizer, g_object_unref);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
@@ -987,11 +1042,11 @@ modulemd_defaults_test_index_prioritizer (DefaultsFixture *fixture,
|
|
|
9b3a95 |
modulemd_prioritizer_add_index (prioritizer, override_index, prio, &error);
|
|
|
9b3a95 |
g_assert_false (result);
|
|
|
9b3a95 |
g_assert_cmpstr (
|
|
|
9b3a95 |
g_quark_to_string (error->domain), ==, "modulemd-defaults-error-quark");
|
|
|
9b3a95 |
g_assert_cmpint (
|
|
|
9b3a95 |
- error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_STREAMS);
|
|
|
9b3a95 |
+ error->code, ==, MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES);
|
|
|
9b3a95 |
g_clear_pointer (&error, g_error_free);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
/* The object's internal state is undefined after an error, so delete it */
|
|
|
9b3a95 |
g_clear_pointer (&prioritizer, g_object_unref);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
@@ -1138,10 +1193,15 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture,
|
|
|
9b3a95 |
g_assert_true (result);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
/* Add another almost-identical document, except with a conflicting default
|
|
|
9b3a95 |
* stream set.
|
|
|
9b3a95 |
+ *
|
|
|
9b3a95 |
+ * NOTE: when this was written (for issue 44 on GitHub), this was meant to be
|
|
|
9b3a95 |
+ * a hard error. As of 1.8.1 we expect this to just result in having no
|
|
|
9b3a95 |
+ * default stream for this module. This test has been slightly modified so
|
|
|
9b3a95 |
+ * that the expected result is now a pass.
|
|
|
9b3a95 |
*/
|
|
|
9b3a95 |
yaml_conflicting_path = g_strdup_printf (
|
|
|
9b3a95 |
"%s/test_data/defaults/issue44-2.yaml", g_getenv ("MESON_SOURCE_ROOT"));
|
|
|
9b3a95 |
g_assert_nonnull (yaml_conflicting_path);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
@@ -1149,11 +1209,11 @@ modulemd_regressions_issue44 (DefaultsFixture *fixture,
|
|
|
9b3a95 |
modulemd_objects_from_file (yaml_conflicting_path, &error);
|
|
|
9b3a95 |
g_assert_nonnull (conflicting_objects);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
result =
|
|
|
9b3a95 |
modulemd_prioritizer_add (prioritizer, conflicting_objects, 0, &error);
|
|
|
9b3a95 |
- g_assert_false (result);
|
|
|
9b3a95 |
+ g_assert_true (result);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
|
|
|
9b3a95 |
|
|
|
9b3a95 |
static void
|
|
|
9b3a95 |
modulemd_regressions_issue45 (DefaultsFixture *fixture,
|
|
|
9b3a95 |
diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
|
9b3a95 |
index 27cccb738dc805724268afa04acc13d4e250eae2..b019f0ed856684a003e9c2f6abefc70e1448246a 100644
|
|
|
9b3a95 |
--- a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
|
9b3a95 |
+++ b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
|
9b3a95 |
@@ -51,22 +51,30 @@ G_BEGIN_DECLS
|
|
|
9b3a95 |
* there exists two #ModulemdModuleStream entries that have different content
|
|
|
9b3a95 |
* for the same NSVC, the behavior is undefined.
|
|
|
9b3a95 |
*
|
|
|
9b3a95 |
* Merging #ModulemdDefaults entries behaves as follows:
|
|
|
9b3a95 |
*
|
|
|
9b3a95 |
+ * - Within a ModuleIndex, if two or more default entries reference the same
|
|
|
9b3a95 |
+ * module, the one with the highest modified field will be used and the
|
|
|
9b3a95 |
+ * others discarded.
|
|
|
9b3a95 |
+ * - When merging ModuleIndexes, if two or more indexes contain Defaults for
|
|
|
9b3a95 |
+ * the same module, but different modified values, the one with the highest
|
|
|
9b3a95 |
+ * modified value will be used and the others discarded.
|
|
|
9b3a95 |
* - Any module default that is provided by a single repository is
|
|
|
9b3a95 |
* authoritative.
|
|
|
9b3a95 |
* - If the repos have different priorities (not common), then the default for
|
|
|
9b3a95 |
* this module and stream name coming from the repo of higher priority will
|
|
|
9b3a95 |
- * be used and the default from the lower-priority repo will not be included.
|
|
|
9b3a95 |
+ * be used and the default from the lower-priority repo will not be included
|
|
|
9b3a95 |
+ * even if it has a higher modified value.
|
|
|
9b3a95 |
* - If the repos have the same priority (such as "fedora" and "updates" in the
|
|
|
9b3a95 |
- * Fedora Project), the entries will be merged as follows:
|
|
|
9b3a95 |
- * - If both repositories specify a default stream for the module, use it.
|
|
|
9b3a95 |
+ * Fedora Project) and modified value, the entries will be merged as follows:
|
|
|
9b3a95 |
+ * - If both repositories specify the same default stream for the module, use
|
|
|
9b3a95 |
+ * it.
|
|
|
9b3a95 |
* - If either repository specifies a default stream for the module and the
|
|
|
9b3a95 |
* other does not, use the one specified.
|
|
|
9b3a95 |
- * - If both repositories specify different streams, this is an unresolvable
|
|
|
9b3a95 |
- * merge conflict and the merge resolution will fail and report an error.
|
|
|
9b3a95 |
+ * - If both repositories specify different default streams, the merge will
|
|
|
9b3a95 |
+ * unset the default stream and proceed with the merge.
|
|
|
9b3a95 |
* - If both repositories specify a set of default profiles for a stream and
|
|
|
9b3a95 |
* the sets are equivalent, use that set.
|
|
|
9b3a95 |
* - If one repository specifies a set of default profiles for a stream and
|
|
|
9b3a95 |
* the other does not, use the one specified.
|
|
|
9b3a95 |
* - If both repositories specify a set of default profiles for a stream and
|
|
|
9b3a95 |
diff --git a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
|
|
|
9b3a95 |
index 9cac6cc53175a0eecca986f4fa96a7b7b1070957..de2ede98e6fb49bfd792b5f2913868fad6ff27db 100644
|
|
|
9b3a95 |
--- a/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
|
|
|
9b3a95 |
+++ b/modulemd/v2/include/modulemd-2.0/private/modulemd-defaults-v1-private.h
|
|
|
9b3a95 |
@@ -26,10 +26,12 @@ G_BEGIN_DECLS
|
|
|
9b3a95 |
* @stability: private
|
|
|
9b3a95 |
* @short_description: #ModulemdDefault methods that should only be used by
|
|
|
9b3a95 |
* internal consumers.
|
|
|
9b3a95 |
*/
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+#define DEFAULT_MERGE_CONFLICT "__merge_conflict__"
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
/**
|
|
|
9b3a95 |
* modulemd_defaults_v1_parse_yaml:
|
|
|
9b3a95 |
* @subdoc: (in): A #ModulemdSubdocumentInfo representing a defaults document
|
|
|
9b3a95 |
* of metadata version 1.
|
|
|
9b3a95 |
* @strict: (in): Whether the parser should return failure if it encounters an
|
|
|
9b3a95 |
diff --git a/modulemd/v2/modulemd-defaults-v1.c b/modulemd/v2/modulemd-defaults-v1.c
|
|
|
9b3a95 |
index c8f983105b529519365d0a653d8d07715f610b97..1c1cdd7b1036734a477b72d12f12526af1de777d 100644
|
|
|
9b3a95 |
--- a/modulemd/v2/modulemd-defaults-v1.c
|
|
|
9b3a95 |
+++ b/modulemd/v2/modulemd-defaults-v1.c
|
|
|
9b3a95 |
@@ -179,11 +179,22 @@ modulemd_defaults_v1_get_default_stream (ModulemdDefaultsV1 *self,
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
const gchar *default_stream = NULL;
|
|
|
9b3a95 |
g_return_val_if_fail (MODULEMD_IS_DEFAULTS_V1 (self), NULL);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
if (!intent)
|
|
|
9b3a95 |
- return self->default_stream;
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ if (self->default_stream &&
|
|
|
9b3a95 |
+ g_str_equal (self->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ /* During an index merge, we determined that this was in conflict
|
|
|
9b3a95 |
+ * with another set of ModulemdDefaults for the same module. If we
|
|
|
9b3a95 |
+ * see this, treat it as no default stream when querying for it.
|
|
|
9b3a95 |
+ */
|
|
|
9b3a95 |
+ return NULL;
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ return self->default_stream;
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
|
|
|
9b3a95 |
default_stream = g_hash_table_lookup (self->intent_default_streams, intent);
|
|
|
9b3a95 |
if (default_stream)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
if (default_stream[0] == '\0')
|
|
|
9b3a95 |
@@ -1159,12 +1170,10 @@ ModulemdDefaults *
|
|
|
9b3a95 |
modulemd_defaults_v1_merge (const gchar *module_name,
|
|
|
9b3a95 |
ModulemdDefaultsV1 *from,
|
|
|
9b3a95 |
ModulemdDefaultsV1 *into,
|
|
|
9b3a95 |
GError **error)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
- const gchar *into_default_stream;
|
|
|
9b3a95 |
- const gchar *from_default_stream;
|
|
|
9b3a95 |
g_autoptr (ModulemdDefaultsV1) merged = NULL;
|
|
|
9b3a95 |
GHashTableIter iter;
|
|
|
9b3a95 |
gpointer key, value;
|
|
|
9b3a95 |
GHashTable *intent_profiles = NULL;
|
|
|
9b3a95 |
GHashTable *merged_intent_profiles = NULL;
|
|
|
9b3a95 |
@@ -1175,37 +1184,45 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
|
9b3a95 |
g_autoptr (GError) nested_error = NULL;
|
|
|
9b3a95 |
|
|
|
9b3a95 |
merged = modulemd_defaults_v1_new (module_name);
|
|
|
9b3a95 |
|
|
|
9b3a95 |
/* Merge the default streams */
|
|
|
9b3a95 |
- into_default_stream = modulemd_defaults_v1_get_default_stream (into, NULL);
|
|
|
9b3a95 |
- from_default_stream = modulemd_defaults_v1_get_default_stream (from, NULL);
|
|
|
9b3a95 |
-
|
|
|
9b3a95 |
- if (into_default_stream && !from_default_stream)
|
|
|
9b3a95 |
+ if (into->default_stream && !from->default_stream)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
- merged, into_default_stream, NULL);
|
|
|
9b3a95 |
+ merged, into->default_stream, NULL);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
- else if (from_default_stream && !into_default_stream)
|
|
|
9b3a95 |
+ else if (from->default_stream && !into->default_stream)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
- merged, from_default_stream, NULL);
|
|
|
9b3a95 |
+ merged, from->default_stream, NULL);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
- else if (into_default_stream && from_default_stream)
|
|
|
9b3a95 |
+ else if (into->default_stream && from->default_stream)
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
- if (!g_str_equal (into_default_stream, from_default_stream))
|
|
|
9b3a95 |
+ if (g_str_equal (into->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
- g_set_error (error,
|
|
|
9b3a95 |
- MODULEMD_ERROR,
|
|
|
9b3a95 |
- MODULEMD_ERROR_VALIDATE,
|
|
|
9b3a95 |
- "Module stream mismatch in merge: %s != %s",
|
|
|
9b3a95 |
- into_default_stream,
|
|
|
9b3a95 |
- from_default_stream);
|
|
|
9b3a95 |
- return NULL;
|
|
|
9b3a95 |
+ /* A previous pass over this same module encountered a merge
|
|
|
9b3a95 |
+ * conflict, so we need to propagate that.
|
|
|
9b3a95 |
+ */
|
|
|
9b3a95 |
+ modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
+ merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ else if (!g_str_equal (into->default_stream, from->default_stream))
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ /* They have conflicting default streams */
|
|
|
9b3a95 |
+ g_info ("Module stream mismatch in merge: %s != %s",
|
|
|
9b3a95 |
+ into->default_stream,
|
|
|
9b3a95 |
+ from->default_stream);
|
|
|
9b3a95 |
+ modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
+ merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
|
9b3a95 |
+ }
|
|
|
9b3a95 |
+ else
|
|
|
9b3a95 |
+ {
|
|
|
9b3a95 |
+ /* They're the same, so store that */
|
|
|
9b3a95 |
+ modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
+ merged, into->default_stream, NULL);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
- modulemd_defaults_v1_set_default_stream (
|
|
|
9b3a95 |
- merged, into_default_stream, NULL);
|
|
|
9b3a95 |
}
|
|
|
9b3a95 |
else
|
|
|
9b3a95 |
{
|
|
|
9b3a95 |
/* Both values were NULL.
|
|
|
9b3a95 |
* Nothing to do, leave it blank.
|
|
|
9b3a95 |
diff --git a/modulemd/v2/tests/ModulemdTests/merger.py b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
|
9b3a95 |
index e7cbf4214bb111fbc5732fe983ee5ccee134fd83..49c2722959486aeb250d88daf7f068cacc8c3fe7 100644
|
|
|
9b3a95 |
--- a/modulemd/v2/tests/ModulemdTests/merger.py
|
|
|
9b3a95 |
+++ b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
|
9b3a95 |
@@ -104,26 +104,41 @@ class TestModuleIndexMerger(TestBase):
|
|
|
9b3a95 |
self.assertEqual(
|
|
|
9b3a95 |
len(httpd_defaults.get_default_profiles_for_stream('2.4', 'workstation')), 1)
|
|
|
9b3a95 |
self.assertEqual(
|
|
|
9b3a95 |
len(httpd_defaults.get_default_profiles_for_stream('2.6', 'workstation')), 3)
|
|
|
9b3a95 |
|
|
|
9b3a95 |
+ # Get another set of objects that will override the default stream for
|
|
|
9b3a95 |
+ # nodejs
|
|
|
9b3a95 |
+ override_nodejs_index = Modulemd.ModuleIndex()
|
|
|
9b3a95 |
+ override_nodejs_index.update_from_file(
|
|
|
9b3a95 |
+ path.join(
|
|
|
9b3a95 |
+ self.source_root,
|
|
|
9b3a95 |
+ "modulemd/v2/tests/test_data/overriding-nodejs.yaml"), True)
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ # Test that adding both of these at the same priority level results in
|
|
|
9b3a95 |
+ # the no default stream
|
|
|
9b3a95 |
+ merger = Modulemd.ModuleIndexMerger()
|
|
|
9b3a95 |
+ merger.associate_index(base_index, 0)
|
|
|
9b3a95 |
+ merger.associate_index(override_nodejs_index, 0)
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ merged_index = merger.resolve()
|
|
|
9b3a95 |
+ self.assertIsNotNone(merged_index)
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ nodejs = merged_index.get_module('nodejs')
|
|
|
9b3a95 |
+ self.assertIsNotNone(nodejs)
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
+ nodejs_defaults = nodejs.get_defaults()
|
|
|
9b3a95 |
+ self.assertIsNotNone(nodejs_defaults)
|
|
|
9b3a95 |
+ self.assertIsNone(nodejs_defaults.get_default_stream())
|
|
|
9b3a95 |
+
|
|
|
9b3a95 |
# Get another set of objects that will override the above
|
|
|
9b3a95 |
override_index = Modulemd.ModuleIndex()
|
|
|
9b3a95 |
override_index.update_from_file(
|
|
|
9b3a95 |
path.join(
|
|
|
9b3a95 |
self.source_root,
|
|
|
9b3a95 |
"modulemd/v2/tests/test_data/overriding.yaml"), True)
|
|
|
9b3a95 |
|
|
|
9b3a95 |
- # Test that adding both of these at the same priority level fails
|
|
|
9b3a95 |
- # with a merge conflict.
|
|
|
9b3a95 |
- merger = Modulemd.ModuleIndexMerger()
|
|
|
9b3a95 |
- merger.associate_index(base_index, 0)
|
|
|
9b3a95 |
- merger.associate_index(override_index, 0)
|
|
|
9b3a95 |
-
|
|
|
9b3a95 |
- with self.assertRaisesRegex(GLib.GError, 'Module stream mismatch in merge'):
|
|
|
9b3a95 |
- merged_index = merger.resolve()
|
|
|
9b3a95 |
-
|
|
|
9b3a95 |
# Test that override_index at a higher priority level succeeds
|
|
|
9b3a95 |
# Test that adding both of these at the same priority level fails
|
|
|
9b3a95 |
# with a merge conflict.
|
|
|
9b3a95 |
# Use randomly-selected high and low values to make sure we don't have
|
|
|
9b3a95 |
# sorting issues.
|
|
|
9b3a95 |
diff --git a/modulemd/v2/tests/test_data/overriding-nodejs.yaml b/modulemd/v2/tests/test_data/overriding-nodejs.yaml
|
|
|
9b3a95 |
new file mode 100644
|
|
|
9b3a95 |
index 0000000000000000000000000000000000000000..b588f5f542d84755fa74fc1dbf059c0766d2a712
|
|
|
9b3a95 |
--- /dev/null
|
|
|
9b3a95 |
+++ b/modulemd/v2/tests/test_data/overriding-nodejs.yaml
|
|
|
9b3a95 |
@@ -0,0 +1,11 @@
|
|
|
9b3a95 |
+---
|
|
|
9b3a95 |
+# Override the default stream
|
|
|
9b3a95 |
+document: modulemd-defaults
|
|
|
9b3a95 |
+version: 1
|
|
|
9b3a95 |
+data:
|
|
|
9b3a95 |
+ module: nodejs
|
|
|
9b3a95 |
+ stream: '9.0'
|
|
|
9b3a95 |
+ profiles:
|
|
|
9b3a95 |
+ '6.0': [default]
|
|
|
9b3a95 |
+ '8.0': [super]
|
|
|
9b3a95 |
+ '9.0': [supermegaultra]
|
|
|
9b3a95 |
\ No newline at end of file
|
|
|
9b3a95 |
diff --git a/test_data/defaults/overriding-nodejs.yaml b/test_data/defaults/overriding-nodejs.yaml
|
|
|
9b3a95 |
new file mode 100644
|
|
|
9b3a95 |
index 0000000000000000000000000000000000000000..937a2b899afc6b5254fd3b3e61e5b32035a3130a
|
|
|
9b3a95 |
--- /dev/null
|
|
|
9b3a95 |
+++ b/test_data/defaults/overriding-nodejs.yaml
|
|
|
9b3a95 |
@@ -0,0 +1,10 @@
|
|
|
9b3a95 |
+---
|
|
|
9b3a95 |
+document: modulemd-defaults
|
|
|
9b3a95 |
+version: 1
|
|
|
9b3a95 |
+data:
|
|
|
9b3a95 |
+ module: nodejs
|
|
|
9b3a95 |
+ stream: '9.0'
|
|
|
9b3a95 |
+ profiles:
|
|
|
9b3a95 |
+ '6.0': [default]
|
|
|
9b3a95 |
+ '8.0': [super]
|
|
|
9b3a95 |
+ '9.0': [supermegaultra]
|
|
|
9b3a95 |
\ No newline at end of file
|
|
|
9b3a95 |
--
|
|
|
9b3a95 |
2.20.1
|
|
|
9b3a95 |
|