#!/bin/sh set -e usage() { echo "deploy: deploy a nix config to a remote machine, possibly activating it" echo "" echo "usage: deploy [options] " echo "options:" echo "- --action switch|test" echo "- --variant light|min" exit 1 } action=switch variant= nixArgs=() parseArgs() { while [ "$#" -ne 0 ]; do local arg=$1 shift case "$arg" in (--action) action=$1 shift ;; (--help) usage ;; (--variant) if [ -n "$1" ]; then variant=-$1 else variant= fi shift ;; (crappy|desko|lappy|moby|servo) host="$arg" ;; (*) nixArgs+=("$arg") ;; esac done } runOnTarget() { # run the command ($@) on the machine we're deploying to. # if that's a remote machine, then do it via ssh, else local shell. if [ -n "$addr" ]; then ssh "$addr" "$@" else "$@" fi } parseArgs "$@" nix-build -A "hosts.$host$variant" --out-link "./build/result-$host$variant" "${nixArgs[@]}" storePath="$(readlink ./build/result-$host$variant)" # mimic `nixos-rebuild --target-host`, in effect: # - nix-copy-closure ... # - nix-env --set ... # - switch-to-configuration # avoid the actual `nixos-rebuild` for a few reasons: # - fewer nix evals # - more introspectability and debuggability # - sandbox friendliness (especially: `git` doesn't have to be run as root) if [ -n "$host" ]; then if [ -e /run/secrets/nix_signing_key ]; then sudo nix store sign -r -k /run/secrets/nix_signing_key "$storePath" else echo "not signing store paths: /run/secrets/nix_signing_key does not exist" fi # add more `-v` for more verbosity (up to 5). # builders-use-substitutes false: optimizes so that the remote machine doesn't try to get paths from its substituters. # we already have all paths here, and the remote substitution is slow to check and SERIOUSLY flaky on moby in particular. nix copy -vv --option builders-use-substitutes false --to "ssh-ng://$host" "$storePath" fi if [ -n "$action" ]; then runOnTarget sudo nix-env -p /nix/var/nix/profiles/system --set "$storePath" runOnTarget sudo "$storePath/bin/switch-to-configuration" "$action" fi