Extend container image name validator (#4480)

* Extend container image name validator

The current validator allows certain invalid names (e.g. upper
case), but disallows valid cases (such as ttl.sh/myimage).
Improve the container image validator to support more valid
options and at the same time disallow some of the invalid
options.

Note that this is not a complete/perfect validation still. A much
much more sophisticated regex would be necessary to be 100% accurate.
Also we format the string and replace {machine}/{arch} using Python
format strings. In that regard the image format in Supervisor deviates
from the Docker/OCI container image name format.

* Use an actual invalid image name in config validation
This commit is contained in:
Stefan Agner 2023-08-10 18:58:33 +02:00 committed by GitHub
parent c88fd9a7d9
commit 9650fd2ba1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 2 deletions

View File

@ -49,7 +49,9 @@ RE_REGISTRY = re.compile(r"^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$")
# pylint: disable=invalid-name
network_port = vol.All(vol.Coerce(int), vol.Range(min=1, max=65535))
wait_boot = vol.All(vol.Coerce(int), vol.Range(min=1, max=60))
docker_image = vol.Match(r"^([a-zA-Z\-\.:\d{}]+/)*?([\-\w{}]+)/([\-\w{}]+)$")
docker_image = vol.Match(
r"^([a-z0-9][a-z0-9.\-]*(:[0-9]+)?/)*?([a-z0-9{][a-z0-9.\-_{}]*/)*?([a-z0-9{][a-z0-9.\-_{}]*)$"
)
uuid_match = vol.Match(r"^[0-9a-f]{32}$")
sha256 = vol.Match(r"^[0-9a-f]{64}$")
token = vol.Match(r"^[0-9a-f]{32,256}$")

View File

@ -110,7 +110,7 @@ def test_invalid_repository():
"""Validate basic config with invalid repositories."""
config = load_json_fixture("basic-addon-config.json")
config["image"] = "something"
config["image"] = "-invalid-something"
with pytest.raises(vol.Invalid):
vd.SCHEMA_ADDON_CONFIG(config)

View File

@ -16,6 +16,24 @@ DNS_GOOD_V6 = [
"DNS://2606:4700:4700::1001", # cloudflare
]
DNS_BAD = ["hello world", "https://foo.bar", "", "dns://example.com"]
IMAGE_NAME_GOOD = [
"ghcr.io/home-assistant/{machine}-homeassistant",
"ghcr.io/home-assistant/{arch}-homeassistant",
"homeassistant/{arch}-homeassistant",
"doocker.io/homeassistant/{arch}-homeassistant",
"ghcr.io/home-assistant/amd64-homeassistant",
"homeassistant/amd64-homeassistant",
"ttl.sh/homeassistant",
"myreg.local:8080/homeassistant",
]
IMAGE_NAME_BAD = [
"ghcr.io/home-assistant/homeassistant:123",
".ghcr.io/home-assistant/homeassistant",
"HOMEASSISTANT/homeassistant",
"homeassistant/HOMEASSISTANT",
"homeassistant/_homeassistant",
"homeassistant/-homeassistant",
]
async def test_dns_url_v4_good():
@ -72,6 +90,19 @@ def test_dns_server_list_bad_combined():
assert validate.dns_server_list(combined)
def test_image_name_good():
"""Test container image names validator with known-good image names."""
for image_name in IMAGE_NAME_GOOD:
assert validate.docker_image(image_name)
def test_image_name_bad():
"""Test container image names validator with known-bad image names."""
for image_name in IMAGE_NAME_BAD:
with pytest.raises(vol.error.Invalid):
assert validate.docker_image(image_name)
def test_version_complex():
"""Test version simple with good version."""
for version in (