Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions arm/nix-os-raspberrypi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# arm/nix-os-raspberrypi/Makefile
#

# Fake targets
.PHONY: rpi2 rpi4 rpi4

all: rp5

rpi2:
nix build .#installerImages.rpi02

rp4:
nix build .#installerImages.rpi4

rp5:
nix build .#installerImages.rpi5

rp5_on_amd64:
sudo nix build .#nixosConfigurations.rpi5.config.system.build.sdImage --system aarch64-linux

update:
sudo nix flake update;

sync:
rsync -avz ./ 172.16.40.122:/home/das/nixos/arm/nix-os-raspberrypi/

# end
181 changes: 181 additions & 0 deletions arm/nix-os-raspberrypi/disko-nvme-zfs.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
{ config, lib, ... }:

let
firmwarePartition = lib.recursiveUpdate {
# label = "FIRMWARE";
priority = 1;

type = "0700"; # Microsoft basic data
attributes = [
0 # Required Partition
];

size = "1024M";
content = {
type = "filesystem";
format = "vfat";
# mountpoint = "/boot/firmware";
mountOptions = [
"noatime"
"noauto"
"x-systemd.automount"
"x-systemd.idle-timeout=1min"
];
};
};

espPartition = lib.recursiveUpdate {
# label = "ESP";

type = "EF00"; # EFI System Partition (ESP)
attributes = [
2 # Legacy BIOS Bootable, for U-Boot to find extlinux config
];

size = "1024M";
content = {
type = "filesystem";
format = "vfat";
# mountpoint = "/boot";
mountOptions = [
"noatime"
"noauto"
"x-systemd.automount"
"x-systemd.idle-timeout=1min"
"umask=0077"
];
};
};

in {

boot.supportedFilesystems = [ "zfs" ];
# networking.hostId is set somewhere else
services.zfs.autoScrub.enable = true;
services.zfs.trim.enable = true;

disko.devices = {
disk.nvme0 = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {

FIRMWARE = firmwarePartition {
label = "FIRMWARE";
content.mountpoint = "/boot/firmware";
};

ESP = espPartition {
label = "ESP";
content.mountpoint = "/boot";
};

zfs = {
size = "100%";
content = {
type = "zfs";
pool = "rpool"; # zroot
};
};

};
};
}; #nvme0

zpool = {
rpool = {
type = "zpool";

# zpool properties
options = {
ashift = "12";
autotrim = "on"; # see also services.zfs.trim.enable
};

# zfs properties
rootFsOptions = {
# "com.sun:auto-snapshot" = "false";
# https://jrs-s.net/2018/08/17/zfs-tuning-cheat-sheet/
compression = "lz4";
atime = "off";
xattr = "sa";
acltype = "posixacl";
# https://rubenerd.com/forgetting-to-set-utf-normalisation-on-a-zfs-pool/
normalization = "formD";
dnodesize = "auto";
mountpoint = "none";
canmount = "off";
};

postCreateHook = let
poolName = "rpool";
in "zfs list -t snapshot -H -o name | grep -E '^${poolName}@blank$' || zfs snapshot ${poolName}@blank";

datasets = {

# stuff which can be recomputed/easily redownloaded, e.g. nix store
local = {
type = "zfs_fs";
options.mountpoint = "none";
};
"local/nix" = {
type = "zfs_fs";
options = {
reservation = "128M";
mountpoint = "legacy"; # to manage "with traditional tools"
};
mountpoint = "/nix"; # nixos configuration mountpoint
};

# _system_ data
system = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"system/root" = {
type = "zfs_fs";
options = {
mountpoint = "legacy";
};
mountpoint = "/";
};
"system/var" = {
type = "zfs_fs";
options = {
mountpoint = "legacy";
};
mountpoint = "/var";
};

# _user_ and _user service_ data. safest, long retention policy
safe = {
type = "zfs_fs";
options = {
copies = "2";
mountpoint = "none";
};
};
"safe/home" = {
type = "zfs_fs";
options = {
mountpoint = "legacy";
};
mountpoint = "/home";
};
"safe/var/lib" = {
type = "zfs_fs";
options = {
mountpoint = "legacy";
};
mountpoint = "/var/lib";
};

};
};
};
};
}
167 changes: 167 additions & 0 deletions arm/nix-os-raspberrypi/disko-usb-btrfs.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
{ config, lib, ... }:

let
firmwarePartition = lib.recursiveUpdate {
# label = "FIRMWARE";
priority = 1;

type = "0700"; # Microsoft basic data
attributes = [
0 # Required Partition
];

size = "1024M";
content = {
type = "filesystem";
format = "vfat";
# mountpoint = "/boot/firmware";
mountOptions = [
"noatime"
"noauto"
"x-systemd.automount"
"x-systemd.idle-timeout=1min"
];
};
};

espPartition = lib.recursiveUpdate {
# label = "ESP";

type = "EF00"; # EFI System Partition (ESP)
attributes = [
2 # Legacy BIOS Bootable, for U-Boot to find extlinux config
];

size = "1024M";
content = {
type = "filesystem";
format = "vfat";
# mountpoint = "/boot";
mountOptions = [
"noatime"
"noauto"
"x-systemd.automount"
"x-systemd.idle-timeout=1min"
"umask=0077"
];
};
};

in {

# https://nixos.wiki/wiki/Btrfs#Scrubbing
services.btrfs.autoScrub = {
enable = true;
interval = "monthly";
fileSystems = [ "/" ];
};

fileSystems = {
# mount early enough in the boot process so no logs will be lost
"/var/log".neededForBoot = true;
};

disko.devices.disk.main = {
type = "disk";
device = "/dev/sda";

content = {
type = "gpt";
partitions = {

FIRMWARE = firmwarePartition {
label = "FIRMWARE";
content.mountpoint = "/boot/firmware";
};

ESP = espPartition {
label = "ESP";
content.mountpoint = "/boot";
};

system = {
type = "8305"; # Linux ARM64 root (/)

size = "100%";
content = {
type = "btrfs";
extraArgs = [
# "--label nixos"
"-f" # Override existing partition
];
postCreateHook = let
thisBtrfs = config.disko.devices.disk.main.content.partitions.system.content;
device = thisBtrfs.device;
subvolumes = thisBtrfs.subvolumes;

makeBlankSnapshot = btrfsMntPoint: subvol: let
subvolAbsPath = lib.strings.normalizePath "${btrfsMntPoint}/${subvol.name}";
dst = "${subvolAbsPath}-blank";
# NOTE: this one-liner has the same functionality (inspired by zfs hook)
# btrfs subvolume list -s mnt/rootfs | grep -E ' rootfs-blank$' || btrfs subvolume snapshot -r mnt/rootfs mnt/rootfs-blank
in ''
if ! btrfs subvolume show "${dst}" > /dev/null 2>&1; then
btrfs subvolume snapshot -r "${subvolAbsPath}" "${dst}"
fi
'';
# Mount top-level subvolume (/) with "subvol=/", without it
# the default subvolume will be mounted. They're the same in
# this case, though. So "subvol=/" isn't really necessary
in ''
MNTPOINT=$(mktemp -d)
mount ${device} "$MNTPOINT" -o subvol=/
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
${makeBlankSnapshot "$MNTPOINT" subvolumes."/rootfs"}
'';
subvolumes = {
"/rootfs" = {
mountpoint = "/";
mountOptions = [ "noatime" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "noatime" ];
};
"/home" = {
mountpoint = "/home";
mountOptions = [ "noatime" ];
};
"/log" = {
mountpoint = "/var/log";
mountOptions = [ "noatime" ];
};
"/swap" = {
mountpoint = "/.swapvol";
swap."swapfile" = {
size = "8G";
priority = 3; # (higher number -> higher priority)
# to be used after zswap (set zramSwap.priority > this priority),
# but before "hibernation" swap
# https://github.com/nix-community/disko/issues/651
};
};
};
};
}; # system

swap = {
type = "8200"; # Linux swap

size = "9G"; # RAM + 1GB
content = {
type = "swap";
resumeDevice = true; # "hibernation" swap
# zram's swap will be used first, and this one only
# used when the system is under pressure enough that zram and
# "regular" swap above didn't work
# https://github.com/systemd/systemd/issues/16708#issuecomment-1632592375
# (set zramSwap.priority > btrfs' .swapvol priority > this priority)
priority = 2;
};
};

};
};

}; # disko.devices.disk.main
}
Loading