Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docker/Dockerfile.controller.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Controller image context allowlist.
**

!pyproject.toml
!setup.py
!requirements.txt
!README.md
!LICENSE

!i[d]rac_ctl/
!i[d]rac_ctl/**
!redfish_ctl/
!redfish_ctl/**
!k8s/
!k8s/controller/
!k8s/controller/**

**/__pycache__/
**/*.py[cod]
**/*.egg-info/
8 changes: 8 additions & 0 deletions docker/Dockerfile.mock-bmc.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Mock-BMC image context allowlist.
**

!k8s/
!k8s/sandbox/
!k8s/sandbox/mock_bmc_server.py
!tests/
!tests/supermicro_gb300_corpus.tar.gz
59 changes: 59 additions & 0 deletions tests/gates/test_dockerfile_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
DOCKERFILE = REPO_ROOT / "docker" / "Dockerfile"
DOCKER_README = REPO_ROOT / "docker" / "README.md"
README = REPO_ROOT / "README.md"
RELEASE_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "release.yml"


def _effective_ignore_rules(path: Path) -> list[str]:
"""Return non-comment Docker ignore rules.

:param path: Docker ignore file to parse.
:return: Ordered non-empty rules with comments removed.
"""
return [
line.strip()
for line in path.read_text(encoding="utf-8").splitlines()
if line.strip() and not line.lstrip().startswith("#")
]


def test_production_dockerfile_installs_local_otlp_wheel_as_non_root() -> None:
Expand Down Expand Up @@ -48,3 +62,48 @@ def test_docker_docs_link_the_production_image_usage() -> None:
assert "exporter --output otlp" in docker_readme
assert "credentials" in docker_readme.lower()
assert "[Docker](docker/README.md)" in readme


def test_published_auxiliary_images_use_minimal_context_allowlists() -> None:
"""Published auxiliary images receive only the files copied by their Dockerfiles."""
expected_rules = {
"Dockerfile.controller": [
"**",
"!pyproject.toml",
"!setup.py",
"!requirements.txt",
"!README.md",
"!LICENSE",
"!i[d]rac_ctl/",
"!i[d]rac_ctl/**",
"!redfish_ctl/",
"!redfish_ctl/**",
"!k8s/",
"!k8s/controller/",
"!k8s/controller/**",
"**/__pycache__/",
"**/*.py[cod]",
"**/*.egg-info/",
],
"Dockerfile.mock-bmc": [
"**",
"!k8s/",
"!k8s/sandbox/",
"!k8s/sandbox/mock_bmc_server.py",
"!tests/",
"!tests/supermicro_gb300_corpus.tar.gz",
],
}

for dockerfile, rules in expected_rules.items():
ignore_file = REPO_ROOT / "docker" / f"{dockerfile}.dockerignore"
assert _effective_ignore_rules(ignore_file) == rules


def test_release_auxiliary_images_use_the_guarded_contexts() -> None:
"""Release builds keep the Dockerfile names bound to their matching allowlists."""
release_workflow = RELEASE_WORKFLOW.read_text(encoding="utf-8")

for dockerfile in ("Dockerfile.controller", "Dockerfile.mock-bmc"):
assert f"file: docker/{dockerfile}" in release_workflow
assert (REPO_ROOT / "docker" / f"{dockerfile}.dockerignore").is_file()
Loading