{ self, inputs, ... }: let nixpkgsLib = inputs.nixpkgs.lib.extend (final: prev: let date = final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101"); revCode = flake: flake.shortRev or "dirty"; in { trivial = prev.trivial // { release = "24.08:u-${prev.trivial.release}"; codeName = "Alpha"; revisionWithDefault = default: self.rev or default; versionSuffix = ".${date}.${revCode self}:u-${revCode inputs.nixpkgs}"; }; } ); mkSystem = target: nixpkgsLib.nixosSystem { modules = [ { imports = [ inputs.impermanence.nixosModules.impermanence ]; } ./base.nix ./disk.nix ./network.nix ./app.nix target ]; }; in { flake.nixosConfigurations = { qclk-rpi3 = mkSystem target/rpi3.nix; }; perSystem = { lib, libMy, pkgs, ... }: let inherit (lib) concatMapStringsSep; in { devenv.shells.firmware = libMy.withRootdir { packages = with pkgs; [ nixos-rebuild nixVersions.latest wireguard-tools ]; scripts = let shellUtils = '' die() { echo "$1" >&2 exit 1 } ''; exportPath = ps: let pkgsPath = concatMapStringsSep ":" (p: "${p}/bin") ps; in ''export PATH="$PATH:${pkgsPath}"''; buildImgRootHelper = pkgs.writeShellScript "fixup-perms" '' pushd "$1" # systemd-network GID chgrp 152 etc/qclk/wg.key chmod 640 etc/qclk/wg.key popd mkfs.ext4 -L qclkos-persist -d "$1" "$2" ''; in { build.exec = '' nix build "..#nixosConfigurations.qclk-$1.config.system.build.toplevel" ''; build-image.exec = '' set -e ${exportPath (with pkgs; [ util-linux fakeroot e2fsprogs zstd python3 ])} ${shellUtils} usage() { die "usage: $0 " } populate_persist() { mkdir -p etc/qclk old_umask="$(umask)" umask 077 wg genkey > etc/qclk/wg.key wg_pubkey="$(wg pubkey < etc/qclk/wg.key)" id="$(python3 -c "import base64; print(base64.b64decode('$wg_pubkey')[:4].hex())")" pin="$(python3 -c "import random; print('''.join(str(random.randint(0, 9)) for _ in range(6)))")" cat << EOF > etc/qclk/config.yaml management: ip: $ip pin: '$pin' EOF umask "$old_umask" } [ $# -eq 2 ] || usage target=$1 ip=$2 nix build "..#nixosConfigurations.qclk-$target.config.my.disk.image" persistRoot=$(mktemp --tmpdir -d qclkos-persist-XXXXX) pushd "$persistRoot" populate_persist popd out=qclkos-$target-$id.img cp --sparse=always result/qclkos-$target.img $out chmod u+w $out eval $(partx $out -o START,SECTORS --nr 2 --pairs) persistImg=$(mktemp --tmpdir qclkos-persist-XXXXX.img) truncate -s $((SECTORS * 512)) $persistImg fakeroot ${buildImgRootHelper} $persistRoot $persistImg dd conv=notrunc if=$persistImg of=$out seek=$START count=$SECTORS rm -r "$persistRoot" "$persistImg" [ -z "$NO_COMPRESS" ] && zstd -7 -T0 --rm -f $out echo "====== DONE! ======" echo "WireGuard pubkey: $wg_pubkey" echo "Control PIN: $pin" ''; push-config.exec = '' ${shellUtils} usage() { die "usage: $0 " } [ $# -eq 3 ] || usage host=$1; shift target=$1; shift verb=$1; shift export NIX_SSHOPTS="-i .keys/management.key" nixos-rebuild $verb --flake ..#qclk-$target --target-host root@"$host" --use-substitutes "$@" ''; clean.exec = '' rm -f qclkos-*.img* ''; }; }; }; }