diff --git a/ops/nixos/default.nix b/ops/nixos/default.nix index 8a6d8db516..73f635da2b 100644 --- a/ops/nixos/default.nix +++ b/ops/nixos/default.nix @@ -46,6 +46,7 @@ let "bvm-logger" "bvm-paperless" "oracle-lon01" + "kerrigan" ]; rebuilder = system: (import ./lib/rebuilder.nix (args // { system = system; })); systemCfgs = lib.genAttrs systems diff --git a/ops/nixos/kerrigan/boot-builder.nix b/ops/nixos/kerrigan/boot-builder.nix new file mode 100644 index 0000000000..bad0c44ef1 --- /dev/null +++ b/ops/nixos/kerrigan/boot-builder.nix @@ -0,0 +1,8 @@ +{ substituteAll, coreutils, gnused, gnugrep, bash, ubootTools }: + +substituteAll { + src = ./boot-builder.sh; + isExecutable = true; + path = [coreutils gnused gnugrep ubootTools]; + inherit bash; +} diff --git a/ops/nixos/kerrigan/boot-builder.sh b/ops/nixos/kerrigan/boot-builder.sh new file mode 100755 index 0000000000..28e9d2387f --- /dev/null +++ b/ops/nixos/kerrigan/boot-builder.sh @@ -0,0 +1,110 @@ +#! @bash@/bin/sh -e + +shopt -s nullglob + +export PATH=/empty +for i in @path@; do PATH=$PATH:$i/bin; done + +usage() { + echo "usage: $0 -c [-d ] [-g ]" >&2 + exit 1 +} + +default= # Default configuration +target=/boot # Target directory +numGenerations=0 # Number of other generations to include in the menu + +while getopts "c:d:g:" opt; do + case "$opt" in + c) default="$OPTARG" ;; + d) target="$OPTARG" ;; + g) numGenerations="$OPTARG" ;; + \?) usage ;; + esac +done + +[ "$default" = "" ] && usage + +mkdir -p $target/nixos + +# Convert a path to a file in the Nix store such as +# /nix/store/-/file to --. +cleanName() { + local path="$1" + echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g' +} + +# Copy a file from the Nix store to $target/nixos. +declare -A filesCopied + +copyToKernelsDir() { + local src=$(readlink -f "$1") + local dst="$target/nixos/$(cleanName $src)" + # Don't copy the file if $dst already exists. This means that we + # have to create $dst atomically to prevent partially copied + # kernels or initrd if this script is ever interrupted. + if ! test -e $dst; then + local dstTmp=$dst.tmp.$$ + cp -r $src $dstTmp + mv $dstTmp $dst + fi + filesCopied[$dst]=1 + result=$dst +} + +# Copy its kernel, initrd and dtbs to $target/nixos, and echo out an +# extlinux menu entry +addEntry() { + local path=$(readlink -f "$1") + local tag="$2" # Generation number or 'default' + + if ! test -e $path/kernel -a -e $path/initrd; then + return + fi + + copyToKernelsDir "$path/kernel"; kernel=$result + copyToKernelsDir "$path/initrd"; initrd=$result + dtbDir=$(readlink -m "$path/dtbs") + if [ -e "$dtbDir" ]; then + copyToKernelsDir "$dtbDir"; dtbs=$result + fi + + timestampEpoch=$(stat -L -c '%Z' $path) + + timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) + nixosLabel="$(cat $path/nixos-version)" + extraParams="$(cat $path/kernel-params)" + + filesCopied[$target/nixos/$tag]=1 + echo > $target/nixos/$tag.tmp + echo "ext4load usb 0:2 \$kernel_addr_r boot/nixos/$(basename $kernel)" >> $target/nixos/$tag.tmp + echo "ext4load usb 0:2 \$fdt_addr_r boot/nixos/$(basename $dtbs)/marvell/armada-7040-mochabin.dtb" >> $target/nixos/$tag.tmp + echo "ext4load usb 0:2 0xa700000 boot/nixos/$(basename $initrd)" >> $target/nixos/$tag.tmp + echo "setenv bootargs \$console init=$path/init $extraParams" >> $target/nixos/$tag.tmp + echo "booti \$kernel_addr_r 0xa700000:\$filesize \$fdt_addr_r" >> $target/nixos/$tag.tmp + mkimage -A arm64 -O u-boot -T script -C none -a 0 -e 0 -n "Boot Script ${nixosLabel} ${timestamp}" -d $target/nixos/$tag.tmp $target/nixos/$tag +} + +addEntry $default default + +if [ "$numGenerations" -gt 0 ]; then + # Add up to $numGenerations generations of the system profile to the menu, + # in reverse (most recent to least recent) order. + for generation in $( + (cd /nix/var/nix/profiles && ls -d system-*-link) \ + | sed 's/system-\([0-9]\+\)-link/\1/' \ + | sort -n -r \ + | head -n $numGenerations); do + link=/nix/var/nix/profiles/system-$generation-link + addEntry $link $generation + done +fi + +# Remove obsolete files from $target/nixos. +for fn in $target/nixos/*; do + if ! test "${filesCopied[$fn]}" = 1; then + echo "Removing no longer needed boot file: $fn" + chmod +w -- "$fn" + rm -rf -- "$fn" + fi +done diff --git a/ops/nixos/kerrigan/default.nix b/ops/nixos/kerrigan/default.nix new file mode 100644 index 0000000000..75c8f9d35c --- /dev/null +++ b/ops/nixos/kerrigan/default.nix @@ -0,0 +1,79 @@ +# SPDX-FileCopyrightText: 2023 Luke Granger-Brown +# +# SPDX-License-Identifier: Apache-2.0 + +{ depot, lib, pkgs, config, modulesPath, ... }: + +let + nmFiles = builtins.attrNames (lib.filterAttrs (n: v: v == "regular" && lib.hasSuffix ".nmconnection" n) (builtins.readDir ./networkmanager)); + nmBits = lib.mkMerge (map (filename: { + "NetworkManager/system-connections/${filename}" = { + source = ./networkmanager + "/${filename}"; + mode = "0600"; + }; + }) nmFiles); + + boot-builder = pkgs.callPackage ./boot-builder.nix { }; + populate-boot-builder = pkgs.buildPackages.callPackage ./boot-builder.nix { }; +in +{ + imports = [ + "${modulesPath}/installer/sd-card/sd-image.nix" + ]; + + fileSystems = { + "/" = { device = "/dev/disk/by-label/NIXOS_SD"; fsType = "ext4"; }; + "/boot/firmware" = { device = "/dev/disk/by-label/FIRMWARE"; fsType = "vfat"; }; + }; + + boot.kernelPackages = pkgs.linuxPackages_latest; + boot.kernelParams = [ "console=ttyS0,115200n8" ]; + boot.initrd.kernelModules = [ "phy-mvebu-cp110-utmi" ]; + + networking = { + hostName = "kerrigan"; + domain = "as205479.net"; + hostId = "c424eeb8"; + useNetworkd = true; + networkmanager = { + enable = true; + dns = "systemd-resolved"; + unmanaged = [ "eth1" "eth2" ]; + extraConfig = '' + [main] + no-auto-default=* + + [logging] + level=TRACE + domains=ALL + ''; + }; + nameservers = [ + "2001:4860:4860::8888" + "2001:4860:4860::8844" + "8.8.8.8" + "8.8.4.4" + ]; + interfaces.eth2.useDHCP = true; + }; + users.users.lukegb.extraGroups = lib.mkAfter [ "networkmanager" ]; + my.systemType = "aarch64-linux"; + + systemd.services.ModemManager = { + wantedBy = [ "network.target" ]; + }; + environment.etc = nmBits; + + sdImage.populateFirmwareCommands = lib.mkForce ""; + + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = lib.mkForce false; + boot.consoleLogLevel = lib.mkDefault 7; + system.build.installBootLoader = "${boot-builder} -g 10 -c"; + sdImage.populateRootCommands = lib.mkAfter '' + mkdir -p ./files/boot + ${populate-boot-builder} -c ${config.system.build.toplevel} -d ./files/boot + ''; + + system.stateVersion = "23.05"; +} diff --git a/ops/nixos/kerrigan/networkmanager/EE.nmconnection b/ops/nixos/kerrigan/networkmanager/EE.nmconnection new file mode 100644 index 0000000000..a985ddfec9 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/EE.nmconnection @@ -0,0 +1,16 @@ +[connection] +id=EE +uuid=f4c3ad45-d4a3-44ee-b29f-af10b5974d22 +type=gsm + +[gsm] +apn=everywhere + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/ops/nixos/kerrigan/networkmanager/bridge-br0.nmconnection b/ops/nixos/kerrigan/networkmanager/bridge-br0.nmconnection new file mode 100644 index 0000000000..9de486bf17 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/bridge-br0.nmconnection @@ -0,0 +1,19 @@ +[connection] +id=bridge-br0 +uuid=bb1df01a-67f4-44f6-99b7-a94a8d91c00e +type=bridge +interface-name=br0 + +[ethernet] + +[bridge] +forward-delay=3 + +[ipv4] +method=shared + +[ipv6] +addr-gen-mode=default +method=shared + +[proxy] diff --git a/ops/nixos/kerrigan/networkmanager/bridge-slave-lan0.nmconnection b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan0.nmconnection new file mode 100644 index 0000000000..af85522b10 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan0.nmconnection @@ -0,0 +1,11 @@ +[connection] +id=bridge-slave-lan0 +uuid=a9bee559-325f-4ac4-9c02-b129d08b0c03 +type=ethernet +interface-name=lan0 +master=br0 +slave-type=bridge + +[ethernet] + +[bridge-port] diff --git a/ops/nixos/kerrigan/networkmanager/bridge-slave-lan1.nmconnection b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan1.nmconnection new file mode 100644 index 0000000000..d5f8287ee5 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan1.nmconnection @@ -0,0 +1,11 @@ +[connection] +id=bridge-slave-lan1 +uuid=a1d80f6a-a7c8-4888-911f-82041324ab84 +type=ethernet +interface-name=lan1 +master=br0 +slave-type=bridge + +[ethernet] + +[bridge-port] diff --git a/ops/nixos/kerrigan/networkmanager/bridge-slave-lan2.nmconnection b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan2.nmconnection new file mode 100644 index 0000000000..31c8120a42 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan2.nmconnection @@ -0,0 +1,11 @@ +[connection] +id=bridge-slave-lan2 +uuid=99e29121-71a4-40d1-886f-fa10410a4897 +type=ethernet +interface-name=lan2 +master=br0 +slave-type=bridge + +[ethernet] + +[bridge-port] diff --git a/ops/nixos/kerrigan/networkmanager/bridge-slave-lan3.nmconnection b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan3.nmconnection new file mode 100644 index 0000000000..7e92858778 --- /dev/null +++ b/ops/nixos/kerrigan/networkmanager/bridge-slave-lan3.nmconnection @@ -0,0 +1,11 @@ +[connection] +id=bridge-slave-lan3 +uuid=8943379a-dc7a-453d-a16a-6be42e842f2c +type=ethernet +interface-name=lan3 +master=br0 +slave-type=bridge + +[ethernet] + +[bridge-port] diff --git a/ops/nixos/porcorosso/default.nix b/ops/nixos/porcorosso/default.nix index 88e6ada0da..c665ccabeb 100644 --- a/ops/nixos/porcorosso/default.nix +++ b/ops/nixos/porcorosso/default.nix @@ -357,6 +357,8 @@ in { enable = true; }; + boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; + # This value determines the NixOS release with which your system is to be # compatible, in order to avoid breaking some software such as database # servers. You should change this only after NixOS release notes say you diff --git a/ops/nixos/totoro/default.nix b/ops/nixos/totoro/default.nix index d9515a8ffb..821a0e9b6f 100644 --- a/ops/nixos/totoro/default.nix +++ b/ops/nixos/totoro/default.nix @@ -578,5 +578,7 @@ in { "invoices.lukegb.com" = { hostnames = [ "invoices.lukegb.com" ]; nginxVirtualHosts = [ "invoices.lukegb.com" ]; }; }; + boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; + system.stateVersion = "22.11"; }