# UltraCloud Bootstrap ISO # Minimal ISO with DHCP + Phone Home to Deployer + Auto-Install # For VM cluster deployment: boots, phones home, partitions disk, installs NixOS { config, lib, pkgs, modulesPath, ultracloudBaremetalFormatMountPaths ? { }, ultracloudBaremetalSystemPaths ? { }, ... }: { imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" ]; # ISO metadata image.fileName = "ultracloud-bootstrap.iso"; isoImage = { makeEfiBootable = true; makeUsbBootable = true; }; # Embed the repository into the ISO for offline flake install isoImage.contents = [ { source = ../../.; target = "/opt/ultracloud-src"; } ]; # Minimal network: DHCP on all interfaces networking.useNetworkd = true; networking.networkmanager.enable = lib.mkForce false; systemd.network.networks."10-dhcp" = { matchConfig.Name = "*"; DHCP = "yes"; }; # Phone Home service — fetches secrets from Deployer systemd.services.ultracloud-bootstrap = { description = "UltraCloud Bootstrap via Phone Home"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = '' set -euo pipefail cmdline_value() { local key="$1" local arg for arg in $(cat /proc/cmdline); do case "$arg" in "$key"=*) echo "''${arg#*=}" return 0 ;; esac done return 1 } dmi_value() { local path="$1" if [ -r "$path" ]; then tr -d '\n' <"$path" 2>/dev/null || true fi } resolve_deployer_url() { local explicit_url="''${DEPLOYER_URL:-}" if [ -z "$explicit_url" ]; then explicit_url="$(cmdline_value ultracloud.deployer_url || true)" fi if [ -n "$explicit_url" ]; then echo "$explicit_url" return 0 fi if ${pkgs.curl}/bin/curl -fsS --connect-timeout 2 --max-time 5 \ http://10.0.2.2:8088/health >/dev/null 2>&1; then echo "http://10.0.2.2:8088" return 0 fi echo "http://192.168.100.1:8080" } mkdir -p /etc/ultracloud # Discover Deployer via environment, kernel cmdline, or fallback. DEPLOYER_URL="$(resolve_deployer_url)" # Get machine identity MACHINE_ID=$(cat /etc/machine-id) echo "UltraCloud Bootstrap starting..." echo "Machine ID: $MACHINE_ID" echo "Deployer URL: $DEPLOYER_URL" # Optional bootstrap token (from file or environment) TOKEN_FILE="/etc/ultracloud/bootstrap-token" DEPLOYER_TOKEN="" if [ -s "$TOKEN_FILE" ]; then DEPLOYER_TOKEN=$(cat "$TOKEN_FILE") elif [ -n "''${DEPLOYER_BOOTSTRAP_TOKEN:-}" ]; then DEPLOYER_TOKEN="''${DEPLOYER_BOOTSTRAP_TOKEN}" else DEPLOYER_TOKEN="$(cmdline_value ultracloud.bootstrap_token || true)" fi DEPLOYER_CA_CERT_PATH="''${DEPLOYER_CA_CERT:-}" if [ -z "$DEPLOYER_CA_CERT_PATH" ]; then DEPLOYER_CA_CERT_URL="$(cmdline_value ultracloud.ca_cert_url || true)" if [ -n "$DEPLOYER_CA_CERT_URL" ]; then DEPLOYER_CA_CERT_PATH="/etc/ultracloud/bootstrap-ca.crt" ${pkgs.curl}/bin/curl -sfL --connect-timeout 5 --max-time 30 \ "$DEPLOYER_CA_CERT_URL" \ -o "$DEPLOYER_CA_CERT_PATH" fi fi CURL_ARGS=(-sf --connect-timeout 5 --max-time 15) if [ -n "$DEPLOYER_TOKEN" ]; then CURL_ARGS+=(-H "X-Deployer-Token: $DEPLOYER_TOKEN") fi if [ -n "$DEPLOYER_CA_CERT_PATH" ] && [ -f "$DEPLOYER_CA_CERT_PATH" ]; then CURL_ARGS+=(--cacert "$DEPLOYER_CA_CERT_PATH") fi NODE_IP=$(${pkgs.iproute2}/bin/ip -4 route get 1.1.1.1 2>/dev/null | ${pkgs.gawk}/bin/awk '{for(i=1;i<=NF;i++) if ($i=="src") {print $(i+1); exit}}') if [ -z "$NODE_IP" ]; then NODE_IP=$(${pkgs.iproute2}/bin/ip -4 addr show scope global 2>/dev/null | ${pkgs.gawk}/bin/awk '/inet / {sub("/.*","",$2); print $2; exit}') fi if [ -z "$NODE_IP" ]; then NODE_IP=$(hostname -I 2>/dev/null | ${pkgs.gawk}/bin/awk '{print $1}') fi REQUESTED_NODE_ID="''${ULTRACLOUD_NODE_ID:-}" if [ -z "$REQUESTED_NODE_ID" ]; then REQUESTED_NODE_ID="$(cmdline_value ultracloud.node_id || true)" fi if [ -z "$REQUESTED_NODE_ID" ]; then REQUESTED_NODE_ID="$(dmi_value /sys/class/dmi/id/product_serial)" fi if [ -z "$REQUESTED_NODE_ID" ]; then REQUESTED_NODE_ID="$(hostname)" fi REQUESTED_HOSTNAME="''${ULTRACLOUD_HOSTNAME:-}" if [ -z "$REQUESTED_HOSTNAME" ]; then REQUESTED_HOSTNAME="$(cmdline_value ultracloud.hostname || true)" fi if [ -z "$REQUESTED_HOSTNAME" ]; then REQUESTED_HOSTNAME="$REQUESTED_NODE_ID" fi echo "ULTRACLOUD_MARKER pre-install.boot.$REQUESTED_NODE_ID" CPU_MODEL=$(${pkgs.gawk}/bin/awk -F: '/model name/ {gsub(/^[ \t]+/, "", $2); print $2; exit}' /proc/cpuinfo 2>/dev/null || true) CPU_CORES=$(${pkgs.gawk}/bin/awk '/^cpu cores/ {print $4; exit}' /proc/cpuinfo 2>/dev/null || true) CPU_THREADS=$(${pkgs.coreutils}/bin/nproc --all 2>/dev/null || true) MEMORY_KIB=$(${pkgs.gawk}/bin/awk '/MemTotal:/ {print $2; exit}' /proc/meminfo 2>/dev/null || true) MEMORY_BYTES="" if [ -n "$MEMORY_KIB" ]; then MEMORY_BYTES=$((MEMORY_KIB * 1024)) fi DISKS_JSON=$(${pkgs.util-linux}/bin/lsblk -J -b -o NAME,PATH,SIZE,MODEL,SERIAL,ROTA,TYPE 2>/dev/null | ${pkgs.jq}/bin/jq ' [.blockdevices[] | select(.type == "disk") | { name: .name, path: (.path // null), size_bytes: (.size | tonumber?), model: ((.model // "") | if . == "" then null else . end), serial: ((.serial // "") | if . == "" then null else . end), rotational: (if .rota == null then null else (.rota == 1) end) }] ') NICS_JSON=$(${pkgs.iproute2}/bin/ip -j link 2>/dev/null | ${pkgs.jq}/bin/jq ' [.[] | select(.ifname != "lo") | { name: .ifname, mac_address: ((.address // "") | if . == "" or . == "00:00:00:00:00:00" then null else . end), oper_state: ((.operstate // "") | ascii_downcase | if . == "" then null else . end) }] ') DMI_VENDOR=$(tr -d '\n' /dev/null || true) DMI_PRODUCT=$(tr -d '\n' /dev/null || true) DMI_SERIAL=$(tr -d '\n' /dev/null || true) HARDWARE_FACTS=$(${pkgs.jq}/bin/jq -n \ --arg architecture "$(${pkgs.coreutils}/bin/uname -m)" \ --arg cpu_model "$CPU_MODEL" \ --arg cpu_threads "$CPU_THREADS" \ --arg cpu_cores "$CPU_CORES" \ --arg memory_bytes "$MEMORY_BYTES" \ --arg dmi_vendor "$DMI_VENDOR" \ --arg dmi_product "$DMI_PRODUCT" \ --arg dmi_serial "$DMI_SERIAL" \ --argjson disks "$DISKS_JSON" \ --argjson nics "$NICS_JSON" ' { architecture: (if $architecture == "" then null else $architecture end), cpu_model: (if $cpu_model == "" then null else $cpu_model end), cpu_threads: (if $cpu_threads == "" then null else ($cpu_threads | tonumber) end), cpu_cores: (if $cpu_cores == "" then null else ($cpu_cores | tonumber) end), memory_bytes: (if $memory_bytes == "" then null else ($memory_bytes | tonumber) end), disks: $disks, nics: $nics, dmi: ({ vendor: (if $dmi_vendor == "" then null else $dmi_vendor end), product_name: (if $dmi_product == "" then null else $dmi_product end), serial_number: (if $dmi_serial == "" then null else $dmi_serial end) } | with_entries(select(.value != null))) } | if (.dmi | length) == 0 then del(.dmi) else . end ') REQUEST_JSON=$(${pkgs.jq}/bin/jq -n \ --arg machine_id "$MACHINE_ID" \ --arg node_id "$REQUESTED_NODE_ID" \ --arg hostname "$REQUESTED_HOSTNAME" \ --arg ip "$NODE_IP" \ --argjson hardware_facts "$HARDWARE_FACTS" ' { machine_id: $machine_id, node_id: $node_id, hostname: $hostname, ip: $ip, hardware_facts: $hardware_facts } ') # Phone Home request with retry for i in 1 2 3 4 5; do echo "Attempt $i/5: Contacting Deployer..." if RESPONSE=$(${pkgs.curl}/bin/curl "''${CURL_ARGS[@]}" -X POST \ -H "Content-Type: application/json" \ -d "$REQUEST_JSON" \ "$DEPLOYER_URL/api/v1/phone-home"); then echo "✓ Phone Home successful" # Create directories mkdir -p /etc/ssh /etc/ultracloud /root/.ssh # Validate success flag SUCCESS=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.success // false' || echo "false") if [ "$SUCCESS" != "true" ]; then MESSAGE=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.message // empty' || true) echo "✗ Phone Home rejected: $MESSAGE" sleep $((2 ** i)) continue fi NODE_CONFIG=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -c '.node_config // empty' || true) if [ -z "$NODE_CONFIG" ] || [ "$NODE_CONFIG" = "null" ]; then echo "✗ Phone Home response missing node_config" sleep $((2 ** i)) continue fi echo "$NODE_CONFIG" > /etc/ultracloud/node-config.json echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r ' .node_config.bootstrap_secrets.ssh_authorized_keys[]? ' > /root/.ssh/authorized_keys # Apply SSH host key if provided SSH_HOST_KEY=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.node_config.bootstrap_secrets.ssh_host_key // empty') if [ -n "$SSH_HOST_KEY" ]; then umask 077 echo "$SSH_HOST_KEY" > /etc/ssh/ssh_host_ed25519_key ${pkgs.openssh}/bin/ssh-keygen -y -f /etc/ssh/ssh_host_ed25519_key > /etc/ssh/ssh_host_ed25519_key.pub fi # Apply TLS material if provided TLS_CERT=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.node_config.bootstrap_secrets.tls_cert // empty') TLS_KEY=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.node_config.bootstrap_secrets.tls_key // empty') if [ -n "$TLS_CERT" ] && [ -n "$TLS_KEY" ]; then umask 077 mkdir -p /etc/ultracloud/tls echo "$TLS_CERT" > /etc/ultracloud/tls/node.crt echo "$TLS_KEY" > /etc/ultracloud/tls/node.key fi # Generate host keys locally if missing if [ ! -s /etc/ssh/ssh_host_ed25519_key ]; then ${pkgs.openssh}/bin/ssh-keygen -A fi # Set permissions chmod 644 /etc/ultracloud/node-config.json 2>/dev/null || true chmod 700 /root/.ssh 2>/dev/null || true chmod 600 /root/.ssh/authorized_keys 2>/dev/null || true chmod 600 /etc/ssh/ssh_host_ed25519_key 2>/dev/null || true chmod 644 /etc/ssh/ssh_host_ed25519_key.pub 2>/dev/null || true chmod 600 /etc/ultracloud/tls/node.key 2>/dev/null || true chmod 644 /etc/ultracloud/tls/node.crt 2>/dev/null || true # Signal success NODE_ID=$(echo "$RESPONSE" | ${pkgs.jq}/bin/jq -r '.node_config.assignment.node_id // "unknown"') echo "ULTRACLOUD_MARKER pre-install.phone-home.complete.$NODE_ID" echo "✓ Bootstrap complete: $NODE_ID" exit 0 else echo "✗ Phone Home failed, attempt $i/5" sleep $((2 ** i)) fi done echo "✗ Bootstrap failed after 5 attempts" exit 1 ''; }; # Auto-install service - partitions disk and runs nixos-install systemd.services.ultracloud-install = { description = "UltraCloud Auto-Install to Disk"; wantedBy = [ "multi-user.target" ]; after = [ "ultracloud-bootstrap.service" ]; requires = [ "ultracloud-bootstrap.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; StandardOutput = "journal+console"; StandardError = "journal+console"; }; script = '' set -euo pipefail export PATH="${pkgs.nix}/bin:${config.system.build.nixos-install}/bin:$PATH" cmdline_value() { local key="$1" local arg for arg in $(cat /proc/cmdline); do case "$arg" in "$key"=*) echo "''${arg#*=}" return 0 ;; esac done return 1 } resolve_deployer_url() { local explicit_url="''${DEPLOYER_URL:-}" if [ -z "$explicit_url" ]; then explicit_url="$(cmdline_value ultracloud.deployer_url || true)" fi if [ -n "$explicit_url" ]; then echo "$explicit_url" return 0 fi if ${pkgs.curl}/bin/curl -fsS --connect-timeout 2 --max-time 5 \ http://10.0.2.2:8088/health >/dev/null 2>&1; then echo "http://10.0.2.2:8088" return 0 fi echo "http://192.168.100.1:8080" } resolve_binary_cache_url() { local explicit_url="''${ULTRACLOUD_BINARY_CACHE_URL:-}" if [ -z "$explicit_url" ]; then explicit_url="$(cmdline_value ultracloud.binary_cache_url || true)" fi if [ -n "$explicit_url" ]; then echo "$explicit_url" return 0 fi if ${pkgs.curl}/bin/curl -fsS --connect-timeout 2 --max-time 5 \ http://10.0.2.2:8090/nix-cache-info >/dev/null 2>&1; then echo "http://10.0.2.2:8090" return 0 fi return 1 } if [ ! -s /etc/ultracloud/node-config.json ]; then echo "ERROR: node-config.json missing (bootstrap not complete?)" exit 1 fi NODE_ID=$(${pkgs.jq}/bin/jq -r '.assignment.hostname // .assignment.node_id // empty' /etc/ultracloud/node-config.json) NODE_IP=$(${pkgs.jq}/bin/jq -r '.assignment.ip // empty' /etc/ultracloud/node-config.json) NIXOS_CONFIGURATION=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.nixos_configuration // .assignment.hostname // empty' /etc/ultracloud/node-config.json) INSTALL_PLAN_DISKO_CONFIG_PATH=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.disko_config_path // empty' /etc/ultracloud/node-config.json) DISKO_SCRIPT_PATH=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.disko_script_path // empty' /etc/ultracloud/node-config.json) if [ -z "$DISKO_SCRIPT_PATH" ] && [ -r /etc/ultracloud/disko-script-paths.json ]; then DISKO_SCRIPT_PATH=$(${pkgs.jq}/bin/jq -r --arg cfg "$NIXOS_CONFIGURATION" '.[$cfg] // empty' /etc/ultracloud/disko-script-paths.json) if [ -n "$DISKO_SCRIPT_PATH" ]; then echo "Resolved pre-built Disko script for install profile $NIXOS_CONFIGURATION from the ISO profile map" fi fi TARGET_SYSTEM_PATH=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.target_system_path // empty' /etc/ultracloud/node-config.json) if [ -z "$TARGET_SYSTEM_PATH" ] && [ -r /etc/ultracloud/system-paths.json ]; then TARGET_SYSTEM_PATH=$(${pkgs.jq}/bin/jq -r --arg cfg "$NIXOS_CONFIGURATION" '.[$cfg] // empty' /etc/ultracloud/system-paths.json) if [ -n "$TARGET_SYSTEM_PATH" ]; then echo "Resolved pre-built target system for install profile $NIXOS_CONFIGURATION from the ISO profile map" fi fi TARGET_DISK=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.target_disk // empty' /etc/ultracloud/node-config.json) TARGET_DISK_BY_ID=$(${pkgs.jq}/bin/jq -r '.bootstrap_plan.install_plan.target_disk_by_id // empty' /etc/ultracloud/node-config.json) DEPLOYER_URL="$(resolve_deployer_url)" SRC_ROOT="/opt/ultracloud-src" if [ -z "$NODE_ID" ] || [ -z "$NODE_IP" ]; then echo "ERROR: node-config.json missing hostname/ip" exit 1 fi if [ -z "$NIXOS_CONFIGURATION" ]; then echo "ERROR: node-config.json missing install_plan.nixos_configuration" exit 1 fi TOKEN_FILE="/etc/ultracloud/bootstrap-token" DEPLOYER_TOKEN="" if [ -s "$TOKEN_FILE" ]; then DEPLOYER_TOKEN=$(cat "$TOKEN_FILE") elif [ -n "''${DEPLOYER_BOOTSTRAP_TOKEN:-}" ]; then DEPLOYER_TOKEN="''${DEPLOYER_BOOTSTRAP_TOKEN}" else DEPLOYER_TOKEN="$(cmdline_value ultracloud.bootstrap_token || true)" fi DEPLOYER_CA_CERT_PATH="''${DEPLOYER_CA_CERT:-}" if [ -z "$DEPLOYER_CA_CERT_PATH" ]; then DEPLOYER_CA_CERT_URL="$(cmdline_value ultracloud.ca_cert_url || true)" if [ -n "$DEPLOYER_CA_CERT_URL" ]; then DEPLOYER_CA_CERT_PATH="/etc/ultracloud/bootstrap-ca.crt" ${pkgs.curl}/bin/curl -sfL --connect-timeout 5 --max-time 30 \ "$DEPLOYER_CA_CERT_URL" \ -o "$DEPLOYER_CA_CERT_PATH" fi fi CURL_ARGS=(-sfL --connect-timeout 5 --max-time 120) if [ -n "$DEPLOYER_TOKEN" ]; then CURL_ARGS+=(-H "X-Deployer-Token: $DEPLOYER_TOKEN") fi if [ -n "$DEPLOYER_CA_CERT_PATH" ] && [ -f "$DEPLOYER_CA_CERT_PATH" ]; then CURL_ARGS+=(--cacert "$DEPLOYER_CA_CERT_PATH") fi BUNDLE_PATH="/run/ultracloud/flake-bundle.tar.gz" mkdir -p /run/ultracloud if ${pkgs.curl}/bin/curl "''${CURL_ARGS[@]}" \ "$DEPLOYER_URL/api/v1/bootstrap/flake-bundle" \ -o "$BUNDLE_PATH"; then echo "Downloaded bootstrap flake bundle from deployer" echo "ULTRACLOUD_MARKER install.bundle-downloaded.$NODE_ID" rm -rf "$SRC_ROOT" mkdir -p "$SRC_ROOT" ${pkgs.gzip}/bin/gzip -dc "$BUNDLE_PATH" | ${pkgs.gnutar}/bin/tar -xf - -C "$SRC_ROOT" else echo "No deployer flake bundle available; using embedded source tree" fi echo "ULTRACLOUD_MARKER install.start.$NODE_ID" DISPLAY_TARGET_DISK="$TARGET_DISK" DISK_SELECTOR_SOURCE="auto-discovery" if [ -n "$TARGET_DISK_BY_ID" ]; then DISPLAY_TARGET_DISK="$TARGET_DISK_BY_ID" DISK_SELECTOR_SOURCE="install_plan.target_disk_by_id" elif [ -n "$TARGET_DISK" ]; then DISK_SELECTOR_SOURCE="install_plan.target_disk" fi echo "UltraCloud install starting for $NODE_ID (ip=$NODE_IP, nixos_configuration=$NIXOS_CONFIGURATION, target_disk=$DISPLAY_TARGET_DISK)" if [ -n "$INSTALL_PLAN_DISKO_CONFIG_PATH" ]; then echo "Install contract: disko_config_path=$INSTALL_PLAN_DISKO_CONFIG_PATH, disk_selector_source=$DISK_SELECTOR_SOURCE" else echo "Install contract: disko_config_path=(embedded profile map for $NIXOS_CONFIGURATION), disk_selector_source=$DISK_SELECTOR_SOURCE" fi # Resolve installation target disk. if [ -n "$TARGET_DISK_BY_ID" ]; then if [ ! -b "$TARGET_DISK_BY_ID" ]; then echo "ERROR: target_disk_by_id does not exist: $TARGET_DISK_BY_ID" exit 1 fi DISK="$TARGET_DISK_BY_ID" elif [ -n "$TARGET_DISK" ]; then if [ ! -b "$TARGET_DISK" ]; then echo "ERROR: target_disk does not exist: $TARGET_DISK" exit 1 fi DISK="$TARGET_DISK" else DISK=$(${pkgs.util-linux}/bin/lsblk -dpno NAME,TYPE | ${pkgs.gawk}/bin/awk '$2=="disk"{print $1; exit}') fi if [ -z "$DISK" ]; then echo "ERROR: No disk found" exit 1 fi ROOT_PART=$(${pkgs.util-linux}/bin/lsblk -lnpo NAME,TYPE "$DISK" 2>/dev/null | ${pkgs.gawk}/bin/awk '$2=="part"{print $1}' | sed -n '2p') mkdir -p /mnt # Skip if already installed if [ -n "$ROOT_PART" ] && ${pkgs.util-linux}/bin/lsblk -no FSTYPE "$ROOT_PART" 2>/dev/null | ${pkgs.gnugrep}/bin/grep -q '^ext4$'; then mount "$ROOT_PART" /mnt 2>/dev/null || true if [ -e /mnt/etc/NIXOS ]; then echo "✓ Existing NixOS detected; skipping install" umount /mnt || true exit 0 fi umount /mnt || true fi NIX_CONFIG_LINES=( "experimental-features = nix-command flakes" ) BINARY_CACHE_URL="$(resolve_binary_cache_url || true)" NIXPKGS_PATH="$SRC_ROOT/.bundle-inputs/nixpkgs" if [ ! -e "$NIXPKGS_PATH" ]; then NIXPKGS_PATH="${pkgs.path}" fi if [ -n "$BINARY_CACHE_URL" ]; then echo "Using bootstrap binary cache: $BINARY_CACHE_URL" NIX_CONFIG_LINES+=("substituters = $BINARY_CACHE_URL") NIX_CONFIG_LINES+=("trusted-substituters = $BINARY_CACHE_URL") NIX_CONFIG_LINES+=("require-sigs = false") fi export NIX_CONFIG="$(printf '%s\n' "''${NIX_CONFIG_LINES[@]}")" export NIX_PATH="nixpkgs=$NIXPKGS_PATH" echo "Preparing NixOS installation for configuration $NIXOS_CONFIGURATION" echo "Running disko to partition $DISK..." if [ -n "$DISKO_SCRIPT_PATH" ]; then echo "Realising pre-built Disko script: $DISKO_SCRIPT_PATH" ${pkgs.nix}/bin/nix-store --realise "$DISKO_SCRIPT_PATH" >/dev/null "$DISKO_SCRIPT_PATH/bin/disko-format-mount" else ${pkgs.disko}/bin/disko \ --mode destroy,format,mount \ --yes-wipe-all-disks \ --root-mountpoint /mnt \ --flake "$SRC_ROOT#$NIXOS_CONFIGURATION" fi echo "ULTRACLOUD_MARKER install.disko.complete.$NODE_ID" echo "Running nixos-install..." if [ -n "$TARGET_SYSTEM_PATH" ]; then echo "Realising pre-built target system: $TARGET_SYSTEM_PATH" ${pkgs.nix}/bin/nix-store --realise "$TARGET_SYSTEM_PATH" >/dev/null ${config.system.build.nixos-install}/bin/nixos-install \ --system "$TARGET_SYSTEM_PATH" \ --no-root-passwd \ --no-channel-copy else ${config.system.build.nixos-install}/bin/nixos-install \ --flake "$SRC_ROOT#$NIXOS_CONFIGURATION" \ --no-root-passwd \ --no-channel-copy fi echo "ULTRACLOUD_MARKER install.nixos-install.complete.$NODE_ID" mkdir -p /mnt/etc/ssh /mnt/etc/ultracloud /mnt/root/.ssh /mnt/var/lib cp -f /etc/ultracloud/node-config.json /mnt/etc/ultracloud/node-config.json cp -f /root/.ssh/authorized_keys /mnt/root/.ssh/authorized_keys shopt -s nullglob for host_key in /etc/ssh/ssh_host_*; do cp -f "$host_key" /mnt/etc/ssh/"$(basename "$host_key")" done shopt -u nullglob chmod 700 /mnt/root/.ssh chmod 600 /mnt/root/.ssh/authorized_keys chmod 600 /mnt/etc/ssh/ssh_host_*_key 2>/dev/null || true chmod 644 /mnt/etc/ssh/ssh_host_*_key.pub 2>/dev/null || true rm -rf /mnt/var/lib/photon-src cp -a "$SRC_ROOT" /mnt/var/lib/photon-src sync echo "ULTRACLOUD_MARKER reboot.$NODE_ID" echo "Allowing the harness to observe the reboot marker before shutting down..." sleep 15 echo "✓ Install complete; rebooting..." ${pkgs.systemd}/bin/systemctl reboot ''; }; # Packages for bootstrap + install environment.etc."ultracloud/disko-script-paths.json".text = builtins.toJSON ultracloudBaremetalFormatMountPaths; environment.etc."ultracloud/system-paths.json".text = builtins.toJSON ultracloudBaremetalSystemPaths; environment.systemPackages = with pkgs; [ curl jq vim htop nix gawk gnugrep util-linux parted dosfstools e2fsprogs disko gnutar gzip ]; # SSH with key-based auth for non-interactive access services.openssh = { enable = true; settings.PermitRootLogin = "prohibit-password"; }; # SSH access keys are provisioned dynamically via phone-home users.users.root.openssh.authorizedKeys.keys = [ ]; }