aboutsummaryrefslogtreecommitdiff
path: root/devices.sh
diff options
context:
space:
mode:
Diffstat (limited to 'devices.sh')
-rwxr-xr-xdevices.sh218
1 files changed, 218 insertions, 0 deletions
diff --git a/devices.sh b/devices.sh
new file mode 100755
index 0000000..7867593
--- /dev/null
+++ b/devices.sh
@@ -0,0 +1,218 @@
+#!/usr/bin/env bash
+set -eu
+declare -a devices
+declare -A sshmap
+################################################################################
+omnia_hash="bd7ac5d8c08538ec1f126d34b765f0362427fe17"
+## aarch64
+# Mox
+devices+=( "dean" "spt-mox2" )
+sshmap["spt-mox2"]="mox2.spt"
+# Raspberry Pi
+devices+=( "adm-mpd" )
+sshmap["adm-mpd"]="mpd.adm"
+
+## armv7
+# Omnia
+devices+=( "spt-omnia" )
+sshmap["spt-omnia"]="omnia.spt"
+# Raspberry Pi
+devices+=( "spt-mpd" )
+sshmap["spt-mpd"]="mpd.spt"
+################################################################################
+
+valid_device() {
+ local check="$1"
+ for dev in "${devices[@]}"; do
+ [ "$dev" != "$check" ] \
+ || return 0
+ done
+ return 1
+}
+
+
+build() {
+ local system="$1"
+ echo "Building $system"
+ local -a args
+ local toplevel=".config.system.build.toplevel"
+ args+=("--keep-going")
+ args+=("--override-input" "nixturris" "/home/cynerd/projects/nixturris")
+ if [[ "$system" == *omnia ]]; then
+ true
+ #toplevel=".config.system.build.cross.x86_64-linux${toplevel}"
+ #args=( \
+ # "--override-input" "nixpkgs" "github:NixOS/nixpkgs/${omnia_hash}"
+ # "--override-input" "nixturris/nixpkgs" "github:NixOS/nixpkgs/${omnia_hash}"
+ #)
+ fi
+ nix build \
+ -o "result-${system}" \
+ "${args[@]}" \
+ "${0%/*}#nixosConfigurations.${system}${toplevel}"
+}
+
+build_validate() {
+ local system="$1"
+ [ -L "result-$system" ] && [ ! -e "result-$system" ]
+}
+
+copy() {
+ local system="$1"
+ if ! build_validate "$system"; then
+ echo "System '$system' seems to be not build." >&2
+ return 1
+ fi
+ local store="$(readlink -f "result-$system")"
+ local host="${sshmap["$system"]:-$system}"
+
+ local freespace="$(ssh "$host" -- df -B 1 /nix | awk 'NR == 2 { print $4 }')"
+ local required="$(nix path-info -S "$store")"
+ if [ "$required" -ge "$freespace" ]; then
+ echo "There is not enough space to copy clousure to: $system" >&2
+ return 1
+ fi
+
+ echo "Copy closure to: $system"
+ nix copy -s --to "ssh://$host" "$store"
+}
+
+setenv() {
+ local system="$1"
+ if ! build_validate "$system"; then
+ echo "System '$system' seems to be not build." >&2
+ return 1
+ fi
+ local store="$(readlink -f "result-$system")"
+ local host="${sshmap["$system"]:-$system}"
+
+ echo "Update system: $system"
+ if [ "$(ssh "$host" -- readlink -f /nix/var/nix/profiles/system)" != "$store" ]; then
+ ssh -t "$host" -- \
+ sudo nix-env --profile /nix/var/nix/profiles/system --set "$store"
+ fi
+}
+
+boot() {
+ local system="$1"
+ setenv "$system" || return 1
+
+ local store="$(readlink -f "result-$system")"
+ local host="${sshmap["$system"]:-$system}"
+
+ echo "Setting boot system: $system"
+ ssh -t "$host" -- \
+ sudo /nix/var/nix/profiles/system/bin/switch-to-configuration boot
+}
+
+is_current() {
+ ssh "$1" -- \
+ '[ "$(readlink -f /run/current-system)" != "$(readlink -f /nix/var/nix/profiles/system)" ]'
+}
+
+switch() {
+ local system="$1"
+ setenv "$system" || return 1
+
+ local store="$(readlink -f "result-$system")"
+ local host="${sshmap["$system"]:-$system}"
+
+ if is_current "$host"; then
+ echo "Switching: $system"
+ ssh -t "$host" -- \
+ sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
+ else
+ echo "This system is already running: $system"
+ fi
+}
+
+switch_test() {
+ local system="$1"
+ setenv "$system" || return 1
+
+ local store="$(readlink -f "result-$system")"
+ local host="${sshmap["$system"]:-$system}"
+
+ if is_current "$host"; then
+ echo "Testing: $system"
+ ssh -t "$host" -- \
+ sudo /nix/var/nix/profiles/system/bin/switch-to-configuration test
+ else
+ echo "This system is already running: $system"
+ fi
+}
+
+for_devices() {
+ for device in "${selected_devices[@]}"; do
+ for op in "$@"; do
+ if ! "$op" "$device"; then
+ echo "Operation '$op' failed for: $device" >&2
+ break
+ fi
+ done
+ done
+}
+
+
+operation="${1:-}"
+[ $# -gt 0 ] && shift
+
+declare -a selected_devices
+if [ $# -gt 0 ]; then
+ for device in "$@"; do
+ if ! valid_device "$device"; then
+ echo "No such device: $device" >&2
+ exit 2
+ fi
+ selected_devices+=("$device")
+ done
+else
+ selected_devices=("${devices[@]}")
+fi
+
+case "$operation" in
+ help|h)
+ cat <<-EOF
+ Usage $0 operation [device]...
+ Local system builder and updater for remote devices.
+
+ Operations:
+ build: build device system
+ copy: copy built system to the device
+ boot: set built system to be boot default on the device
+ switch: switch to the built system on the target device
+ test: test the built system on the target device
+ EOF
+ ;;
+ build|b|"")
+ for_devices build
+ ;;
+ copy|c)
+ for_devices copy
+ ;;
+ boot)
+ for_devices boot
+ ;;
+ switch|s)
+ for_devices switch
+ ;;
+ test|t)
+ for_devices switch_test
+ ;;
+ build-copy|bc)
+ for_devices build copy
+ ;;
+ build-switch|bs)
+ for_devices build copy switch
+ ;;
+ build-test|bt)
+ for_devices build copy switch_test
+ ;;
+ build-boot|bb)
+ for_devices build copy boot
+ ;;
+ default)
+ echo "Unknown operation: $operation" >&2
+ exit 2
+ ;;
+esac