fix: build talos iso without docker
This commit is contained in:
parent
d61225a9d3
commit
aecbf392bc
|
|
@ -4,10 +4,10 @@ import gzip
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import ssl
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import ssl
|
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
@ -79,41 +79,66 @@ def wait_for_task(base_url, token, node, upid):
|
||||||
raise RuntimeError("timed out waiting for ISO download task to finish")
|
raise RuntimeError("timed out waiting for ISO download task to finish")
|
||||||
|
|
||||||
|
|
||||||
|
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 build_custom_iso(base_url, token, node, storage, source_filename, output_filename, network_config_path):
|
def build_custom_iso(base_url, token, node, storage, source_filename, output_filename, network_config_path):
|
||||||
storage_path = f"/var/lib/vz/template/iso/{source_filename}"
|
iso_dir = detect_proxmox_iso_dir(storage)
|
||||||
output_path = f"/var/lib/vz/template/iso/{output_filename}"
|
storage_path = iso_dir / source_filename
|
||||||
|
output_path = iso_dir / output_filename
|
||||||
network_config = Path(network_config_path).read_text(encoding="utf-8").strip()
|
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")
|
installer_meta = base64.b64encode(gzip.compress(f"0xa={network_config}".encode("utf-8"), compresslevel=9)).decode("ascii")
|
||||||
|
|
||||||
if shutil.which("docker") is None:
|
xorriso = shutil.which("xorriso")
|
||||||
raise RuntimeError("docker is required to build Talos ISO with embedded META")
|
if xorriso is None:
|
||||||
|
raise RuntimeError("xorriso is required to build Talos ISO with embedded META")
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as temp_dir:
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
temp_path = Path(temp_dir)
|
temp_path = Path(temp_dir)
|
||||||
script_path = temp_path / "build.sh"
|
extract_dir = temp_path / "extract"
|
||||||
script_path.write_text(
|
extract_dir.mkdir()
|
||||||
"#!/bin/sh\n"
|
output_tmp = temp_path / output_filename
|
||||||
"set -eu\n"
|
|
||||||
"apk add --no-cache xorriso >/dev/null\n"
|
subprocess.run([xorriso, "-osirrox", "on", "-indev", str(storage_path), "-extract", "/", str(extract_dir)], check=True)
|
||||||
"cp /input/source.iso /work/source.iso\n"
|
|
||||||
"xorriso -indev /work/source.iso -outdev /output/result.iso -boot_image any replay \\\n"
|
isolinux_cfg = extract_dir / "isolinux" / "isolinux.cfg"
|
||||||
f" -append_partition 2 0x0 /dev/null \\\n"
|
grub_cfg = extract_dir / "boot" / "grub" / "grub.cfg"
|
||||||
f" -boot_image any keep \\\n"
|
append = f" talos.environment=INSTALLER_META_BASE64={installer_meta}"
|
||||||
f" -map /input/cmdline /cmdline\n",
|
for cfg in (isolinux_cfg, grub_cfg):
|
||||||
encoding="utf-8",
|
if cfg.exists():
|
||||||
)
|
text = cfg.read_text(encoding="utf-8")
|
||||||
cmdline_path = temp_path / "cmdline"
|
text = text.replace("---", f"{append} ---", 1)
|
||||||
cmdline_path.write_text(f"talos.environment=INSTALLER_META_BASE64={installer_meta}\n", encoding="utf-8")
|
cfg.write_text(text, encoding="utf-8")
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
"docker", "run", "--rm",
|
xorriso,
|
||||||
"-v", f"{script_path}:/input/build.sh:ro",
|
"-as", "mkisofs",
|
||||||
"-v", f"{cmdline_path}:/input/cmdline:ro",
|
"-o", str(output_tmp),
|
||||||
"-v", f"{Path(storage_path).resolve()}:/input/source.iso:ro",
|
"-isohybrid-mbr", str(extract_dir / "isolinux" / "isohdpfx.bin"),
|
||||||
"-v", f"{temp_path}:/work",
|
"-c", "isolinux/boot.cat",
|
||||||
"-v", f"{Path(output_path).resolve().parent}:/output",
|
"-b", "isolinux/isolinux.bin",
|
||||||
"alpine:3.20", "sh", "/input/build.sh",
|
"-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)
|
], check=True)
|
||||||
|
|
||||||
|
shutil.copyfile(output_tmp, output_path)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue