-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate_stable.py
executable file
·83 lines (61 loc) · 2.76 KB
/
update_stable.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python3
import json
import subprocess
import sys
from datetime import datetime
from textwrap import dedent
from typing import List, Tuple
DOCKER_SYNTAX = "docker/dockerfile:1.14"
DOCKER_FILES_TO_IMAGES: list[tuple[str, str]] = [
("docker/rust-stable.dockerfile", "docker.gosh.sh/rust"),
("docker/debian-stable.dockerfile", "docker.gosh.sh/debian"),
("docker/debian-stable-slim.dockerfile", "docker.gosh.sh/debian:slim"),
]
def run_command(cmd: List[str]) -> Tuple[str, str, int]:
"""Run a command and return stdout, stderr, and return code."""
process = subprocess.run(cmd, capture_output=True, text=True)
return process.stdout.strip(), process.stderr.strip(), process.returncode
def get_digest_for_platform(manifest: str, architecture: str) -> str:
"""Gets the digest for a given platform from a docker manifest."""
stdout, stderr, rc = run_command(["docker", "manifest", "inspect", manifest])
if rc != 0:
raise RuntimeError(f"Failed to inspect manifest {manifest}: {stderr}")
try:
manifest_data = json.loads(stdout)
for manifest_item in manifest_data.get("manifests", []):
if manifest_item.get("platform", {}).get("architecture") == architecture:
return manifest_item.get("digest")
except json.JSONDecodeError:
raise ValueError("Failed to parse manifest data")
raise ValueError(f"Could not get digest for {manifest} {architecture}")
def update_dockerfile(dockerfile_path: str, manifest_base: str) -> None:
"""Updates a dockerfile with the latest digests for amd64 and arm64 architectures."""
manifest_without_tag = manifest_base.split(":")[0]
amd64_digest = get_digest_for_platform(manifest_base, "amd64")
arm64_digest = get_digest_for_platform(manifest_base, "arm64")
print(dedent(f"""\
Current digests for {manifest_base} are
amd64: {amd64_digest}
arm64: {arm64_digest}"""))
dockerfile_content = f"""# syntax={DOCKER_SYNTAX}
#
# This file is automatically generated by `./update_stable.py` at {datetime.now()}
# Manual modifications will be overwritten
#
FROM --platform=linux/amd64 {manifest_without_tag}@{amd64_digest} AS base-amd64
FROM --platform=linux/arm64 {manifest_without_tag}@{arm64_digest} AS base-arm64
FROM base-${{TARGETARCH}}
"""
with open(dockerfile_path, "w") as f:
f.write(dockerfile_content)
print(f"{dockerfile_path} updated successfully")
def main():
for docker_file, image_base in DOCKER_FILES_TO_IMAGES:
print(f"Updating {docker_file} with {image_base}")
try:
update_dockerfile(docker_file, image_base)
except Exception as e:
print(f"Failed to update {docker_file}: {e}")
sys.exit(1)
if __name__ == "__main__":
main()