fix(svc-opt-ssd-hdd): recognise database images behind registry, namespace and custom builds

is_database() compared the whole repository part of the image reference
against postgres, mariadb, redis, memcached and mongo. Every reference
with a registry or namespace prefix, every derivative image and every
locally built `<engine>_custom` image therefore counted as application
data and went to the mass storage. On a local stack the central
databases report `postgres_custom:18` and `openldap_custom:13.7-slim`,
both classified False and moved to the HDD.

The check now takes the last path component of the reference, drops
digest, tag and a `_custom` suffix, and compares it against the engines
the svc-db-* providers and the app-local databases run: elasticsearch,
mariadb, memcached, mongo, mysql, openldap, opensearch, postgis,
postgres, qdrant, rabbitmq, redis, typesense, valkey.

Volumes the script already symlinked stay where they are; a database
volume misplaced on the HDD has to be moved back by hand.

Fixes #1163

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-22 21:02:06 +02:00
1 parent b40c05dbbf
commit 8567cb6992
2 files changed
+53 -3

No files matched your search

+27 -3
View File
@@ -38,10 +38,34 @@ def start_containers(containers):
run_command(f"container start {container_list}")
DATABASE_IMAGES = {
"elasticsearch",
"mariadb",
"memcached",
"mongo",
"mysql",
"openldap",
"opensearch",
"postgis",
"postgres",
"qdrant",
"rabbitmq",
"redis",
"typesense",
"valkey",
}
def is_database(image):
databases = {"postgres", "mariadb", "redis", "memcached", "mongo"}
prefix = image.split(":")[0]
return prefix in databases
"""Tell whether an image reference names a database engine.
Args:
image: reference as the container's `.Config.Image` reports it, with
optional registry, namespace, tag and digest; a locally built
`<engine>_custom` image counts as its engine.
"""
name = image.rsplit("/", 1)[-1].split("@")[0].split(":")[0]
return name.removesuffix("_custom") in DATABASE_IMAGES
def is_symbolic_link(file_path):
@@ -54,5 +54,31 @@ class TestHealthCheckLogic(unittest.TestCase):
)
class TestIsDatabase(unittest.TestCase):
def test_classification(self):
test_cases = [
("postgres_custom:18", True),
("openldap_custom:13.7-slim", True),
("mariadb_custom:11.8", True),
("postgis/postgis:17-3.5", True),
("valkey/valkey:8", True),
("docker.io/library/postgres:18", True),
("ghcr.io/infinito-nexus/mirror/docker.io/library/postgres:18", True),
("registry.infinito.test:5000/openldap_custom:13.7-slim", True),
("postgres@sha256:" + "0" * 64, True),
("docker.elastic.co/elasticsearch/elasticsearch:9.1.0", True),
("bigbluebutton_custom:v3.0.39", False),
("registry.infinito.test:5000/nextcloud:31", False),
("ghcr.io/ldapaccountmanager/lam:9", False),
("phpldapadmin/phpldapadmin:2", False),
]
for image_name, expected in test_cases:
self.assertEqual(
storage_optimizer.is_database(image_name),
expected,
f"Image {image_name} expected {expected}",
)
if __name__ == "__main__":
unittest.main()