diff --git a/scripts/codex-setup.sh b/scripts/codex-setup.sh index e1e67c8..4d19207 100755 --- a/scripts/codex-setup.sh +++ b/scripts/codex-setup.sh @@ -41,6 +41,17 @@ warn-dirty = false build-users-group = nixbld EOF + # The official installer's single-user root path still shells out to + # `sudo` to create /nix even though it already knows it's running as + # root -- confirmed live against a sudo-less minimal Debian/Proxmox + # node, where it fails with "sudo: not found" and prints this exact + # mkdir/chown as the manual fix. Pre-create it so that branch of the + # installer is skipped entirely. + if [ ! -d /nix ]; then + mkdir -m 0755 /nix + chown root /nix + fi + sh <(curl -L https://nixos.org/nix/install) --no-daemon else sh <(curl -L https://nixos.org/nix/install) --no-daemon diff --git a/scripts/create-proxmox-resource.sh b/scripts/create-proxmox-resource.sh index fc8161c..6d303df 100755 --- a/scripts/create-proxmox-resource.sh +++ b/scripts/create-proxmox-resource.sh @@ -524,7 +524,7 @@ ensure_remote_repo() { echo echo "==> Ensuring ${remote_repo_dir} exists and is current on ${node}..." if [[ "$dry_run" -eq 1 ]]; then - echo "[dry-run] would ensure ${remote_repo_dir} exists on ${node} (clone + scripts/codex-setup.sh if missing, git pull if present)" + echo "[dry-run] would ensure ${remote_repo_dir} exists on ${node} (clone if missing, git pull if present), and would verify/bootstrap build tooling there (scripts/codex-setup.sh) if \`nix\` isn't already on PATH" return fi @@ -542,6 +542,33 @@ ensure_remote_repo() { fi echo "Not present -- cloning from ${origin_url}..." ssh "$ssh_target" "git clone '${origin_url}' '${remote_repo_dir}'" + fi + + # Trivial check, run every time (not just right after a fresh clone) -- + # confirmed live: a first bootstrap can clone the repo successfully and + # still leave the node without a working `nix` (e.g. the node had no + # `sudo`, which the Nix installer's root path depends on -- see the fix + # in scripts/codex-setup.sh), and a later run with the repo already + # present would otherwise never retry it. Sources + # scripts/lib/nix-bootstrap.sh's ensure_nix_profile first -- a + # single-user Nix install typically only gets sourced into login shells, + # and ssh's non-interactive command execution is neither, so a + # freshly-installed `nix` still wouldn't be on PATH here without it. + # + # Just `nix` today -- the only thing the remote build commands below + # actually invoke -- but a list (not a single hardcoded check) so a + # future remote step needing another tool can add itself here instead of + # growing a parallel check. + local remote_required_cmds=(nix) + local tooling_check_cmd="cd '${remote_repo_dir}' && . scripts/lib/nix-bootstrap.sh && ensure_nix_profile" + local cmd + for cmd in "${remote_required_cmds[@]}"; do + tooling_check_cmd="${tooling_check_cmd} && command -v ${cmd}" + done + + if ssh "$ssh_target" "$tooling_check_cmd" >/dev/null 2>&1; then + echo "Build tooling already present on ${node}." + else echo "==> Bootstrapping build tooling on ${node} (scripts/codex-setup.sh)..." ssh "$ssh_target" "cd '${remote_repo_dir}' && bash scripts/codex-setup.sh" fi @@ -625,6 +652,11 @@ repo_dir="$1"; target="$2"; dest_dir="$3"; dest_name="$4"; nix_extra_opts_str="$ declare -a NIX_OPTS=() [[ -n "$nix_extra_opts_str" ]] && eval "NIX_OPTS=(${nix_extra_opts_str})" cd "$repo_dir" +# A single-user Nix install only gets sourced into login shells; this ssh +# session is neither, so `nix` wouldn't otherwise be on PATH here even +# right after a successful install. +. scripts/lib/nix-bootstrap.sh +ensure_nix_profile NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build --impure \ --no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \ ".#nixosConfigurations.${target}.config.system.build.tarball" \ @@ -672,6 +704,8 @@ repo_dir="$1"; target="$2"; dest_dir="$3"; dest_name="$4"; nix_extra_opts_str="$ declare -a NIX_OPTS=() [[ -n "$nix_extra_opts_str" ]] && eval "NIX_OPTS=(${nix_extra_opts_str})" cd "$repo_dir" +. scripts/lib/nix-bootstrap.sh +ensure_nix_profile nix build --no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \ ".#nixosConfigurations.${target}.config.system.build.diskoImagesScript" \ --out-link "result-${target}"