Files
monky-deployd/tests/test_registry_auth.py
T
mdella b25c6b3b8b feat: pull private images without a hand docker login; surface the pull error
Design merged first: monky-design-docs !225 (doc 24 §4a). Pairs with monky-tenancy!40, which
copies the estate-wide read-only Harbor robot into each environment's own prefix and marks the
manifest entry `use: registry-auth`.

- That entry is not an env var (it would otherwise land in .env and therefore in every container's
  environment). The agent parses it — JSON, or `username:password` with the new `registry_host` —
  and writes `<state_dir>/docker/config.json` 0600 in a directory it owns, with an explicit
  DOCKER_CONFIG pointing the docker CLI at it. The unit runs as monky-deployd, so a `docker login`
  by a human or by root is invisible to the agent: that is what made env-dev-01 look like it had no
  credential at all after the operator had just logged in.
- `compose pull` failures now carry the registry's own message ("no basic auth credentials",
  "manifest unknown", DNS) into the journal and the report instead of `rc=1`.
- Tests: both credential shapes, the refusals, 0600/0700 modes, idempotent rewrite, and that the
  runner never silently falls back to a human's $HOME.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLB7jieMNRkTsJ2epr4Ds1
2026-09-08 15:45:22 +00:00

54 lines
2.3 KiB
Python

"""The registry credential (doc 24 §4a): parsed from either seeded shape, written to a Docker
config the AGENT owns, never an env var, never logged."""
from __future__ import annotations
import base64
import json
import pytest
from monky_deployd import registry as registrymod
def test_parses_json_and_user_colon_password():
a = registrymod.parse(
json.dumps({"registry": "harbor.tikali.net", "username": "robot$pull", "password": "p4ss"}),
default_registry="ignored.example",
)
assert (a.registry, a.username, a.password) == ("harbor.tikali.net", "robot$pull", "p4ss")
b = registrymod.parse("robot$pull:p4ss", default_registry="harbor.tikali.net")
assert (b.registry, b.username, b.password) == ("harbor.tikali.net", "robot$pull", "p4ss")
# a password containing a colon survives (partition on the FIRST one)
c = registrymod.parse("robot$pull:p4:ss", default_registry="h")
assert c.password == "p4:ss"
@pytest.mark.parametrize("bad", ["", " ", "no-colon-here", '{"username": "u"}', "{not json"])
def test_refuses_what_it_cannot_use(bad):
with pytest.raises(registrymod.RegistryAuthError):
registrymod.parse(bad, default_registry="harbor.tikali.net")
def test_docker_config_is_written_0600_in_a_directory_the_agent_owns(tmp_path):
auth = registrymod.parse("robot$pull:p4ss", default_registry="harbor.tikali.net")
target = registrymod.write_docker_config(tmp_path / "docker", auth)
assert target.exists()
assert oct(target.stat().st_mode)[-3:] == "600"
assert oct(target.parent.stat().st_mode)[-3:] == "700"
cfg = json.loads(target.read_text())
token = cfg["auths"]["harbor.tikali.net"]["auth"]
assert base64.b64decode(token).decode() == "robot$pull:p4ss"
# rewriting is idempotent (the agent does it every tick)
registrymod.write_docker_config(tmp_path / "docker", auth)
assert json.loads(target.read_text()) == cfg
def test_docker_runner_points_the_cli_at_that_directory():
from monky_deployd.compose import Docker
d = Docker("docker", docker_config="/var/lib/monky-deployd/docker")
assert d._env()["DOCKER_CONFIG"] == "/var/lib/monky-deployd/docker"
# unset when no directory is configured — never silently fall back to a human's $HOME
assert "DOCKER_CONFIG" not in Docker("docker")._env()