# _DEFAULT_VERSION_TMPL: # echo "{{invocation_directory()}}/nix/variables/versions.tmpl.nix" _usage: just -l # Re-render the default versions update-default-versions: nix flake update _get_nix_path versionsPath: echo $(set -x; nix-build --no-link --show-trace {{ invocation_directory() }}/nix/default.nix -A channelSources --argstr versionsPath {{ versionsPath }}) _device recipe dir +moreargs="": #!/usr/bin/env bash set -ex unset NIX_PATH source $(just -v _get_nix_path {{ invocation_directory() }}/{{ dir }}/versions.nix) $(set -x; nix-build --no-link --show-trace $(dirname {{ dir }})/default.nix -A recipes.{{ recipe }} --argstr dir {{ dir }} {{ moreargs }}) _render_templates: #!/usr/bin/env bash set -ex if ! ip route get 1.1.1.1; then echo No route to WAN. Skipping template rendering... else source $(just -v _get_nix_path {{ invocation_directory() }}/nix/variables/versions.nix) # nix/scripts/pre-eval-fixed.sh nix/home-manager/profiles/dotfiles/vcsh{.tmpl,}.nix fi rebuild-remote-device device +rebuildargs="dry-activate": #!/usr/bin/env bash set -ex nix run .#colmena -- apply --impure --on {{ device }} {{ rebuildargs }} # Rebuild this device's NixOS rebuild-this-device +rebuildargs="dry-activate": nix run .#colmena -- apply-local --impure --sudo {{ rebuildargs }} # Re-render the versions of a remote device and rebuild its environment update-remote-device devicename +rebuildargs='build': #!/usr/bin/env bash set -e ( set -xe cd nix/os/devices/{{ devicename }} nix flake update ) just -v rebuild-remote-device {{ devicename }} {{ rebuildargs }} git commit -v nix/os/devices/{{ devicename }}/flake.{nix,lock} -m "nix/os/devices/{{ devicename }}: bump versions" # Re-render the versions of the current device and rebuild its environment update-this-device rebuild-mode='switch' +moreargs='': #!/usr/bin/env bash set -e ( set -xe cd nix/os/devices/$(hostname -s) nix flake update ) just -v rebuild-this-device {{ rebuild-mode }} {{ moreargs }} git commit -v nix/os/devices/$(hostname -s)/flake.{nix,lock} -m "nix/os/devices/$(hostname -s): bump versions" # Rebuild an offline system rebuild-disk device: #!/usr/bin/env bash set -xe just -v disk-mount {{ device }} trap "set +e; just -v disk-umount {{ device }}" EXIT just -v disk-install {{ device }} # Re-render the versions of the given offline system and reinstall it in offline-mode update-disk dir: #!/usr/bin/env bash set -exuo pipefail dir={{ dir }} template={{ dir }}/versions.tmpl.nix outfile={{ dir }}/versions.nix if ! test -e ${template}; then template="$(just _DEFAULT_VERSION_TMPL)" fi esh -o ${outfile} ${template} if ! test "$(git diff ${outfile})"; then echo Already on latest versions exit 0 fi export SYSREBUILD_LOG=.{{ dir }}_sysrebuild.log just -v rebuild-disk {{ dir }} || { echo ERROR: Update of {{ dir }} failed, reverting ${outfile}... exit 1 } git commit -v ${outfile} -m "${dir}: bump versions" # Iterate on a qtile config by running it inside Xephyr. (un-/grab the mouse with Ctrl + Shift-L) hm-iterate-qtile: #!/usr/bin/env bash set -xe home-manager switch || just -v rebuild-this-device switch Xephyr -ac -br -resizeable :1 & XEPHYR_PID=$! echo ${XEPHYR_PID} DISPLAY=:1 $(grep qtile ~/.xsession) & echo "Xephyr started. un-/grab the mouse with Ctrl + Shift-L" wait $! kill ${XEPHYR_PID} # !!! DANGERIOUS !!! This wipes the disk which is configured for the given device. disk-prepare dir: just -v _device diskPrepare {{ dir }} disk-relabel dir previous: just -v _device diskRelabel {{ dir }} --argstr previousDiskId {{ previous }} # Mount the target disk specified by device configuration directory. The 'dir' argument points to a device configuration, e.g. 'nix/os/devices/steveej-live-mmc-SL32G_0x259093f6' disk-mount dir: just -v _device diskMount {{ dir }} # Unmount target disk, specified by device configuration directory disk-umount dir: just -v _device diskUmount {{ dir }} # Perform an offline installation on the mounted target disk, specified by device configuration directory disk-install dir: _render_templates just -v _device diskInstall {{ dir }} verify-n-unlock sshserver attempts="10": #!/usr/bin/env bash set -e env \ GETPW="just _get_pass_entry Infrastructure/VPS/{{ sshserver }} DRIVE_PW" \ SSHOPTS="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} SSHOPTS)" \ VNCSOCK="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} VNCSOCK)" \ VNCPW="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} VNCPW)" \ \ just _verify-n-unlock {{ sshserver }} {{ attempts }} _verify-n-unlock sshserver attempts: #!/usr/bin/env bash set -e : ${VNCSOCK:?VNCSOCK must be set} : ${VNCPW:?VNCPW must be set} export MAGICK_ARGS="-filter Catrom -density 72 -resample 300 -contrast -normalize -despeckle -type grayscale -sharpen 1 -posterize 3 -negate -gamma 100 -blur 1x65535" export TESS_ARGS="-c debug_file=/dev/null --psm 4" function send() { local what="${1:?need something to send}" ssh -4 ${SSHOPTS:?need sshopts} root@{{ sshserver }} "echo -e ${what}>> /dev/tty0" &>/dev/null } function expect() { local what="${1:?need something to expect}" vncdo --server=${VNCSOCK} --password=${VNCPW} --disable-desktop-resizing --nocursor capture $PWD/screenshot.bmp convert ${MAGICK_ARGS} screenshot.bmp screenshot.tiff tesseract ${TESS_ARGS} screenshot.tiff screenshot grep --quiet "${what}" screenshot.txt } function send_and_expect() { local send="${1:?need something to send}" local expect="${2:?need something to expect}" if ! send "${send}"; then echo warning: cannot send > /dev/stderr return -1 fi expect "${expect}" } trap 'E=$?; set +e; rm screenshot.*; echo Exiting...; kill $(jobs -p | cut -d " " -f 4); exit $E' EXIT for i in `seq 1 {{ attempts }}`; do echo Attempt $i... expect="$(pwgen -0 12)" send="'\0033\0143'${expect}" if send_and_expect "${send}" "${expect}"; then pipe=$(mktemp -u) mkfifo ${pipe} exec 3<>${pipe} rm ${pipe} echo Verification succeeded at attempt $i. Unlocking remote drive... ssh -4 ${SSHOPTS} root@{{ sshserver }} "cryptsetup-askpass" <&3 &>/dev/null & eval ${GETPW} | head -n1 >&3 for j in `seq 1 120`; do sleep 0.5 if expect '— success'; then echo Unlock successful. exit 0 fi done echo Unlock failed... exit 1 fi done echo Verification failed {{ attempts }} times. Giving up... exit 1 _get_pass_entry path key: pass show {{ path }}| grep -E "^{{ key }}:" | sed -E 's/^[^:]+: *//g' run-with-channels +cmds: #!/usr/bin/env bash source $(just -v _get_nix_path {{ invocation_directory() }}/nix/variables/versions.nix) {{ cmds }} install-config config root: sudo just run-with-channels nixos-install -I nixos-config={{ invocation_directory() }}/{{ config }} --root {{ root }} --no-root-passwd # Switch between gpg-card capable devices which have a copy of the same key switch-gpg-card key-id="6EEFA706CB17E89B": #!/usr/bin/env bash # # Derived from https://github.com/drduh/YubiKey-Guide/issues/19. # # Connect the new device and then run this script to make it known to gnupg. # set -xe if [[ -n "{{key-id}}" ]]; then KEY_ID="{{key-id}}" else KEY_ID=$(gpg --card-status | rg sec | rg -o '[0-9A-Z]{16}') fi # export pubkey and ownertrust gpg2 --output "${KEY_ID}".pubkey --export "${KEY_ID}" # if this fails the trust in the key is missing and can be fixed with `gpg --edit-key ${KEY_ID}` gpg2 --export-ownertrust | rg "${KEY_ID}" > "${KEY_ID}".ownertrust # delete the key gpg --yes --delete-secret-and-public-keys "${KEY_ID}" # import pubkey and ownertrust back and cleanup gpg2 --import "${KEY_ID}".pubkey gpg2 --import-ownertrust < "${KEY_ID}".ownertrust rm "${KEY_ID}".{pubkey,ownertrust} # refresh the gpg agent gpg-connect-agent "scd serialno" "learn --force" /bye gpg --card-status # Connect to `remote` UUID, and turn it into a short name uuid-to-device-name remote: #!/usr/bin/env bash set -e -o pipefail ssh {{ remote }} 'nix run nixpkgs.dmidecode -c dmidecode -s system-uuid' | xxhsum --quiet -H1 | awk '{print $1}' test-connection: #! /usr/bin/env nix-shell #! nix-shell -p curl zsh #! nix-shell -i zsh #! nix-shell --pure while true; do FAILURE="false" output=$( echo "$(date)\n---" for url in \ "https://172.16.0.1:65443/0.7/gui/#/login/" \ "https://192.168.0.1" \ "http://172.172.171.9" \ "https://172.172.171.10:65443" \ "https://172.172.171.11:65443" \ "https://172.172.171.13:443" \ "https://172.172.171.14:443" \ "http://172.172.171.15:22" \ "http://172.172.171.16:22" \ "https://crates.io" \ "https://holo.host" \ ; \ do print "trying ${url}": $( curl_output=$(curl --http0.9 -k --head --connect-timeout 0.5 ${url} 2>&1) # if [ $? -ne 0 ]; then if [[ "$curl_output" == *timeout* ]]; then echo failure: $(echo ${curl_output} | tail -n1) # BUG: outer FAILURE is not set by this FAILURE="true" else echo success fi ) done ) clear echo ${output} if [[ ${FAILURE} == "true" ]]; then echo something failed tracepath -m5 -n1 172.16.0.1 tracepath -m5 -n1 192.168.0.1 fi sleep 5 done cachix-use name: nix run nixpkgs/nixos-unstable#cachix -- use {{ name }} -m nixos -d nix/os/ update-sops-keys: for file in $(egrep -lr '"?sops"?:') secrets; do sops updatekeys -y $file; done deploy-router0-dmz0: NIX_SSHOPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o CheckHostIP=no" nixos-rebuild switch --impure --flake .\#router0-dmz0 --target-host root@192.168.20.1 ttyusb: screen -fa /dev/ttyUSB0 115200