Skip to content

Commit c24af17

Browse files
ggaineydralley
authored andcommitted
Loosened import version-restriction to x.y instead of x.y.z.
closes #2269 (cherry picked from commit 962d28a)
1 parent 0cd6acf commit c24af17

File tree

4 files changed

+91
-21
lines changed

4 files changed

+91
-21
lines changed

CHANGES/2269.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Loosened the version-restrictions on PulpImport to only require X.Y matching.

docs/workflows/import-export.rst

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,6 @@ In order to minimize space utilization, import/export operates on sets of
3737
:term:`Artifacts<Artifact>` only once per-export, rather than once for each
3838
:term:`Repository` being exported.
3939

40-
.. note::
41-
42-
Export will not operate on :term:`RepositoryVersions<RepositoryVersion>` that have
43-
been synchronized using ``policy=on_demand``. :term:`Artifacts<Artifact>` must actually
44-
exist in order to be exported - this is, after all the only way for the Downstream Pulp
45-
instance to gain access to them!
46-
47-
.. note::
48-
49-
Import and Export strictly control which directories may be read from/written to via
50-
the settings options ``ALLOWED_IMPORT_PATHS`` and ``ALLOWED_EXPORT_PATHS``.
51-
These default to empty, if not explicitly set attempts to import or export will fail
52-
with a validation error like
53-
54-
``"Path '/tmp/exports/' is not an allowed export path"``
55-
5640
Definitions
5741
^^^^^^^^^^^
5842
Upstream
@@ -87,6 +71,55 @@ Import order
8771
ModelResources be imported in order. Plugins are responsible for specifying the
8872
import-order of the ModelResources they own
8973

74+
Assumptions
75+
^^^^^^^^^^^
76+
77+
The import/export workflow operates on a set of assumptions. Violating them will result
78+
in error-messages as described below.
79+
80+
On-Demand content not supported
81+
-------------------------------
82+
83+
Export will not operate on :term:`RepositoryVersions<RepositoryVersion>` that have
84+
been synchronized using ``policy=on_demand`` or ``policy=streamed``. :term:`Artifacts<Artifact>`
85+
must actually exist in order to be exported - this is, after
86+
all the only way for the Downstream Pulp instance to gain access to them!
87+
88+
If a repository is specified for export that utilized on-demand/streamed syncing, the
89+
export will fail with a RuntimeError:
90+
91+
``Remote artifacts cannot be exported.``
92+
93+
Export/Import Directories must be explicitly allowed
94+
----------------------------------------------------
95+
96+
Import and Export strictly control which directories may be read from/written to via
97+
the settings options ``ALLOWED_IMPORT_PATHS`` and ``ALLOWED_EXPORT_PATHS``.
98+
These default to empty - if they not explicitly set, attempts to import or export will fail
99+
with a validation error like
100+
101+
``"Path '/tmp/exports/' is not an allowed export path"``
102+
103+
Installed plugins must match
104+
----------------------------
105+
106+
A Downstream must support the complete set of plugins present in a given export. If the
107+
export includes plugins that are not installed in the Downstream, an import attempt will
108+
fail with a validation error like
109+
110+
``Export uses pulp_rpm which is not installed.``
111+
112+
Version-compatibility required
113+
------------------------------
114+
115+
The export-to-import workflow is built on the assumption that the Upstream and
116+
Downstream instances are running "compatible" versions of pulpcore and plugins. In this
117+
context, "compatible" is defined as **"share the same X.Y version"**. If this is not the
118+
case, an import attempt will fail with a validation error like
119+
120+
``Export version 3.14.15 of pulpcore incompatible with installed version 3.16.3.``
121+
122+
90123
Exporting
91124
^^^^^^^^^
92125

pulpcore/app/tasks/importer.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ def _import_file(fpath, resource_class, retry=False):
9191

9292

9393
def _check_versions(version_json):
94-
"""Compare the export version_json to the installed components."""
94+
"""
95+
Compare the export version_json to the installed components.
96+
97+
An upstream whose db-metadata doesn't match the downstream won't import successfully; check
98+
for compatibility and raise a ValidationError if incompatible versions are found.
99+
"""
95100
error_messages = []
96101
for component in version_json:
97102
try:
@@ -101,10 +106,13 @@ def _check_versions(version_json):
101106
_("Export uses {} which is not installed.").format(component["component"])
102107
)
103108
else:
104-
if version != component["version"]:
109+
# Check that versions are compatible. Currently, "compatible" is defined as "same X.Y".
110+
# Versions are strings that generally look like "X.Y.Z" or "X.Y.Z.dev"; we check that
111+
# first two places are the same.
112+
if version.split(".")[:2] != component["version"].split(".")[:2]:
105113
error_messages.append(
106114
_(
107-
"Export version {export_ver} of {component} does not match "
115+
"Export version {export_ver} of {component} incompatible with "
108116
"installed version {ver}."
109117
).format(
110118
export_ver=component["version"],
@@ -113,8 +121,8 @@ def _check_versions(version_json):
113121
)
114122
)
115123

116-
if error_messages:
117-
raise ValidationError((" ".join(error_messages)))
124+
if error_messages:
125+
raise ValidationError((" ".join(error_messages)))
118126

119127

120128
def import_repository_version(importer_pk, destination_repo_pk, source_repo_name, tar_path):
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from unittest.mock import patch
2+
3+
from django.test import TestCase
4+
from rest_framework.serializers import ValidationError
5+
6+
from pulpcore.app.tasks.importer import _check_versions
7+
8+
9+
class TestObject:
10+
version = "1.2.3" # Every component is vers 1.2.3
11+
12+
13+
class TestCheckVersions(TestCase):
14+
@patch("pulpcore.app.tasks.importer.get_distribution", return_value=TestObject())
15+
def test_vers_check(self, mock_get_distribution):
16+
export_json = [{"component": "xyz", "version": "1.2.3"}]
17+
_check_versions(export_json)
18+
19+
export_json = [{"component": "xy", "version": "1.2"}]
20+
_check_versions(export_json)
21+
22+
export_json = [{"component": "x_noty_z", "version": "1.4.3"}]
23+
with self.assertRaises(ValidationError):
24+
_check_versions(export_json)
25+
26+
export_json = [{"component": "notx_y_z", "version": "2.2.3"}]
27+
with self.assertRaises(ValidationError):
28+
_check_versions(export_json)

0 commit comments

Comments
 (0)