feat: deploy onto the pi and add scripts for boot

This commit is contained in:
Jet 2026-03-22 23:24:05 -07:00
parent f4d95c595e
commit 16ad3c6181
No known key found for this signature in database
13 changed files with 399 additions and 175 deletions

155
flake.nix
View file

@ -74,8 +74,17 @@
overlays = [ rust-overlay.overlays.default ];
};
muslPkgs = import nixpkgs {
inherit system;
crossSystem.config = "aarch64-unknown-linux-musl";
overlays = [ rust-overlay.overlays.default ];
};
piRustToolchain = pkgs.rust-bin.stable.latest.default.override {
targets = [ "aarch64-unknown-linux-gnu" ];
targets = [
"aarch64-unknown-linux-gnu"
"aarch64-unknown-linux-musl"
];
};
piCraneLib = (crane.mkLib pkgs).overrideToolchain piRustToolchain;
@ -106,7 +115,33 @@
}
);
bootstrapModule =
piStaticArgs = {
inherit src;
pname = "noisebell-pi-static";
version = "0.1.0";
strictDeps = true;
doCheck = false;
CARGO_BUILD_TARGET = "aarch64-unknown-linux-musl";
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER = "${muslPkgs.stdenv.cc.targetPrefix}cc";
TARGET_CC = "${muslPkgs.stdenv.cc.targetPrefix}cc";
CC_aarch64_unknown_linux_musl = "${muslPkgs.stdenv.cc.targetPrefix}cc";
HOST_CC = "${pkgs.stdenv.cc.nativePrefix}cc";
depsBuildBuild = [ muslPkgs.stdenv.cc ];
cargoExtraArgs = "-p noisebell";
};
piStaticArtifacts = piCraneLib.buildDepsOnly piStaticArgs;
noisebell-pi-static = piCraneLib.buildPackage (
piStaticArgs
// {
cargoArtifacts = piStaticArtifacts;
}
);
piImageBaseModule =
{
lib,
nixos-raspberrypi,
@ -132,66 +167,72 @@
];
boot.kernelParams = lib.mkAfter [ "cfg80211.ieee80211_regdom=US" ];
networking.hostName = "noisebridge-pi";
networking.networkmanager.enable = lib.mkForce false;
networking.wireless = {
enable = true;
networks."Noisebridge".psk = "noisebridge";
};
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "prohibit-password";
};
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu"
];
};
flash-bootstrap-sd = pkgs.writeShellApplication {
name = "flash-bootstrap-sd";
flash-pi-sd = pkgs.writeShellApplication {
name = "flash-pi-sd";
runtimeInputs = [
agenix.packages.${system}.default
pkgs.coreutils
pkgs.nix
pkgs.parted
pkgs.systemd
pkgs.util-linux
pkgs.xz
pkgs.zstd
];
text = ''
set -euo pipefail
PARTPROBE=${pkgs.parted}/bin/partprobe
MOUNT=${pkgs.util-linux}/bin/mount
UMOUNT=${pkgs.util-linux}/bin/umount
MOUNTPOINT=${pkgs.util-linux}/bin/mountpoint
FINDMNT=${pkgs.util-linux}/bin/findmnt
UDEVADM=${pkgs.systemd}/bin/udevadm
if [ "$#" -ne 1 ]; then
echo "usage: flash-bootstrap-sd /dev/sdX" >&2
echo "usage: flash-pi-sd /dev/sdX" >&2
exit 1
fi
device="$1"
flake_path=${builtins.toString ./.}
zstd_bin=${pkgs.zstd}/bin/zstd
secrets_dir=${builtins.toString ./secrets}
rules_file=${builtins.toString ./secrets/secrets.nix}
key_name="bootstrap-identity.age"
boot_mount_dir="$(mktemp -d)"
cleanup() {
if "$MOUNTPOINT" -q "$boot_mount_dir"; then
sudo "$UMOUNT" "$boot_mount_dir"
fi
rm -rf "$boot_mount_dir"
}
trap cleanup EXIT
if [ ! -b "$device" ]; then
echo "not a block device: $device" >&2
exit 1
fi
boot_part="''${device}1"
case "$device" in
*[0-9]) boot_part="''${device}p1" ;;
esac
echo "Requesting sudo access before build and flash..."
sudo -v
echo "Sudo authentication successful."
echo "Building bootstrap NixOS Raspberry Pi Zero 2 W image..."
echo "Building full Pi NixOS image..."
image_out="$(nix build \
--print-out-paths \
--cores 0 \
--max-jobs auto \
"$flake_path#nixosConfigurations.bootstrap.config.system.build.sdImage")"
"$flake_path#nixosConfigurations.pi.config.system.build.sdImage")"
image="$(echo "$image_out"/sd-image/*.img*)"
if [ ! -f "$image" ]; then
@ -202,12 +243,30 @@
echo "Flashing $image to $device..."
if [ "''${image##*.}" = "zst" ]; then
"$zstd_bin" -d --stdout "$image" | sudo dd of="$device" bs=16M conv=fsync status=progress
elif [ "''${image##*.}" = "xz" ]; then
xz -d -c "$image" | sudo dd of="$device" bs=16M conv=fsync status=progress
else
sudo dd if="$image" of="$device" bs=16M conv=fsync status=progress
fi
sync
echo "Done. This is the custom bootstrap NixOS image."
sudo "$PARTPROBE" "$device"
sudo "$UDEVADM" settle
if "$FINDMNT" -rn "$boot_part" >/dev/null 2>&1; then
sudo "$UMOUNT" "$boot_part"
fi
echo "Installing bootstrap age identity onto $boot_part..."
sudo "$MOUNT" "$boot_part" "$boot_mount_dir"
(
cd "$secrets_dir"
RULES="$rules_file" agenix -d "$key_name"
) | sudo tee "$boot_mount_dir/noisebell-bootstrap.agekey" >/dev/null
sudo chmod 600 "$boot_mount_dir/noisebell-bootstrap.agekey"
sync
echo "Done. This is the full Pi NixOS image."
'';
};
@ -288,7 +347,7 @@
inherit
noisebell-cache
noisebell-discord
flash-bootstrap-sd
flash-pi-sd
pi-serial
;
default = noisebell-cache;
@ -296,6 +355,7 @@
packages.aarch64-linux = {
noisebell = noisebell-pi;
noisebell-static = noisebell-pi-static;
default = noisebell-pi;
};
@ -313,33 +373,26 @@
};
};
nixosConfigurations.pi = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
modules = [
agenix.nixosModules.default
nixos-hardware.nixosModules.raspberry-pi-3
(import ./pi/module.nix {
pkg = noisebell-pi;
rev = self.shortRev or "dirty";
})
./pi/configuration.nix
./pi/hardware-configuration.nix
];
};
nixosConfigurations.bootstrap = nixos-raspberrypi.lib.nixosSystem {
nixosConfigurations.pi = nixos-raspberrypi.lib.nixosSystem {
specialArgs = {
inherit nixos-raspberrypi;
};
modules = [
nixos-raspberrypi.nixosModules.sd-image
bootstrapModule
agenix.nixosModules.default
piImageBaseModule
(import ./pi/module.nix {
pkg = noisebell-pi;
rev = self.shortRev or "dirty";
})
./pi/configuration.nix
];
};
devShells.${system}.default = craneLib.devShell {
packages = [
flash-bootstrap-sd
agenix.packages.${system}.default
flash-pi-sd
pi-serial
pkgs.nix
pkgs.parted
@ -350,9 +403,9 @@
};
apps.${system} = {
flash-bootstrap-sd = {
flash-pi-sd = {
type = "app";
program = "${flash-bootstrap-sd}/bin/flash-bootstrap-sd";
program = "${flash-pi-sd}/bin/flash-pi-sd";
};
pi-serial = {