From d80b469e5745bf80ca787748c4181b99b5a3ff37 Mon Sep 17 00:00:00 2001 From: eding Date: Sun, 19 Jul 2026 23:10:31 +0200 Subject: [PATCH] fix: bake talos iso on proxmox host --- terraform/scripts/stage_talos_image.py | 79 +++++++++----------------- 1 file changed, 26 insertions(+), 53 deletions(-) diff --git a/terraform/scripts/stage_talos_image.py b/terraform/scripts/stage_talos_image.py index 1e01815..462a2eb 100644 --- a/terraform/scripts/stage_talos_image.py +++ b/terraform/scripts/stage_talos_image.py @@ -7,7 +7,6 @@ import shutil import ssl import subprocess import sys -import tempfile import time import urllib.error import urllib.parse @@ -90,65 +89,39 @@ def wait_for_storage_content(base_url, token, node, storage, filename): raise RuntimeError(f"timed out waiting for {filename} to appear in {node}/{storage}") -def detect_proxmox_iso_dir(storage): - candidates = [ - Path("/var/lib/vz/template/iso"), - Path("C:/var/lib/vz/template/iso"), - ] - for candidate in candidates: - if candidate.exists(): - return candidate - raise RuntimeError(f"unable to find ISO directory for storage '{storage}'") +def run_ssh(node, script): + ssh = shutil.which("ssh") + if ssh is None: + raise RuntimeError("ssh is required to customize Talos ISO on the Proxmox host") + subprocess.run([ssh, f"root@{node}", script], check=True) def build_custom_iso(base_url, token, node, storage, source_filename, output_filename, network_config_path): - iso_dir = detect_proxmox_iso_dir(storage) - storage_path = iso_dir / source_filename - output_path = iso_dir / output_filename network_config = Path(network_config_path).read_text(encoding="utf-8").strip() installer_meta = base64.b64encode(gzip.compress(f"0xa={network_config}".encode("utf-8"), compresslevel=9)).decode("ascii") - xorriso = shutil.which("xorriso") - if xorriso is None: - raise RuntimeError("xorriso is required to build Talos ISO with embedded META") - - with tempfile.TemporaryDirectory() as temp_dir: - temp_path = Path(temp_dir) - extract_dir = temp_path / "extract" - extract_dir.mkdir() - output_tmp = temp_path / output_filename - - subprocess.run([xorriso, "-osirrox", "on", "-indev", str(storage_path), "-extract", "/", str(extract_dir)], check=True) - - isolinux_cfg = extract_dir / "isolinux" / "isolinux.cfg" - grub_cfg = extract_dir / "boot" / "grub" / "grub.cfg" - append = f" talos.environment=INSTALLER_META_BASE64={installer_meta}" - for cfg in (isolinux_cfg, grub_cfg): - if cfg.exists(): - text = cfg.read_text(encoding="utf-8") - text = text.replace("---", f"{append} ---", 1) - cfg.write_text(text, encoding="utf-8") - - subprocess.run([ - xorriso, - "-as", "mkisofs", - "-o", str(output_tmp), - "-isohybrid-mbr", str(extract_dir / "isolinux" / "isohdpfx.bin"), - "-c", "isolinux/boot.cat", - "-b", "isolinux/isolinux.bin", - "-no-emul-boot", - "-boot-load-size", "4", - "-boot-info-table", - "-eltorito-alt-boot", - "-e", "EFI/BOOT/BOOTX64.EFI", - "-no-emul-boot", - "-isohybrid-gpt-basdat", - "-V", "TALOS", - str(extract_dir), - ], check=True) - - shutil.copyfile(output_tmp, output_path) + script = ( + "set -eu; " + f"SRC='/var/lib/vz/template/iso/{source_filename}'; " + f"OUT='/var/lib/vz/template/iso/{output_filename}'; " + "TMPDIR=$(mktemp -d); trap 'rm -rf \"$TMPDIR\"' EXIT; " + "xorriso -osirrox on -indev \"$SRC\" -extract / \"$TMPDIR/extract\" >/dev/null 2>&1; " + "for CFG in \"$TMPDIR/extract/isolinux/isolinux.cfg\" \"$TMPDIR/extract/boot/grub/grub.cfg\"; do " + " if [ -f \"$CFG\" ]; then " + f" sed -i '0,/---/s// talos.environment=INSTALLER_META_BASE64={installer_meta} ---/' \"$CFG\"; " + " fi; " + "done; " + "xorriso -as mkisofs " + "-o \"$OUT\" " + "-isohybrid-mbr \"$TMPDIR/extract/isolinux/isohdpfx.bin\" " + "-c isolinux/boot.cat " + "-b isolinux/isolinux.bin " + "-no-emul-boot -boot-load-size 4 -boot-info-table " + "-eltorito-alt-boot -e EFI/BOOT/BOOTX64.EFI -no-emul-boot -isohybrid-gpt-basdat " + "-V TALOS \"$TMPDIR/extract\" >/dev/null 2>&1" + ) + run_ssh(node, script) def main():