Skip to content

Commit b8bcba5

Browse files
authored
feat: use cargo install for Agave 4.1+ docker images (#339)
## Summary - Agave 4.1.x uses `cargo install cargo-build-sbf` instead of the full CLI - Older Agave versions keep the existing install path - New release trains need an entry in `AGAVE_CARGO_INSTALL_MAP` or the script fails ## Why Anza is splitting build tooling from the CLI. Verifiable builds only need `cargo build-sbf`, and 4.1.x should use platform-tools v1.54.
1 parent 1a79e63 commit b8bcba5

1 file changed

Lines changed: 77 additions & 12 deletions

File tree

generate_dockerfiles.py

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@
2929
SOLANA_VERSION_PLACEHOLDER = "$SOLANA_VERSION"
3030
AGAVE_VERSION_PLACEHOLDER = "$AGAVE_VERSION"
3131
INSTALL_SHA256_PLACEHOLDER = "$INSTALL_SHA256"
32+
CARGO_BUILD_SBF_VERSION_PLACEHOLDER = "$CARGO_BUILD_SBF_VERSION"
33+
PLATFORM_TOOLS_ARGS_PLACEHOLDER = "$PLATFORM_TOOLS_ARGS"
34+
35+
# Agave trains that install cargo-build-sbf from crates.io (not the full CLI).
36+
# One map entry per minor line, bump cargo_build_sbf_version when the train moves to a new crate.
37+
AGAVE_CARGO_INSTALL_MAP = {
38+
(4, 1): {
39+
"cargo_build_sbf_version": "4.1.0",
40+
"platform_tools_args": "--tools-version v1.54",
41+
},
42+
}
43+
44+
missing_cargo_install_trains = set()
3245

3346
_INSTALL_SHA256_CACHE = {}
3447

@@ -89,14 +102,14 @@ def with_pinned_installer(url: str, install_path: str = "/tmp/solana_install.sh"
89102
CMD /bin/bash
90103
"""
91104

92-
# Dockerfile template for Agave
105+
# Dockerfile template for Agave (CLI install)
93106
base_dockerfile_agave = f"""
94107
FROM --platform=linux/amd64 rust@{RUST_VERSION_PLACEHOLDER}
95108
96109
RUN apt-get update && apt-get install -qy git gnutls-bin curl ca-certificates
97110
{with_pinned_installer(f"https://release.anza.xyz/{AGAVE_VERSION_PLACEHOLDER}/install")}
98111
ENV PATH="/root/.local/share/solana/install/active_release/bin:$PATH"
99-
# Call cargo build-sbf to trigger installation of associated platform tools
112+
# Call cargo build-sbf to trigger installation of platform tools
100113
RUN cargo init temp --edition 2021 && \\
101114
cd temp && \\
102115
cargo build-sbf && \\
@@ -106,6 +119,23 @@ def with_pinned_installer(url: str, install_path: str = "/tmp/solana_install.sh"
106119
CMD /bin/bash
107120
"""
108121

122+
# Dockerfile template for Agave (cargo install path)
123+
base_dockerfile_agave_cargo_install = f"""
124+
FROM --platform=linux/amd64 rust@{RUST_VERSION_PLACEHOLDER}
125+
126+
LABEL agave.version="{AGAVE_VERSION_PLACEHOLDER}"
127+
RUN apt-get update && apt-get install -qy git gnutls-bin curl ca-certificates
128+
RUN cargo install cargo-build-sbf --version {CARGO_BUILD_SBF_VERSION_PLACEHOLDER} --locked
129+
# Call cargo build-sbf to trigger installation of platform tools
130+
RUN cargo init temp --edition 2021 && \\
131+
cd temp && \\
132+
cargo build-sbf{PLATFORM_TOOLS_ARGS_PLACEHOLDER} && \\
133+
rm -rf temp
134+
WORKDIR /build
135+
136+
CMD /bin/bash
137+
"""
138+
109139
# Skipping these because the are not valid releases or where yanked or not released for mainnet
110140
SKIPPED_VERSIONS = {
111141
"v1.15", "v1.14.0", "v1.10.0", "v1.10.16", "v1.10.18",
@@ -158,12 +188,27 @@ def get_release_info(version_tag):
158188
}
159189
#Everything after we need to get from anza
160190
elif (major == 1 and minor == 18 and patch >= 24) or major >= 2:
161-
return {
162-
"base_dockerfile_text": base_dockerfile_agave,
191+
agave_info = {
163192
"version_placeholder": AGAVE_VERSION_PLACEHOLDER,
164193
"url": f"https://raw.githubusercontent.com/anza-xyz/agave/{version_tag}/rust-toolchain.toml",
165-
"install_url": f"https://release.anza.xyz/{version_tag}/install"
194+
"install_url": f"https://release.anza.xyz/{version_tag}/install",
166195
}
196+
train = (major, minor)
197+
if train in AGAVE_CARGO_INSTALL_MAP:
198+
cfg = AGAVE_CARGO_INSTALL_MAP[train]
199+
agave_info["base_dockerfile_text"] = base_dockerfile_agave_cargo_install
200+
agave_info["cargo_build_sbf_version"] = cfg["cargo_build_sbf_version"]
201+
agave_info["platform_tools_args"] = cfg.get("platform_tools_args", "")
202+
elif train >= (4, 1):
203+
missing_cargo_install_trains.add(train)
204+
print(
205+
f"ERROR: {version_tag} needs an AGAVE_CARGO_INSTALL_MAP entry for Agave {major}.{minor}.x",
206+
flush=True,
207+
)
208+
return None
209+
else:
210+
agave_info["base_dockerfile_text"] = base_dockerfile_agave
211+
return agave_info
167212

168213
return None
169214

@@ -273,20 +318,34 @@ def process_releases(releases):
273318
RUST_VERSION_PLACEHOLDER, RUST_DOCKER_IMAGESHA_MAP[rust_version]
274319
).lstrip("\n")
275320

321+
if "cargo_build_sbf_version" in release_info:
322+
platform_tools_args = release_info.get("platform_tools_args", "").strip()
323+
if platform_tools_args:
324+
platform_tools_args = f" {platform_tools_args}"
325+
dockerfile = dockerfile.replace(
326+
CARGO_BUILD_SBF_VERSION_PLACEHOLDER,
327+
release_info["cargo_build_sbf_version"],
328+
).replace(
329+
PLATFORM_TOOLS_ARGS_PLACEHOLDER,
330+
platform_tools_args,
331+
)
332+
276333
if os.path.exists(path):
277334
if not args.update_existing:
278335
# Only generate Dockerfiles for new releases
279336
continue
280337

281-
sha = fetch_install_script_sha256(release_info["install_url"])
282-
if not sha:
283-
print(f"Warning: failed to fetch installer checksum for {release}; leaving {path} unchanged")
284-
continue
338+
# Only templates with the install script need a checksum
339+
if INSTALL_SHA256_PLACEHOLDER in dockerfile:
340+
sha = fetch_install_script_sha256(release_info["install_url"])
341+
if not sha:
342+
print(f"Warning: failed to fetch installer checksum for {release}; leaving {path} unchanged")
343+
continue
285344

286-
dockerfile = dockerfile.replace(INSTALL_SHA256_PLACEHOLDER, sha)
345+
dockerfile = dockerfile.replace(INSTALL_SHA256_PLACEHOLDER, sha)
287346

288-
if INSTALL_SHA256_PLACEHOLDER in dockerfile:
289-
raise Exception(f"Checksum not injected for {release}")
347+
if INSTALL_SHA256_PLACEHOLDER in dockerfile:
348+
raise Exception(f"Checksum not injected for {release}")
290349

291350
stripped = release.strip("v")
292351
if os.path.exists(path):
@@ -315,6 +374,12 @@ def process_releases(releases):
315374
process_releases(solana_releases)
316375
process_releases(agave_releases)
317376

377+
if missing_cargo_install_trains:
378+
trains = ", ".join(f"{m}.{n}.x" for m, n in sorted(missing_cargo_install_trains))
379+
raise Exception(
380+
f"Missing AGAVE_CARGO_INSTALL_MAP entries for Agave release trains: {trains}"
381+
)
382+
318383
print(RUST_DOCKER_IMAGESHA_MAP)
319384

320385

0 commit comments

Comments
 (0)