#!/usr/bin/env bash # # Download the latest NixOS installer ISO into iso/. # # Saves the ISO under its real upstream snapshot name (e.g. # nixos-graphical-25.11.10684.8fd9daa3db09-x86_64-linux.iso) so different # channel heads don't clobber each other. Maintains a stable # `latest-nixos--.iso` symlink in iso/ pointing at the newest. set -euo pipefail CHANNEL="nixos-26.05" EDITION="graphical" ARCH="x86_64-linux" DEST_DIR="iso" while (($#)); do case "$1" in --channel) CHANNEL="${2:?missing value}"; shift 2 ;; --edition) EDITION="${2:?missing value}"; shift 2 ;; --arch) ARCH="${2:?missing value}"; shift 2 ;; --dest) DEST_DIR="${2:?missing value}"; shift 2 ;; -h|--help) awk '/^#!/ {next} /^[^#]/ {exit} {sub(/^# ?/, ""); print}' "$0" exit 0 ;; *) echo "[-] unknown arg: $1" >&2; exit 1 ;; esac done BASE="https://channels.nixos.org/${CHANNEL}" LATEST_NAME="latest-nixos-${EDITION}-${ARCH}.iso" mkdir -p "$DEST_DIR" # Fetch the small sha256 file first. Its format is ` ` # so we can derive the actual snapshot filename from it. echo "[+] Fetching ${BASE}/${LATEST_NAME}.sha256" tmp_sum="$(mktemp)" trap 'rm -f "$tmp_sum"' EXIT curl --fail --location --silent --show-error --output "$tmp_sum" \ "${BASE}/${LATEST_NAME}.sha256" \ || { echo "[-] sha256 fetch failed" >&2; exit 2; } real_name="$(awk '{print $2}' "$tmp_sum")" if [[ -z "$real_name" || "$real_name" != *.iso ]]; then echo "[-] couldn't parse filename from upstream sha256:" >&2 cat "$tmp_sum" >&2 exit 2 fi iso="${DEST_DIR}/${real_name}" sum="${DEST_DIR}/${real_name}.sha256" if [[ -f "$iso" && -f "$sum" ]]; then if ( cd "$DEST_DIR" && sha256sum --status -c "${real_name}.sha256" ); then echo "[+] ${iso} already present and verified." ln -sfn "${real_name}" "${DEST_DIR}/${LATEST_NAME}" exit 0 fi echo "[!] ${iso} present but sha256 mismatch — re-downloading from scratch." # curl --continue-at would resume from the corrupt bytes; nuke first. rm -f "$iso" fi mv "$tmp_sum" "$sum" trap - EXIT echo "[+] Downloading ${BASE}/${LATEST_NAME}" echo " -> ${iso}" curl --fail --location --progress-bar --continue-at - \ --output "$iso" "${BASE}/${LATEST_NAME}" \ || { echo "[-] download failed" >&2; exit 2; } echo "[+] Verifying sha256..." ( cd "$DEST_DIR" && sha256sum -c "${real_name}.sha256" ) \ || { echo "[-] sha256 verification failed" >&2; exit 3; } ln -sfn "${real_name}" "${DEST_DIR}/${LATEST_NAME}" echo "[+] ${iso}" echo "[+] symlink: ${DEST_DIR}/${LATEST_NAME} -> ${real_name}"