2020-10-01 15:46:04 -07:00
|
|
|
#!/usr/bin/env zsh
|
|
|
|
|
2021-01-20 00:05:10 -08:00
|
|
|
# I don't like the user story for Nix's binaries, unlike Guix's. So I wrote
|
|
|
|
# this to abstract away the unneeded complexity for everyday maintenance of my
|
|
|
|
# NixOS config.
|
2020-10-01 15:46:04 -07:00
|
|
|
#
|
2021-01-20 00:05:10 -08:00
|
|
|
# hey cd|check
|
|
|
|
# nix flake check $DOTFILES
|
|
|
|
# hey sh|show
|
|
|
|
# nix flake show $DOTFILES
|
|
|
|
# hey u|update [INPUT...]
|
|
|
|
# nix flake update --recreate-lock-file $DOTFILES
|
|
|
|
# hey re|rebuild [ARGS...]
|
|
|
|
# nixos-rebuild --flake $DOTFILES#$HOST ${@:-build}
|
2020-10-26 02:47:31 -07:00
|
|
|
# hey t|test -> nixos-rebuild --flake $DOTFILES#$HOST --fast test
|
2020-10-25 12:19:38 -07:00
|
|
|
# hey theme $THEME -> THEME=$THEME hey test (quick theme swapping)
|
2020-10-16 02:49:47 -07:00
|
|
|
# hey rollback -> hey rebuild --rollback switch
|
|
|
|
# hey s|search -> nix search nixpkgs $@
|
2020-10-25 12:19:38 -07:00
|
|
|
# hey swap $PATH -> swaps all specified nix-store symlinks (or recursively
|
|
|
|
# in a specified directory) with copies so they can be
|
|
|
|
# modified in place (while tweaking). Run again to
|
|
|
|
# restore the old link (careful, you'll lose work if you
|
|
|
|
# don't save your changes elsewhere!)
|
2020-10-16 02:49:47 -07:00
|
|
|
# hey vm -> hey rebuild vm
|
|
|
|
# hey up|upgrade -> hey update && hey rebuild switch
|
|
|
|
# hey gc -> GC user profile, optimise nix store
|
|
|
|
# sudo hey gc -> GC, optimise nix store, & delete old boot entries
|
2021-01-20 00:05:10 -08:00
|
|
|
# hey push REMOTE -> 1. Build machine locally, 2. Copy result to remote, 3. Activate config on remote
|
2020-10-16 02:49:47 -07:00
|
|
|
# hey gen|generations -> explore, manage, diff across generations (WIP)
|
2020-10-01 15:46:04 -07:00
|
|
|
#
|
2020-10-16 02:49:47 -07:00
|
|
|
# hey (with no sub-command) can also be used as an alternative to nix-env:
|
2020-10-01 15:46:04 -07:00
|
|
|
#
|
2020-10-16 02:49:47 -07:00
|
|
|
# hey -q
|
|
|
|
# hey -iA nixos.htop
|
|
|
|
# hey -e htop
|
2020-10-01 15:46:04 -07:00
|
|
|
|
|
|
|
set -e
|
2021-01-22 01:18:57 -08:00
|
|
|
if [[ -z $FLAKE ]]; then
|
|
|
|
for dir in /etc/nixos /etc/dotfiles; do
|
|
|
|
if [[ -f "$dir/flake.nix" ]]; then
|
|
|
|
FLAKE=$dir
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
2020-10-01 15:46:04 -07:00
|
|
|
|
|
|
|
#
|
|
|
|
function main {
|
|
|
|
function _do { [[ $DRYRUN ]] && echo "$@" || "$@" }
|
|
|
|
|
|
|
|
### Helpers
|
|
|
|
function _usage {
|
2020-10-16 02:49:47 -07:00
|
|
|
echo "Usage: hey COMMAND [FLAGS...] [ARGS...]"
|
2020-10-01 15:46:04 -07:00
|
|
|
echo
|
|
|
|
echo "Available commands:"
|
2020-10-17 14:01:35 -07:00
|
|
|
echo " check (ch) Same as 'nix flake check \$DOTFILES'"
|
|
|
|
echo " gc Garbage collect and optimize store"
|
2020-10-01 15:46:04 -07:00
|
|
|
echo " generations (gen) TODO"
|
2020-10-17 14:01:35 -07:00
|
|
|
echo " push Push thie config to a remote NixOS system and rebuild it"
|
|
|
|
echo " rebuild (re) Rebuild current system flake"
|
|
|
|
echo " rollback Roll back to last generation"
|
|
|
|
echo " search (s) Searches nixpkgs for a package"
|
|
|
|
echo " show (sh) Same as 'nix flake show \$DOTFILES'"
|
|
|
|
echo " swap Swap nix-store link (or directory thereof) for tweaking"
|
2020-10-17 15:42:02 -07:00
|
|
|
echo " test (t) Quickly rebuild, for quick iteration"
|
2020-10-25 12:19:38 -07:00
|
|
|
echo " theme Quickly swap to another theme"
|
2020-10-17 14:01:35 -07:00
|
|
|
echo " upgrade (up) Update flake lockfile and rebuild"
|
|
|
|
echo " vm Build flake into a VM image"
|
2020-10-01 15:46:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
function _rebuild {
|
|
|
|
# Move to $DOTFILES to prevent polluting the system with result links
|
2021-01-22 01:18:57 -08:00
|
|
|
pushd $FLAKE >/dev/null
|
2021-01-20 00:04:23 -08:00
|
|
|
# REVIEW Use --impure instead when it's in a stable release of nix
|
2021-01-22 01:18:57 -08:00
|
|
|
_do ${SUDO:+sudo} nixos-rebuild \
|
|
|
|
--flake "${FLAKE}#${HOSTNAME:-$HOST}" \
|
2021-01-20 00:04:23 -08:00
|
|
|
--option pure-eval no \
|
|
|
|
${@:-build}
|
2020-10-01 15:46:04 -07:00
|
|
|
popd >/dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
function _update {
|
|
|
|
echo "Updating NixOS flake"
|
2020-10-17 14:23:56 -07:00
|
|
|
if [[ "$@" ]]; then
|
|
|
|
for flake in $@; do
|
2021-01-22 01:18:57 -08:00
|
|
|
_do nix flake update --update-input "$flake" "$FLAKE"
|
2020-10-17 14:23:56 -07:00
|
|
|
done
|
|
|
|
else
|
2021-01-22 01:18:57 -08:00
|
|
|
_do nix flake update --recreate-lock-file "$FLAKE"
|
2020-10-17 14:23:56 -07:00
|
|
|
fi
|
2020-10-01 15:46:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
function _gc {
|
|
|
|
if [[ $EUID == 0 ]]; then
|
|
|
|
echo "Cleaning up your system..."
|
2021-01-20 21:32:40 -08:00
|
|
|
_do nix-collect-garbage ${@:--d}
|
2020-10-17 13:35:04 -07:00
|
|
|
_do nix-store --optimise
|
2021-01-20 21:32:40 -08:00
|
|
|
# Clear out left-over secrets. The switch-to-configuration call below will
|
|
|
|
# regenerate them.
|
|
|
|
[[ -d /run/secrets ]] && _do rm -f /run/secrets/*
|
2020-10-01 15:46:04 -07:00
|
|
|
# nix-collect-garbage is a Nix tool, not a NixOS tool. It won't delete old
|
|
|
|
# boot entries until you do a nixos-rebuild (which means we'll always have
|
|
|
|
# 2 boot entries at any time). Instead, we properly delete them by
|
|
|
|
# reloading the current environment.
|
2021-01-20 21:32:40 -08:00
|
|
|
_do nix-env --delete-generations old --profile /nix/var/nix/profiles/system
|
|
|
|
_do /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
2020-10-01 15:46:04 -07:00
|
|
|
else
|
|
|
|
echo "Cleaning up your user profile..."
|
|
|
|
_do nix-collect-garbage ${@:--d}
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-10-17 13:48:08 -07:00
|
|
|
function _swap {
|
|
|
|
for target in $@; do
|
|
|
|
if [ -d "$target" ]; then
|
|
|
|
files=( "$target"/**/*.nix-store-backup )
|
|
|
|
links=( $(find "$target" -type l) )
|
|
|
|
if [[ "$files" ]]; then
|
|
|
|
echo "There are swapped files here. Unswapping!"
|
|
|
|
for file in $files[@]; do
|
|
|
|
_swap "$link"
|
|
|
|
done
|
|
|
|
else
|
|
|
|
echo "Swapping files in $target"
|
|
|
|
for link in $links[@]; do
|
|
|
|
if [[ "$(readlink $link)" == /nix/store/* ]]; then
|
|
|
|
_swap "$link"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
elif [ -f "$target.nix-store-backup" ]; then
|
|
|
|
echo "Unswapping $target"
|
|
|
|
_do mv -i "$target.nix-store-backup" "$target"
|
|
|
|
elif [ -f "$target" ]; then
|
|
|
|
echo "Swapping $target"
|
|
|
|
_do mv "$target" "$target.nix-store-backup"
|
|
|
|
_do cp "$target.nix-store-backup" "$target"
|
|
|
|
else
|
|
|
|
>&2 echo "Not a valid target: $target"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2020-10-01 15:46:04 -07:00
|
|
|
###
|
2021-01-22 01:18:57 -08:00
|
|
|
eval set -- $(getopt -n hey -o df:h: -l dryrun,flake:,host: -- "$@")
|
|
|
|
while :
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-d|--dryrun) DRYRUN=1; shift ;;
|
|
|
|
-f|--flake) FLAKE=$2; shift 2 ;;
|
|
|
|
-h|--host) HOSTNAME=$2; shift 2 ;;
|
|
|
|
--) shift; break ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
if [[ ! -d $FLAKE ]]; then
|
|
|
|
>&2 echo "Couldn't find flake.nix in $FLAKE"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2020-10-01 15:46:04 -07:00
|
|
|
cmd="$1"
|
|
|
|
[[ $# > 0 ]] && shift
|
|
|
|
case "$cmd" in
|
2021-01-22 01:18:57 -08:00
|
|
|
sh|shell) _do nix develop "$FLAKE" "$@" ;;
|
|
|
|
repl) _do nix repl "$FLAKE/flake.nix" "<nixpkgs>" "$@" ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
|
2021-01-22 01:18:57 -08:00
|
|
|
ch|check) _do nix flake check "$@" "$FLAKE" ;;
|
|
|
|
sh|show) _do nix flake show "$@" "$FLAKE" ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
|
2021-01-22 01:18:57 -08:00
|
|
|
theme) THEME="$1" SUDO=1 _rebuild --fast test ;;
|
|
|
|
t|test) SUDO=1 _rebuild --fast test "$@" ;;
|
|
|
|
re|rebuild) SUDO=1 _rebuild "${@:-switch}" ;;
|
|
|
|
rollback) SUDO=1 _rebuild --rollback switch ;;
|
|
|
|
vm) SUDO=1 _rebuild "$@" vm ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
|
2021-01-22 01:18:57 -08:00
|
|
|
u|update) _update "$@" ;;
|
|
|
|
up|upgrade) _update && SUDO=1 _rebuild switch ;;
|
|
|
|
s|search) nix search nixpkgs "$@" ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
|
2021-01-22 01:18:57 -08:00
|
|
|
swap) _swap "$@" ;;
|
2021-01-20 21:18:52 -08:00
|
|
|
gc) _gc "$@" ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
push)
|
2021-01-19 22:30:43 -08:00
|
|
|
target=$1
|
|
|
|
cmd=${2:-test}
|
|
|
|
echo "Enabling root ssh access on $target"
|
2021-01-20 21:18:52 -08:00
|
|
|
if _do ssh -t "$target" "sudo mkdir -p /root/.ssh && sudo cp -f ~/.ssh/authorized_keys /root/.ssh/authorized_keys"; then
|
2021-01-22 01:18:57 -08:00
|
|
|
trap '_do ssh -t "root@$target" "rm -f /root/.ssh/authorized_keys"' EXIT
|
2021-01-20 21:18:52 -08:00
|
|
|
echo "Building $target ($cmd)"
|
|
|
|
HOSTNAME="${HOSTNAME:-$target}" _rebuild \
|
|
|
|
--build-host localhost \
|
|
|
|
--target-host "root@$target" \
|
|
|
|
$cmd
|
|
|
|
echo "Undoing root ssh access on $target"
|
|
|
|
fi
|
2020-10-01 15:46:04 -07:00
|
|
|
;;
|
|
|
|
|
|
|
|
gen|generations)
|
|
|
|
profile=/nix/var/nix/profiles/system
|
|
|
|
case "$1" in
|
|
|
|
switch) >&2 echo "Targeted rollback not supported yet" ;; # TODO Is this true?
|
|
|
|
diff)
|
|
|
|
to=/nix/var/nix/profiles/system-${2}-link
|
|
|
|
diff \
|
|
|
|
<(nix-store -q --references $profile) \
|
|
|
|
<(nix-store -q --references $to)
|
|
|
|
;;
|
|
|
|
remove)
|
|
|
|
shift
|
|
|
|
_do sudo nix-env --delete-generations --profile $profile $@
|
|
|
|
;;
|
|
|
|
"")
|
|
|
|
_do sudo nix-env --list-generations --profile $profile
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
;;
|
|
|
|
|
2021-01-24 10:05:38 -08:00
|
|
|
h|help) _usage ;;
|
2020-10-01 15:46:04 -07:00
|
|
|
-*) _do nix-env "$cmd" "$@" ;;
|
|
|
|
"") _usage ;;
|
2021-01-24 10:06:03 -08:00
|
|
|
*) if command -v hey-$cmd >/dev/null; then
|
|
|
|
hey-$cmd $@
|
|
|
|
else
|
|
|
|
echo "Couldn't find command: $cmd" 1>&2
|
|
|
|
exit 1
|
|
|
|
fi
|
2020-10-01 15:46:04 -07:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
main "$@"
|