#!/usr/bin/env bash set -euo pipefail FLAKE= TARGET= ON_NEXT_BOOT= USE_SUBSTITUTES="1" USE_REMOTE_SUDO="1" ARGS=() OPTS=() while [[ $# -gt 0 ]]; do case $1 in --flake) FLAKE="$2" shift shift ;; --target) TARGET="$2" shift shift ;; --on-next-boot) ON_NEXT_BOOT="1" shift ;; --use-substitutes) USE_SUBSTITUTES="1" shift ;; --no-use-substitutes) USE_SUBSTITUTES="" shift ;; --use-remote-sudo) USE_REMOTE_SUDO="1" shift ;; --no-use-remote-sudo) USE_REMOTE_SUDO="" shift ;; --) shift OPTS=( "$@" ) break ;; -*) echo "unknown option: $1" exit 1 ;; *) ARGS+=("$1") shift ;; esac done set -- "${ARGS[@]}" if [[ -z ${FLAKE} ]]; then # Flake not specified, use working directory FLAKE="$(pwd)" fi FLAKE_STORE_PATH="$(nix flake archive --json "${FLAKE}" | jq -r .path)" if [[ "${#ARGS[@]}" -lt 1 ]]; then echo "Command not specified" exit 1 fi COMMAND="${ARGS[0]}" if [[ "${COMMAND}" != "apply" && "${COMMAND}" != "build" && "${COMMAND}" != "exec" ]]; then echo "Unsupported command: ${COMMAND}" exit 1 fi if [[ "${#ARGS[1]}" -lt 2 ]]; then echo "Host not specified" exit 1 fi HOST="${ARGS[1]}" if [[ -z ${TARGET} ]]; then # Use fqdn as target TARGET="$(nix --extra-experimental-features "nix-command flakes" eval --raw "${FLAKE_STORE_PATH}#nixosConfigurations.${HOST}" --apply "host: host.config.networking.fqdn")" fi APPLY_OPTS=() if [[ -n "${USE_SUBSTITUTES}" ]]; then APPLY_OPTS+=("--use-substitutes") fi if [[ -n "${USE_REMOTE_SUDO}" ]]; then APPLY_OPTS+=("--use-remote-sudo") fi APPLY_OPERATION="switch" if [[ -n "${ON_NEXT_BOOT}" ]]; then APPLY_OPERATION="boot" fi case "${COMMAND}" in apply) nixos-rebuild "${APPLY_OPERATION}" --flake "${FLAKE_STORE_PATH}#${HOST}" --target-host "${TARGET}" "${APPLY_OPTS[@]}" ;; build) nixos-rebuild build --flake "${FLAKE_STORE_PATH}#${HOST}" ;; exec) # shellcheck disable=SC2029 ssh -t "${TARGET}" "${OPTS[@]}" ;; *) echo "Unsupported command: ${COMMAND}" exit 1 ;; esac