diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/oci/image.py | 13 | ||||
-rw-r--r-- | lib/spack/spack/test/oci/image.py | 4 |
2 files changed, 14 insertions, 3 deletions
diff --git a/lib/spack/spack/oci/image.py b/lib/spack/spack/oci/image.py index 1954bf013d..b61591b7be 100644 --- a/lib/spack/spack/oci/image.py +++ b/lib/spack/spack/oci/image.py @@ -9,8 +9,10 @@ from typing import Optional, Union import spack.spec -# all the building blocks -alphanumeric = r"[a-z0-9]+" +# notice: Docker is more strict (no uppercase allowed). We parse image names *with* uppercase +# and normalize, so: example.com/Organization/Name -> example.com/organization/name. Tags are +# case sensitive though. +alphanumeric_with_uppercase = r"[a-zA-Z0-9]+" separator = r"(?:[._]|__|[-]+)" localhost = r"localhost" domainNameComponent = r"(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])" @@ -25,7 +27,7 @@ host = rf"(?:{domainName}|{ipv6address})" domainAndPort = rf"{host}{optionalPort}" # image name -pathComponent = rf"{alphanumeric}(?:{separator}{alphanumeric})*" +pathComponent = rf"{alphanumeric_with_uppercase}(?:{separator}{alphanumeric_with_uppercase})*" remoteName = rf"{pathComponent}(?:\/{pathComponent})*" namePat = rf"(?:{domainAndPort}\/)?{remoteName}" @@ -130,6 +132,11 @@ class ImageReference: name = f"{domain}/{name}" domain = "index.docker.io" + # Lowercase the image name. This is enforced by Docker, although the OCI spec isn't clear? + # We do this anyways, cause for example in Github Actions the <organization>/<repository> + # part can have uppercase, and may be interpolated when specifying the relevant OCI image. + name = name.lower() + if not tag: tag = "latest" diff --git a/lib/spack/spack/test/oci/image.py b/lib/spack/spack/test/oci/image.py index 17899d1f43..b074cc679a 100644 --- a/lib/spack/spack/test/oci/image.py +++ b/lib/spack/spack/test/oci/image.py @@ -34,6 +34,10 @@ from spack.oci.image import Digest, ImageReference, default_tag, tag ("myname:1234/myimage:abc", ("myname:1234", "myimage", "abc", None)), ("localhost/myimage:abc", ("localhost", "myimage", "abc", None)), ("localhost:1234/myimage:abc", ("localhost:1234", "myimage", "abc", None)), + ( + "example.com/UPPERCASE/lowercase:AbC", + ("example.com", "uppercase/lowercase", "AbC", None), + ), ], ) def test_name_parsing(image_ref, expected): |