infra/Justfile

321 lines
10 KiB
Makefile
Executable file

# _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