Skip to content

Commit daf186d

Browse files
committed
Remove backward compatibility for manifest with artifact
This commit removes support for manifests storing their data inside an artifact instead of using the recently introduced Manifest.data text field. closes #1621
1 parent bf5c789 commit daf186d

File tree

7 files changed

+14
-162
lines changed

7 files changed

+14
-162
lines changed

CHANGES/1621.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Removed backward compatibility support for manifests which store their data inside an artifact.

pulp_container/app/downloaders.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
from pulpcore.plugin.download import DownloaderFactory, HttpDownloader
1212

13-
from pulp_container.constants import V2_ACCEPT_HEADERS
14-
1513
log = getLogger(__name__)
1614

1715
HeadResult = namedtuple(
@@ -53,11 +51,7 @@ async def _run(self, handle_401=True, extra_data=None):
5351
handle_401(bool): If true, catch 401, request a new token and retry.
5452
5553
"""
56-
# manifests are header sensitive, blobs do not care
57-
# these accept headers are going to be sent with every request to ensure downloader
58-
# can download manifests, namely in the repair core task
59-
# FIXME this can be rolledback after https://github.com/pulp/pulp_container/issues/1288
60-
headers = V2_ACCEPT_HEADERS
54+
headers = {}
6155
repo_name = None
6256
if extra_data is not None:
6357
headers = extra_data.get("headers", headers)

pulp_container/app/redirects.py

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from django.conf import settings
22
from django.core.exceptions import ObjectDoesNotExist
33
from django.shortcuts import redirect
4-
from django.http import Http404
54

65
from pulp_container.app.exceptions import ManifestNotFound
76
from pulp_container.app.utils import get_accepted_media_types
@@ -91,47 +90,6 @@ def redirect_to_object_storage(self, artifact, return_media_type):
9190
)
9291
return redirect(content_url)
9392

94-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifests
95-
def redirect_to_artifact(self, content_name, manifest, manifest_media_type):
96-
"""
97-
Search for the passed manifest's artifact and issue a redirect.
98-
"""
99-
try:
100-
artifact = manifest._artifacts.get()
101-
except ObjectDoesNotExist:
102-
raise Http404(f"An artifact for '{content_name}' was not found")
103-
104-
return self.redirect_to_object_storage(artifact, manifest_media_type)
105-
106-
def issue_tag_redirect(self, tag):
107-
"""
108-
Issue a redirect if an accepted media type requires it or return not found if manifest
109-
version is not supported.
110-
"""
111-
if tag.tagged_manifest.data:
112-
return super().issue_tag_redirect(tag)
113-
114-
manifest_media_type = tag.tagged_manifest.media_type
115-
if manifest_media_type == MEDIA_TYPE.MANIFEST_V1:
116-
return self.redirect_to_artifact(
117-
tag.name, tag.tagged_manifest, MEDIA_TYPE.MANIFEST_V1_SIGNED
118-
)
119-
elif manifest_media_type in get_accepted_media_types(self.request.headers):
120-
return self.redirect_to_artifact(tag.name, tag.tagged_manifest, manifest_media_type)
121-
else:
122-
raise ManifestNotFound(reference=tag.name)
123-
124-
def issue_manifest_redirect(self, manifest):
125-
"""
126-
Directly redirect to an associated manifest's artifact.
127-
"""
128-
if manifest.data:
129-
return super().issue_manifest_redirect(manifest)
130-
131-
return self.redirect_to_artifact(manifest.digest, manifest, manifest.media_type)
132-
133-
# END OF BACKWARD COMPATIBILITY
134-
13593

13694
class AzureStorageRedirects(S3StorageRedirects):
13795
"""

pulp_container/app/registry.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,6 @@ async def get_tag(self, request):
199199
"Content-Type": return_media_type,
200200
"Docker-Content-Digest": tag.tagged_manifest.digest,
201201
}
202-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
203-
if not tag.tagged_manifest.data:
204-
return await self.dispatch_tag(request, tag, response_headers)
205-
# END OF BACKWARD COMPATIBILITY
206202
return web.Response(text=tag.tagged_manifest.data, headers=response_headers)
207203

208204
# return what was found in case media_type is accepted header (docker, oci)
@@ -212,41 +208,11 @@ async def get_tag(self, request):
212208
"Content-Type": return_media_type,
213209
"Docker-Content-Digest": tag.tagged_manifest.digest,
214210
}
215-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
216-
if not tag.tagged_manifest.data:
217-
return await self.dispatch_tag(request, tag, response_headers)
218-
# END OF BACKWARD COMPATIBILITY
219211
return web.Response(text=tag.tagged_manifest.data, headers=response_headers)
220212

221213
# return 404 in case the client is requesting docker manifest v2 schema 1
222214
raise PathNotResolved(tag_name)
223215

224-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
225-
async def dispatch_tag(self, request, tag, response_headers):
226-
"""
227-
Finds an artifact associated with a Tag and sends it to the client, otherwise tries
228-
to stream it.
229-
230-
Args:
231-
request(:class:`~aiohttp.web.Request`): The request to prepare a response for.
232-
tag: Tag
233-
response_headers (dict): dictionary that contains the 'Content-Type' header to send
234-
with the response
235-
236-
Returns:
237-
:class:`aiohttp.web.StreamResponse` or :class:`aiohttp.web.FileResponse`: The response
238-
streamed back to the client.
239-
240-
"""
241-
try:
242-
artifact = await tag.tagged_manifest._artifacts.aget()
243-
except ObjectDoesNotExist:
244-
ca = await sync_to_async(lambda x: x[0])(tag.tagged_manifest.contentartifact_set.all())
245-
return await self._stream_content_artifact(request, web.StreamResponse(), ca)
246-
else:
247-
return await Registry._dispatch(artifact, response_headers)
248-
# END OF BACKWARD COMPATIBILITY
249-
250216
@RegistryContentCache(
251217
base_key=lambda req, cac: Registry.find_base_path_cached(req, cac),
252218
auth=lambda req, cac, bk: Registry.auth_cached(req, cac, bk),
@@ -282,16 +248,6 @@ async def get_by_digest(self, request):
282248
"Content-Type": manifest.media_type,
283249
"Docker-Content-Digest": manifest.digest,
284250
}
285-
# TODO: BACKWARD COMPATIBILITY - remove after migrating to artifactless manifest
286-
if not manifest.data:
287-
if saved_artifact := await manifest._artifacts.afirst():
288-
return await Registry._dispatch(saved_artifact, headers)
289-
else:
290-
ca = await sync_to_async(lambda x: x[0])(manifest.contentartifact_set.all())
291-
return await self._stream_content_artifact(
292-
request, web.StreamResponse(), ca
293-
)
294-
# END OF BACKWARD COMPATIBILITY
295251
return web.Response(text=manifest.data, headers=headers)
296252
elif content_type == "blobs":
297253
ca = await ContentArtifact.objects.select_related("artifact", "content").aget(

pulp_container/app/registry_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ def handle_safe_method(self, request, path, pk):
11201120
self.fetch_manifest(remote, pk)
11211121
return redirects.redirect_to_content_app("manifests", pk)
11221122
elif manifest:
1123-
return redirects.issue_manifest_redirect(manifest)
1123+
return Response(manifest.data)
11241124
else:
11251125
raise ManifestNotFound(reference=pk)
11261126

pulp_container/app/tasks/sign.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import hashlib
44

55
from aiofiles import tempfile
6-
from asgiref.sync import sync_to_async
76
from django.conf import settings
87
from django.db.models import Q
98

@@ -103,23 +102,10 @@ async def create_signature(manifest, reference, signing_service):
103102
"""
104103
async with semaphore:
105104
# download and write file for object storage
106-
if not manifest.data:
107-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
108-
artifact = await manifest._artifacts.aget()
109-
if settings.STORAGES["default"]["BACKEND"] != "pulpcore.app.models.storage.FileSystem":
110-
async with tempfile.NamedTemporaryFile(dir=".", mode="wb", delete=False) as tf:
111-
await tf.write(await sync_to_async(artifact.file.read)())
112-
await tf.flush()
113-
artifact.file.close()
114-
manifest_path = tf.name
115-
else:
116-
manifest_path = artifact.file.path
117-
# END OF BACKWARD COMPATIBILITY
118-
else:
119-
async with tempfile.NamedTemporaryFile(dir=".", mode="wb", delete=False) as tf:
120-
await tf.write(manifest.data.encode("utf-8"))
121-
await tf.flush()
122-
manifest_path = tf.name
105+
async with tempfile.NamedTemporaryFile(dir=".", mode="wb", delete=False) as tf:
106+
await tf.write(manifest.data.encode("utf-8"))
107+
await tf.flush()
108+
manifest_path = tf.name
123109

124110
async with tempfile.NamedTemporaryFile(dir=".", prefix="signature") as tf:
125111
sig_path = tf.name

pulp_container/app/tasks/sync_stages.py

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
validate_manifest,
3636
calculate_digest,
3737
filter_resources,
38-
get_content_data,
3938
)
4039

4140
log = logging.getLogger(__name__)
@@ -78,24 +77,9 @@ async def _check_for_existing_manifest(self, download_tag):
7877

7978
digest = response.headers.get("docker-content-digest")
8079

81-
if (
82-
manifest := await Manifest.objects.prefetch_related("contentartifact_set")
83-
.filter(digest=digest)
84-
.afirst()
85-
):
86-
if raw_text_data := manifest.data:
87-
content_data = json.loads(raw_text_data)
88-
89-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
90-
elif saved_artifact := await manifest._artifacts.afirst():
91-
content_data, raw_bytes_data = await sync_to_async(get_content_data)(saved_artifact)
92-
raw_text_data = raw_bytes_data.decode("utf-8")
93-
# if artifact is not available (due to reclaim space) we will download it again
94-
else:
95-
content_data, raw_text_data, response = await self._download_manifest_data(
96-
response.url
97-
)
98-
# END OF BACKWARD COMPATIBILITY
80+
if manifest := await Manifest.objects.filter(digest=digest).afirst():
81+
raw_text_data = manifest.data
82+
content_data = json.loads(raw_text_data)
9983

10084
else:
10185
content_data, raw_text_data, response = await self._download_manifest_data(response.url)
@@ -316,9 +300,7 @@ async def get_paginated_tag_list(self, rel_link, repo_name):
316300
while True:
317301
link = urljoin(self.remote.url, rel_link)
318302
list_downloader = self.remote.get_downloader(url=link)
319-
# FIXME this can be rolledback after https://github.com/pulp/pulp_container/issues/1288
320-
# tags/list endpoint does not like any unnecessary headers to be sent
321-
await list_downloader.run(extra_data={"repo_name": repo_name, "headers": {}})
303+
await list_downloader.run(extra_data={"repo_name": repo_name})
322304
with open(list_downloader.path) as tags_raw:
323305
tags_dict = json.loads(tags_raw.read())
324306
tag_list.extend(tags_dict["tags"])
@@ -454,31 +436,8 @@ async def create_listed_manifest(self, manifest_data):
454436
455437
"""
456438
digest = manifest_data["digest"]
457-
relative_url = "/v2/{name}/manifests/{digest}".format(
458-
name=self.remote.namespaced_upstream_name, digest=digest
459-
)
460-
manifest_url = urljoin(self.remote.url, relative_url)
461-
462-
if (
463-
manifest := await Manifest.objects.prefetch_related("contentartifact_set")
464-
.filter(digest=digest)
465-
.afirst()
466-
):
467-
if manifest.data:
468-
content_data = json.loads(manifest.data)
469-
# TODO: BACKWARD COMPATIBILITY - remove after fully migrating to artifactless manifest
470-
elif saved_artifact := await manifest._artifacts.afirst():
471-
content_data, _ = await sync_to_async(get_content_data)(saved_artifact)
472-
# if artifact is not available (due to reclaim space) we will download it again
473-
else:
474-
content_data, manifest = await self._download_and_instantiate_manifest(
475-
manifest_url, digest
476-
)
477-
# END OF BACKWARD COMPATIBILITY
478-
else:
479-
content_data, manifest = await self._download_and_instantiate_manifest(
480-
manifest_url, digest
481-
)
439+
if manifest := await Manifest.objects.filter(digest=digest).afirst():
440+
content_data = json.loads(manifest.data)
482441

483442
# in oci-index spec, platform is an optional field
484443
platform = manifest_data.get("platform", None)
@@ -568,9 +527,7 @@ async def create_signatures(self, man_dc, signature_source):
568527
man_dc.content.digest,
569528
)
570529
signatures_downloader = self.remote.get_downloader(url=signatures_url)
571-
# FIXME this can be rolledback after https://github.com/pulp/pulp_container/issues/1288
572-
# signature extensions endpoint does not like any unnecessary headers to be sent
573-
await signatures_downloader.run(extra_data={"headers": {}})
530+
await signatures_downloader.run()
574531
with open(signatures_downloader.path) as signatures_fd:
575532
api_extension_signatures = json.loads(signatures_fd.read())
576533
for signature in api_extension_signatures.get("signatures", []):

0 commit comments

Comments
 (0)