qclk/firmware/default.nix

155 lines
4.0 KiB
Nix

{ 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 <target> <IP>"
}
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 <host> <target> <verb>"
}
[ $# -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*
'';
};
};
};
}