refactor: Use haumea for filesystem-based module system for flake outputs

refactor: Use hyphen(`-`) for variable names & folder names(except Python), replace all unserscore(`_`) with hyphen(`-`).
This commit is contained in:
Ryan Yin
2024-03-09 01:32:58 +08:00
parent d7738efed2
commit b382999a70
167 changed files with 1570 additions and 955 deletions

View File

@@ -0,0 +1,149 @@
# Suzu - Orange Pi 5
LUKS encrypted SSD for NixOS, on Orange Pi 5.
## Showcases
![](../../_img/2024-03-07_orangepi5_suzu.webp)
Disk layout:
```bash
[ryan@suzu:~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 58.6G 0 disk
└─sda1 8:1 1 486M 0 part
mtdblock0 31:0 0 16M 0 disk
zram0 254:0 0 0B 0 disk
nvme0n1 259:0 0 238.5G 0 disk
├─nvme0n1p1 259:1 0 630M 0 part /boot
└─nvme0n1p2 259:2 0 237.9G 0 part
└─crypted 253:0 0 237.8G 0 crypt /tmp
/snapshots
/swap
/home/ryan/tmp
/home/ryan/nix-config
/home/ryan/go
/home/ryan/.local/state
/home/ryan/codes
/home/ryan/.npm
/home/ryan/.ssh
/home/ryan/.local/share
/etc/ssh
/home/ryan/.conda
/etc/secureboot
/etc/agenix
/etc/nix/inputs
/etc/NetworkManager/system-connections
/nix/store
/var/log
/var/lib
/nix
/persistent
[ryan@suzu:~]$ df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 383M 0 383M 0% /dev
tmpfs tmpfs 3.8G 0 3.8G 0% /dev/shm
tmpfs tmpfs 1.9G 6.2M 1.9G 1% /run
tmpfs tmpfs 3.8G 1.9M 3.8G 1% /run/wrappers
none tmpfs 2.0G 48K 2.0G 1% /
/dev/mapper/crypted btrfs 238G 11G 226G 5% /persistent
/dev/mapper/crypted btrfs 238G 11G 226G 5% /nix
/dev/mapper/crypted btrfs 238G 11G 226G 5% /swap
/dev/mapper/crypted btrfs 238G 11G 226G 5% /snapshots
/dev/mapper/crypted btrfs 238G 11G 226G 5% /tmp
/dev/nvme0n1p1 vfat 629M 86M 543M 14% /boot
tmpfs tmpfs 766M 4.0K 766M 1% /run/user/1000
```
CPU info:
```bash
[ryan@suzu:~]$ lscpu
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Vendor ID: ARM
Model name: Cortex-A55
Model: 0
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Stepping: r2p0
CPU(s) scaling MHz: 56%
CPU max MHz: 1800.0000
CPU min MHz: 408.0000
BogoMIPS: 48.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
Model name: Cortex-A76
Model: 0
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 2
Stepping: r4p0
CPU(s) scaling MHz: 18%
CPU max MHz: 2256.0000
CPU min MHz: 408.0000
BogoMIPS: 48.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
Caches (sum of all):
L1d: 384 KiB (8 instances)
L1i: 384 KiB (8 instances)
L2: 2.5 MiB (8 instances)
L3: 3 MiB (1 instance)
```
## How to install NixOS on Orange Pi 5
### 1. Prepare a USB LUKS key
Generate LUKS keyfile to encrypt the root partition, it's used by disko.
```bash
# partition the usb stick
DEV=/dev/sdX
parted ${DEV} -- mklabel gpt
parted ${DEV} -- mkpart primary 2M 512MB
mkfs.fat -F 32 -n OPI5_DSC ${DEV}1
# Generate a keyfile from the true random number generator
KEYFILE=./orangepi5-luks-keyfile
dd bs=512 count=64 iflag=fullblock if=/dev/random of=$KEYFILE
# copy the keyfile and token to the usb stick
KEYFILE=./orangepi5-luks-keyfile
DEVICE=/dev/disk/by-label/OPI5_DSC
# seek=128 skip N obs-sized output blocks to avoid overwriting the filesystem header
dd bs=512 count=64 iflag=fullblock seek=128 if=$KEYFILE of=$DEVICE
```
### 2. Partition the SSD & install NixOS via disko
First, follow [UEFI - ryan4yin/nixos-rk3588](https://github.com/ryan4yin/nixos-rk3588/blob/main/UEFI.md) to install UEFI bootloader and boot into NixOS live environment via a USB stick.
Then, run the following commands:
```bash
# login via ssh
ssh rk@<ip-addr>
git clone https://github.com/ryan4yin/nix-config.git
cd ~/nix-config/hosts/12kingdoms_suzu
# 1. change the disk device path in ./disko-fs.nix to the disk you want to use
# 2. partition & format the disk via disko
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko ./disko-fs.nix
cd ~/nix-config
# install nixos
# NOTE: the root password you set here will be discarded when reboot
sudo nixos-install --root /mnt --flake .#suzu --no-root-password --show-trace --verbose
```

View File

@@ -0,0 +1,43 @@
{
disko,
nixos-rk3588,
myvars,
...
}:
#############################################################
#
# Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM
#
#############################################################
let
hostName = "suzu"; # Define your hostname.
hostAddress = myvars.networking.hostAddress.${hostName};
in {
imports = [
# import the rk3588 module, which contains the configuration for bootloader/kernel/firmware
nixos-rk3588.nixosModules.orangepi5plus.core
disko.nixosModules.default
./hardware-configuration.nix
./disko-fs.nix
./impermanence.nix
];
networking = {
inherit hostName;
inherit (myvars.networking) defaultGateway nameservers;
networkmanager.enable = false;
interfaces.end1 = {
useDHCP = false;
ipv4.addresses = [hostAddress];
};
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
}

View File

@@ -0,0 +1,102 @@
{
# required by impermanence
fileSystems."/persistent".neededForBoot = true;
disko.devices = {
nodev."/" = {
fsType = "tmpfs";
mountOptions = [
"size=2G"
"defaults"
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
# relatime: Update inode access times relative to modify or change time.
"mode=755"
];
};
# TODO: rename to main
disk.sda = {
type = "disk";
# When using disko-install, we will overwrite this value from the commandline
device = "/dev/nvme0n1"; # The device to partition
content = {
type = "gpt";
partitions = {
# The EFI & Boot partition
ESP = {
size = "630M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
# The root partition
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
settings = {
keyFile = "/dev/disk/by-label/OPI5_DSC"; # The keyfile is stored on a USB stick
# The maxium size of the keyfile is 8192 bytes
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
fallbackToPassword = true;
allowDiscards = true;
};
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
initrdUnlock = true;
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
# cryptsetup luksFormat
extraFormatArgs = [
"--type luks2"
"--cipher aes-xts-plain64"
"--hash sha512"
"--iter-time 5000"
"--key-size 256"
"--pbkdf argon2id"
# use true random data from /dev/random, will block until enough entropy is available
"--use-random"
];
extraOpenArgs = [
"--timeout 10"
];
content = {
type = "btrfs";
extraArgs = ["-f"];
subvolumes = {
"@nix" = {
mountpoint = "/nix";
mountOptions = ["compress-force=zstd:1" "noatime"];
};
"@persistent" = {
mountpoint = "/persistent";
mountOptions = ["compress-force=zstd:1" "noatime"];
};
"@tmp" = {
mountpoint = "/tmp";
mountOptions = ["compress-force=zstd:1" "noatime"];
};
"@snapshots" = {
mountpoint = "/snapshots";
mountOptions = ["compress-force=zstd:1" "noatime"];
};
"@swap" = {
mountpoint = "/swap";
swap.swapfile.size = "8192M";
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,39 @@
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.loader = {
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
efi.efiSysMountPoint = "/boot/";
efi.canTouchEfiVariables = true;
# do not use systemd-boot here, it has problems when running `nixos-install`
grub = {
device = "nodev";
efiSupport = true;
};
};
# clear /tmp on boot to get a stateless /tmp directory.
boot.tmp.cleanOnBoot = true;
boot.initrd.availableKernelModules = ["nvme" "usbhid" "usb_storage"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enP3p49s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View File

@@ -0,0 +1,75 @@
{
impermanence,
pkgs,
...
}: {
imports = [
impermanence.nixosModules.impermanence
];
environment.systemPackages = [
# `sudo ncdu -x /`
pkgs.ncdu
];
# There are two ways to clear the root filesystem on every boot:
## 1. use tmpfs for /
## 2. (btrfs/zfs only)take a blank snapshot of the root filesystem and revert to it on every boot via:
## boot.initrd.postDeviceCommands = ''
## mkdir -p /run/mymount
## mount -o subvol=/ /dev/disk/by-uuid/UUID /run/mymount
## btrfs subvolume delete /run/mymount
## btrfs subvolume snapshot / /run/mymount
## '';
#
# See also https://grahamc.com/blog/erase-your-darlings/
# NOTE: impermanence only mounts the directory/file list below to /persistent
# If the directory/file already exists in the root filesystem, you should
# move those files/directories to /persistent first!
environment.persistence."/persistent" = {
# sets the mount option x-gvfs-hide on all the bind mounts
# to hide them from the file manager
hideMounts = true;
directories = [
"/etc/NetworkManager/system-connections"
"/etc/ssh"
"/etc/nix/inputs"
"/etc/secureboot" # lanzaboote - secure boot
# my secrets
"/etc/agenix/"
"/var/log"
"/var/lib"
];
files = [
"/etc/machine-id"
];
# the following directories will be passed to /persistent/home/$USER
users.ryan = {
directories = [
"codes"
"nix-config"
"tmp"
{
directory = ".ssh";
mode = "0700";
}
# neovim / remmina / flatpak / ...
".local/share"
".local/state"
# language package managers
".npm"
".conda" # generated by `conda-shell`
"go"
];
files = [
".config/nushell/history.txt"
];
};
};
}