mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-15 19:42:06 +00:00
Fix parse_repository_tag to handle images with both tag and digest
The parse_repository_tag() function was incorrectly parsing Docker image
references that contained both a tag and a digest (e.g., nginx:1.0@sha256:abc).
Previously, when splitting by '@' first, the tag would be included in the
repository name, resulting in incorrect parsing:
- Input: "nginx:1.0@sha256:abc123"
- Old output: ("nginx:1.0", "sha256:abc123")
- Expected: ("nginx", "1.0@sha256:abc123")
The fix now:
1. Checks for digest (@) separator first
2. Examines the part before the digest for a tag (:) separator
3. Combines tag and digest as "tag@digest" when both are present
Added test cases:
- test_index_image_tag_and_sha
- test_index_user_image_tag_and_sha
- test_private_reg_image_tag_and_sha
This commit is contained in:
parent
a985e05482
commit
9e666af1ab
@ -240,9 +240,23 @@ def convert_service_networks(
|
|||||||
|
|
||||||
|
|
||||||
def parse_repository_tag(repo_name: str) -> tuple[str, str | None]:
|
def parse_repository_tag(repo_name: str) -> tuple[str, str | None]:
|
||||||
|
# Check for digest (@ separator) first
|
||||||
parts = repo_name.rsplit("@", 1)
|
parts = repo_name.rsplit("@", 1)
|
||||||
if len(parts) == 2:
|
if len(parts) == 2:
|
||||||
return tuple(parts) # type: ignore
|
# We have a digest, but there might also be a tag before it
|
||||||
|
repo_and_tag = parts[0]
|
||||||
|
digest = parts[1]
|
||||||
|
|
||||||
|
# Check if there's a tag in the part before the digest
|
||||||
|
tag_parts = repo_and_tag.rsplit(":", 1)
|
||||||
|
if len(tag_parts) == 2 and "/" not in tag_parts[1]:
|
||||||
|
# We have both tag and digest: return repo and "tag@digest"
|
||||||
|
return tag_parts[0], f"{tag_parts[1]}@{digest}"
|
||||||
|
else:
|
||||||
|
# Only digest, no tag: return repo and digest
|
||||||
|
return repo_and_tag, digest
|
||||||
|
|
||||||
|
# No digest, check for tag only
|
||||||
parts = repo_name.rsplit(":", 1)
|
parts = repo_name.rsplit(":", 1)
|
||||||
if len(parts) == 2 and "/" not in parts[1]:
|
if len(parts) == 2 and "/" not in parts[1]:
|
||||||
return tuple(parts) # type: ignore
|
return tuple(parts) # type: ignore
|
||||||
|
|||||||
@ -359,6 +359,24 @@ class ParseRepositoryTagTest(unittest.TestCase):
|
|||||||
f"sha256:{self.sha}",
|
f"sha256:{self.sha}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_index_image_tag_and_sha(self) -> None:
|
||||||
|
assert parse_repository_tag(f"root:tag@sha256:{self.sha}") == (
|
||||||
|
"root",
|
||||||
|
f"tag@sha256:{self.sha}",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_index_user_image_tag_and_sha(self) -> None:
|
||||||
|
assert parse_repository_tag(f"user/repo:tag@sha256:{self.sha}") == (
|
||||||
|
"user/repo",
|
||||||
|
f"tag@sha256:{self.sha}",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_private_reg_image_tag_and_sha(self) -> None:
|
||||||
|
assert parse_repository_tag(f"url:5000/repo:tag@sha256:{self.sha}") == (
|
||||||
|
"url:5000/repo",
|
||||||
|
f"tag@sha256:{self.sha}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ParseDeviceTest(unittest.TestCase):
|
class ParseDeviceTest(unittest.TestCase):
|
||||||
def test_dict(self) -> None:
|
def test_dict(self) -> None:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user