Compare commits
60
Commits
openzfs-guide
...
custom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e57c016891 | ||
|
|
4a1cc42ea8 | ||
|
|
62c4a4eb3a | ||
|
|
9ef9a4b248 | ||
|
|
cc29b97421 | ||
|
|
f9f3e89f87 | ||
|
|
53b9aee230 | ||
|
|
3e46ee3a7d | ||
|
|
c5a68ae77d | ||
|
|
32b2405a2d | ||
|
|
675f163e62 | ||
|
|
5a2a2dcc07 | ||
|
|
10b5fe70d7 | ||
|
|
dc574712f4 | ||
|
|
a881642d0d | ||
|
|
327b58fbed | ||
|
|
c564c50e36 | ||
|
|
0d17d8316a | ||
|
|
450f5fff16 | ||
|
|
d8577a8938 | ||
|
|
aced56e287 | ||
|
|
0ad37939f6 | ||
|
|
76ce1aa6b6 | ||
|
|
796fc7930c | ||
|
|
ca11c1770b | ||
|
|
3ba50bb195 | ||
|
|
9428bb3263 | ||
|
|
54c95c7a6f | ||
|
|
0733ee3106 | ||
|
|
7f438f4451 | ||
|
|
5abb237b6c | ||
|
|
ab10481652 | ||
|
|
4d6c98e75b | ||
|
|
efb53cd066 | ||
|
|
dafd939d12 | ||
|
|
bcaa17d9d2 | ||
|
|
165bbdf8d3 | ||
|
|
cd180ce627 | ||
|
|
7278b18607 | ||
|
|
92b956fb1c | ||
|
|
ae8fa6e247 | ||
|
|
367e9c0e3e | ||
|
|
e7bf496f7a | ||
|
|
4b6997de33 | ||
|
|
c00627a811 | ||
|
|
a370b53f1d | ||
|
|
e1aa52a77e | ||
|
|
7b89415746 | ||
|
|
903a969d76 | ||
|
|
7a1de01ef3 | ||
|
|
8068bb1d81 | ||
|
|
f7e9f335e4 | ||
|
|
5580032733 | ||
|
|
1cd6bd6cfc | ||
|
|
58606b8306 | ||
|
|
4605a97544 | ||
|
|
c798df9b55 | ||
|
|
5a168dab3e | ||
|
|
04260a676b | ||
|
|
131f3820dd |
+10
@@ -0,0 +1,10 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk update
|
||||
RUN apk add mkpasswd zfs
|
||||
|
||||
COPY LICENSE configuration.nix flake.lock flake.nix install.sh ./
|
||||
COPY hosts ./
|
||||
COPY modules ./
|
||||
|
||||
ENTRYPOINT [ "./install.sh" ]
|
||||
+15
-21
@@ -1,24 +1,18 @@
|
||||
* Minimal NixOS Root on ZFS configuration
|
||||
This repo contains a minimal set of configuration needed for
|
||||
installing NixOS on a computer with ZFS as root filesystem.
|
||||
* Install NixOS with ZFS as root filesystem
|
||||
This repo contains a minimal set of configuration for installing
|
||||
NixOS, using ZFS as root filesystem.
|
||||
|
||||
#+begin_src text
|
||||
.gitignore
|
||||
LICENSE
|
||||
configuration.nix <- configuration shared by all hosts
|
||||
flake.lock
|
||||
flake.nix
|
||||
hosts/exampleHost/default.nix <- per-host configuration
|
||||
hosts/exampleHost/sshUnlock.txt
|
||||
modules/boot/default.nix
|
||||
modules/default.nix
|
||||
modules/fileSystems/default.nix
|
||||
modules/networking/default.nix
|
||||
modules/users/default.nix
|
||||
#+end_src
|
||||
ZFS is a modern filesystem with many features such as snapshot,
|
||||
self-healing and pooled storage, see [[https://openzfs.org/wiki/Main_Page#Introduction_to_OpenZFS][Introduction]] for details.
|
||||
|
||||
Just enough to get you started.
|
||||
For using this repo on your computer, see [[https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html][Documentation]].
|
||||
|
||||
See [[https://github.com/ne9z/personal-dotfiles][my personal dotfiles repo]] for an example of how to configure
|
||||
servers and desktop computers in the same git repository, based on
|
||||
this template repo you are viewing now.
|
||||
Upon initial installation, only the bootloader, mountpoints and root
|
||||
password are configured.
|
||||
|
||||
- Refer to =man configuration.nix= for available options;
|
||||
- Search for available packages with [[https://search.nixos.org/packages][Package Search]];
|
||||
- Search for options with [[https://search.nixos.org/options][Option Search]].
|
||||
|
||||
[[https://codeberg.org/m0p/dotfiles][My personal dotfiles repo]] contains an example of desktop configuration
|
||||
based on sway, tmux and Emacs.
|
||||
|
||||
+54
-23
@@ -1,16 +1,8 @@
|
||||
{ my-config, zfs-root, inputs, pkgs, lib, ... }: {
|
||||
# load module config to top-level configuration
|
||||
inherit my-config zfs-root;
|
||||
|
||||
# Let 'nixos-version --json' know about the Git revision
|
||||
# of this flake.
|
||||
system.configurationRevision = if (inputs.self ? rev) then
|
||||
inputs.self.rev
|
||||
else
|
||||
throw "refuse to build: git tree is dirty";
|
||||
|
||||
system.stateVersion = "22.11";
|
||||
# configuration in this file is shared by all hosts
|
||||
|
||||
{ pkgs, pkgs-unstable, inputs, ... }:
|
||||
let inherit (inputs) self;
|
||||
in {
|
||||
# Enable NetworkManager for wireless networking,
|
||||
# You can configure networking with "nmtui" command.
|
||||
networking.useDHCP = true;
|
||||
@@ -23,31 +15,48 @@
|
||||
};
|
||||
};
|
||||
|
||||
## enable GNOME desktop.
|
||||
## You need to configure a normal, non-root user.
|
||||
# services.xserver = {
|
||||
# enable = true;
|
||||
# desktopManager.gnome.enable = true;
|
||||
# displayManager.gdm.enable = true;
|
||||
# };
|
||||
|
||||
## enable ZFS auto snapshot on datasets
|
||||
## You need to set the auto snapshot property to "true"
|
||||
## on datasets for this to work, such as
|
||||
# zfs set com.sun:auto-snapshot=true rpool/nixos/home
|
||||
services.zfs = {
|
||||
autoSnapshot = {
|
||||
enable = false;
|
||||
flags = "-k -p --utc";
|
||||
monthly = 48;
|
||||
};
|
||||
};
|
||||
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
};
|
||||
|
||||
imports = [
|
||||
"${inputs.nixpkgs}/nixos/modules/installer/scan/not-detected.nix"
|
||||
# "${inputs.nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
|
||||
];
|
||||
|
||||
services.openssh = {
|
||||
enable = lib.mkDefault true;
|
||||
settings = { PasswordAuthentication = lib.mkDefault false; };
|
||||
enable = true;
|
||||
settings = { PasswordAuthentication = false; };
|
||||
};
|
||||
|
||||
boot.zfs.forceImportRoot = lib.mkDefault false;
|
||||
boot.zfs.forceImportRoot = false;
|
||||
|
||||
nix.settings.experimental-features = lib.mkDefault [ "nix-command" "flakes" ];
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
boot.initrd.systemd.enable = true;
|
||||
|
||||
programs.git.enable = true;
|
||||
|
||||
security = {
|
||||
doas.enable = lib.mkDefault true;
|
||||
sudo.enable = lib.mkDefault false;
|
||||
doas.enable = true;
|
||||
sudo.enable = false;
|
||||
};
|
||||
|
||||
environment.systemPackages = builtins.attrValues {
|
||||
@@ -55,5 +64,27 @@
|
||||
mg # emacs-like editor
|
||||
jq # other programs
|
||||
;
|
||||
# By default, the system will only use packages from the
|
||||
# stable channel. i.e.
|
||||
# inherit (pkg) my-favorite-stable-package;
|
||||
# You can selectively install packages
|
||||
# from the unstable channel. Such as
|
||||
# inherit (pkgs-unstable) my-favorite-unstable-package;
|
||||
# You can also add more
|
||||
# channels to pin package version.
|
||||
};
|
||||
|
||||
# Safety mechanism: refuse to build unless everything is
|
||||
# tracked by git
|
||||
system.configurationRevision = if (self ? rev) then
|
||||
self.rev
|
||||
else
|
||||
throw "refuse to build: git tree is dirty";
|
||||
|
||||
system.stateVersion = "23.05";
|
||||
|
||||
# let nix commands follow system nixpkgs revision
|
||||
nix.registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
# you can then test any package in a nix shell, such as
|
||||
# $ nix shell nixpkgs#neovim
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
nixos-zfs-installer:
|
||||
image: marcpartensky/nixos-zfs-installer
|
||||
build: .
|
||||
Generated
+47
-10
@@ -1,24 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1685533922,
|
||||
"narHash": "sha256-y4FCQpYafMQ42l1V+NUrMel9RtFtZo59PzdzflKR/lo=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3a70dd92993182f8e514700ccf5b1ae9fc8a3b8d",
|
||||
"lastModified": 1695108154,
|
||||
"narHash": "sha256-gSg7UTVtls2yO9lKtP0yb66XBHT1Fx5qZSZbGMpSn2c=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "07682fff75d41f18327a871088d20af2710d4744",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-23.05",
|
||||
"repo": "nixpkgs",
|
||||
"owner": "nix-community",
|
||||
"ref": "release-23.05",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1696983906,
|
||||
"narHash": "sha256-L7GyeErguS7Pg4h8nK0wGlcUTbfUMDu+HMf1UcyP72k=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bd1cde45c77891214131cbbea5b1203e485a9d51",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-23.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1697349934,
|
||||
"narHash": "sha256-mSOXTIvCMA31nD/XEYmeSOebrXl0lFKirM14LK845e4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f320b0d46ee33f521f50d7c6885605714210e5c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "master",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"home-manager": "home-manager",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,27 +1,61 @@
|
||||
{
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
|
||||
## after reboot, you can track rolling release by using
|
||||
#inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
description = "Barebones NixOS on ZFS config";
|
||||
|
||||
outputs = { self, nixpkgs }@inputs:
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-23.05";
|
||||
nixpkgs-unstable.url = "nixpkgs/master";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-23.05";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager }@inputs:
|
||||
let
|
||||
lib = nixpkgs.lib;
|
||||
mkHost = { my-config, zfs-root, pkgs, system, ... }:
|
||||
lib.nixosSystem {
|
||||
inherit system;
|
||||
mkHost = hostName: system:
|
||||
nixpkgs.lib.nixosSystem {
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
# settings to nixpkgs goes to here
|
||||
# nixpkgs.pkgs.zathura.useMupdf = true;
|
||||
# nixpkgs.config.allowUnfree = false;
|
||||
};
|
||||
|
||||
specialArgs = {
|
||||
# By default, the system will only use packages from the
|
||||
# stable channel. You can selectively install packages
|
||||
# from the unstable channel. You can also add more
|
||||
# channels to pin package version.
|
||||
pkgs-unstable = import nixpkgs-unstable {
|
||||
inherit system;
|
||||
# settings to nixpkgs-unstable goes to here
|
||||
};
|
||||
|
||||
# make all inputs availabe in other nix files
|
||||
inherit inputs;
|
||||
};
|
||||
|
||||
modules = [
|
||||
# Root on ZFS related configuration
|
||||
./modules
|
||||
(import ./configuration.nix {
|
||||
inherit my-config zfs-root inputs pkgs lib;
|
||||
})
|
||||
|
||||
# Configuration shared by all hosts
|
||||
./configuration.nix
|
||||
|
||||
# Configuration per host
|
||||
./hosts/${hostName}
|
||||
|
||||
# home-manager
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
in {
|
||||
nixosConfigurations = {
|
||||
exampleHost = let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in mkHost (import ./hosts/exampleHost { inherit system pkgs; });
|
||||
laptop = mkHost "laptop" "x86_64-linux";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
How to set hostname for a host.
|
||||
|
||||
This repo is structured in a way that allows managing multiple hosts
|
||||
in a single repo. As a consequence of this, hostname appears in
|
||||
several different places and should be updated together if needed.
|
||||
|
||||
The entry point of this repo is ``flake.nix'' file, which takes a
|
||||
revision of the nixpkgs as input then gives an attribute set (attrset)
|
||||
as output:
|
||||
|
||||
{
|
||||
nixosConfigurations = {
|
||||
exampleHost = { ... };
|
||||
host2 = { ... };
|
||||
host3 = { ... };
|
||||
...
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
The hostname specified here inside nixosConfigurations attrset is used
|
||||
when ``nix command'' is invoked, as in
|
||||
|
||||
nixos-install --flake ./#exampleHost
|
||||
|
||||
The hostname also appears in the filesystem path of the per-host
|
||||
configuration file:
|
||||
|
||||
hosts/exampleHost/default.nix
|
||||
hosts/host2/default.nix
|
||||
...
|
||||
|
||||
Finally, the hostname is specified in the zfs-boot.networking.hostName
|
||||
option inside per-host configuration file at
|
||||
hosts/exampleHost/default.nix:
|
||||
|
||||
zfs-boot.networking.hostName = "exampleHost";
|
||||
|
||||
If the value of this option is identical to the name of
|
||||
nixosConfigurations.<hostname> attrset, all subsequent invocations of
|
||||
``nix command'' will default to this hostname, i.e. the command:
|
||||
|
||||
nixos-rebuild boot
|
||||
|
||||
will automatically append ``#hostName'' when evaluating the flake.
|
||||
@@ -1,37 +0,0 @@
|
||||
# #
|
||||
##
|
||||
## per-host configuration for exampleHost
|
||||
##
|
||||
##
|
||||
|
||||
{ system, pkgs, ... }: {
|
||||
inherit pkgs system;
|
||||
zfs-root = {
|
||||
boot = {
|
||||
devNodes = "/dev/disk/by-id/";
|
||||
bootDevices = [ "bootDevices_placeholder" ];
|
||||
immutable = false;
|
||||
availableKernelModules = [ "kernelModules_placeholder" ];
|
||||
removableEfi = true;
|
||||
kernelParams = [ ];
|
||||
sshUnlock = {
|
||||
# read sshUnlock.txt file.
|
||||
enable = false;
|
||||
authorizedKeys = [ ];
|
||||
};
|
||||
};
|
||||
networking = {
|
||||
# read changeHostName.txt file.
|
||||
hostName = "exampleHost";
|
||||
timeZone = "Europe/Berlin";
|
||||
hostId = "abcd1234";
|
||||
};
|
||||
};
|
||||
|
||||
# To add more options to per-host configuration, you can create a
|
||||
# custom configuration module, then add it here.
|
||||
my-config = {
|
||||
# Enable custom gnome desktop on exampleHost
|
||||
template.desktop.gnome.enable = false;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
How to set hostname for a host.
|
||||
|
||||
You need to change the host name in three different places.
|
||||
|
||||
Place 1.
|
||||
|
||||
./flake.nix
|
||||
|
||||
Change
|
||||
|
||||
exampleHost = mkHost "exampleHost" "x86_64-linux";
|
||||
|
||||
to
|
||||
|
||||
myHost = mkHost "myHost" "x86_64-linux";
|
||||
|
||||
Place 2.
|
||||
|
||||
Move directory
|
||||
|
||||
./hosts/exampleHost
|
||||
|
||||
to
|
||||
|
||||
./hosts/myHost
|
||||
|
||||
Place 3.
|
||||
|
||||
./hosts/exampleHost/default.nix
|
||||
|
||||
Change
|
||||
|
||||
networking.hostName = "exampleHost";
|
||||
|
||||
to
|
||||
|
||||
networking.hostName = "myHost";
|
||||
|
||||
End.
|
||||
@@ -0,0 +1,24 @@
|
||||
{ config, pkgs, lib, inputs, modulesPath, ... }: {
|
||||
zfs-root = {
|
||||
boot = {
|
||||
devNodes = "/dev/disk/by-id/";
|
||||
bootDevices = [ "bootDevices_placeholder" ];
|
||||
immutable.enable = false;
|
||||
removableEfi = true;
|
||||
luks.enable = True;
|
||||
};
|
||||
};
|
||||
boot.initrd.availableKernelModules = [ "kernelModules_placeholder" ];
|
||||
boot.kernelParams = [ ];
|
||||
networking.hostId = "nixos";
|
||||
# read changeHostName.txt file.
|
||||
networking.hostName = "laptop";
|
||||
time.timeZone = "Europe/Paris";
|
||||
|
||||
# import preconfigured profiles
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
# (modulesPath + "/profiles/hardened.nix")
|
||||
# (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
}
|
||||
Executable
+272
@@ -0,0 +1,272 @@
|
||||
#!/bin/env bash
|
||||
|
||||
log() { echo -e "\n\033[1m${@}\033[0m"; }
|
||||
|
||||
log Checking root
|
||||
mustberoot() {
|
||||
log You must be root
|
||||
exit 1
|
||||
}
|
||||
whoami | grep root || mustberoot
|
||||
|
||||
log Checking connectivity
|
||||
curl -s google.com > /dev/null || exit 1
|
||||
|
||||
log Loading zfs module first
|
||||
modprobe zfs || exit 1
|
||||
|
||||
echo ""
|
||||
lsblk
|
||||
echo ""
|
||||
|
||||
# read -p "disk: " DISK
|
||||
DISK=`lsblk | grep disk | grep -v SWAP | awk '{print $1}' | fzf`
|
||||
DISK=`echo /dev/$DISK`
|
||||
log $disk
|
||||
read -p "swapsize GiB: " SWAPSIZEGIB
|
||||
read -p "reserve GiB: " RESERVEGIB
|
||||
read -sp "password: " POOLPASS
|
||||
|
||||
EMAIL="marc@marcpartensky.com"
|
||||
NAME="Marc Partensky"
|
||||
|
||||
RESERVE=$((RESERVEGIB * 1024))
|
||||
SWAPSIZE=$((SWAPSIZEGIB * 1024))
|
||||
|
||||
|
||||
MNT=$(mktemp -d)
|
||||
|
||||
log Destroying zfs pool rpool and bpool just in case
|
||||
swapoff -a
|
||||
zpool import -fa
|
||||
for i in ${DISK}; do
|
||||
zpool labelclear -f $i
|
||||
done
|
||||
zpool destroy -f bpool
|
||||
zpool destroy -f rpool
|
||||
zpool export -a
|
||||
|
||||
log Unmounting filesystems just in case
|
||||
# ---
|
||||
umount -Rl "${MNT}"
|
||||
|
||||
log Enabling Nix Flakes functionality
|
||||
# ---
|
||||
mkdir -p ~/.config/nix
|
||||
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
|
||||
|
||||
|
||||
log Installing programs needed for system installation
|
||||
# ---
|
||||
if ! command -v git; then nix-env -f '<nixpkgs>' -iA git; fi
|
||||
if ! command -v jq; then nix-env -f '<nixpkgs>' -iA jq; fi
|
||||
if ! command -v partprobe; then nix-env -f '<nixpkgs>' -iA parted; fi
|
||||
|
||||
|
||||
log Partition the disks
|
||||
# ---
|
||||
partition_disk () {
|
||||
local disk=$1
|
||||
blkdiscard -f $disk || true
|
||||
|
||||
parted --script --align=optimal $disk -- \
|
||||
mklabel gpt \
|
||||
mkpart swap 1MiB $((SWAPSIZE + 1))MiB \
|
||||
mkpart rpool $((SWAPSIZE + 1))MiB -$((RESERVE + 100))MiB \
|
||||
mkpart bpool -$((RESERVE + 100))MiB -$((RESERVE + 3))MiB \
|
||||
mkpart EFI -$((RESERVE + 3))MiB -$((RESERVE + 2))MiB \
|
||||
mkpart BIOS -$((RESERVE + 2))MiB -$((RESERVE + 1))MiB \
|
||||
set 4 esp on \
|
||||
set 5 bios_grub on \
|
||||
set 5 legacy_boot on
|
||||
|
||||
partprobe $disk
|
||||
udevadm settle
|
||||
}
|
||||
|
||||
for i in $DISK; do
|
||||
partition_disk $i || exit 1
|
||||
done
|
||||
|
||||
log disk $DISK
|
||||
|
||||
|
||||
log Creating boot pool
|
||||
# ---
|
||||
# shellcheck disable=SC2046
|
||||
createbpool="zpool create \
|
||||
-o compatibility=grub2 \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=lz4 \
|
||||
-O devices=off \
|
||||
-O normalization=formD \
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-m /boot \
|
||||
-R $MNT \
|
||||
bpool \
|
||||
`for i in $DISK; do
|
||||
printf '%s ' ${i}3
|
||||
done`"
|
||||
echo $createbpool
|
||||
eval $createbpool
|
||||
|
||||
|
||||
log Creating root pool
|
||||
# ---
|
||||
# shellcheck disable=SC2046
|
||||
echo $POOLPASS | zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-R $MNT \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=zstd \
|
||||
-O dnodesize=auto \
|
||||
-O normalization=formD \
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-o feature@encryption=enabled \
|
||||
-O encryption=on \
|
||||
-O keyformat=passphrase \
|
||||
-m / \
|
||||
rpool \
|
||||
$(for i in $DISK; do
|
||||
printf '%s ' "${i}p2";
|
||||
done)
|
||||
|
||||
|
||||
log Creating encrypted root system container
|
||||
# ---
|
||||
echo $POOLPASS | zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=none \
|
||||
-o encryption=on \
|
||||
-o keylocation=prompt \
|
||||
-o keyformat=passphrase \
|
||||
rpool/nixos
|
||||
|
||||
|
||||
log Creating system datasets, managing mountpoints with mountpoint=legacy
|
||||
# ---
|
||||
zfs create -o mountpoint=legacy rpool/nixos/root
|
||||
mount -t zfs rpool/nixos/root "${MNT}"/
|
||||
zfs create -o mountpoint=legacy rpool/nixos/home
|
||||
mkdir "${MNT}"/home
|
||||
mount -t zfs rpool/nixos/home "${MNT}"/home
|
||||
zfs create -o mountpoint=legacy rpool/nixos/var
|
||||
zfs create -o mountpoint=legacy rpool/nixos/var/lib
|
||||
zfs create -o mountpoint=legacy rpool/nixos/var/log
|
||||
zfs create -o mountpoint=none bpool/nixos
|
||||
zfs create -o mountpoint=legacy bpool/nixos/root
|
||||
mkdir "${MNT}"/boot
|
||||
mount -t zfs bpool/nixos/root "${MNT}"/boot
|
||||
mkdir -p "${MNT}"/var/log
|
||||
mkdir -p "${MNT}"/var/lib
|
||||
mount -t zfs rpool/nixos/var/lib "${MNT}"/var/lib
|
||||
mount -t zfs rpool/nixos/var/log "${MNT}"/var/log
|
||||
zfs create -o mountpoint=legacy rpool/nixos/empty
|
||||
zfs snapshot rpool/nixos/empty@start
|
||||
|
||||
|
||||
log Formatting and mounting ESP
|
||||
# ---
|
||||
for i in ${DISK}; do
|
||||
mkfs.vfat -n EFI "${i}"4
|
||||
mkdir -p "${MNT}"/boot/efis/"${i##*/}"4
|
||||
mount -t vfat -o iocharset=iso8859-1 "${i}"4 "${MNT}"/boot/efis/"${i##*/}"4
|
||||
done
|
||||
|
||||
|
||||
log Cloning template flake configuration
|
||||
# ---
|
||||
mkdir -p "${MNT}"/etc
|
||||
git clone --depth 1 --branch custom \
|
||||
https://github.com/marcpartensky/nixos-zfs-installer.git "${MNT}"/etc/nixos
|
||||
|
||||
rm -rf "${MNT}"/etc/nixos/.git
|
||||
git -C "${MNT}"/etc/nixos/ init -b master
|
||||
git -C "${MNT}"/etc/nixos/ add "${MNT}"/etc/nixos/
|
||||
git -C "${MNT}"/etc/nixos config user.email $EMAIL
|
||||
git -C "${MNT}"/etc/nixos config user.name $NAME
|
||||
git -C "${MNT}"/etc/nixos commit -nasm 'initial commit'
|
||||
|
||||
|
||||
log Customizing configuration to your hardware
|
||||
# ---
|
||||
for i in ${DISK}; do
|
||||
sed -i \
|
||||
"s|/dev/disk/by-id/|${i%/*}/|" \
|
||||
"${MNT}"/etc/nixos/hosts/nixos/default.nix
|
||||
break
|
||||
done
|
||||
|
||||
diskNames=""
|
||||
for i in ${DISK}; do
|
||||
diskNames="${diskNames} \"${i##*/}\""
|
||||
done
|
||||
|
||||
sed -i "s|\"bootDevices_placeholder\"|${diskNames}|g" \
|
||||
"${MNT}"/etc/nixos/hosts/nixos/default.nix
|
||||
|
||||
sed -i "s|\"abcd1234\"|\"$(head -c4 /dev/urandom | od -A none -t x4| sed 's| ||g' || true)\"|g" \
|
||||
"${MNT}"/etc/nixos/hosts/nixos/default.nix
|
||||
|
||||
sed -i "s|\"x86_64-linux\"|\"$(uname -m || true)-linux\"|g" \
|
||||
"${MNT}"/etc/nixos/flake.nix
|
||||
|
||||
cp "$(command -v nixos-generate-config || true)" ./nixos-generate-config
|
||||
|
||||
chmod a+rwx ./nixos-generate-config
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
echo 'print STDOUT $initrdAvailableKernelModules' >> ./nixos-generate-config
|
||||
|
||||
kernelModules="$(./nixos-generate-config --show-hardware-config --no-filesystems | tail -n1 || true)"
|
||||
|
||||
sed -i "s|\"kernelModules_placeholder\"|${kernelModules}|g" \
|
||||
"${MNT}"/etc/nixos/hosts/nixos/default.nix
|
||||
|
||||
log Setting root password
|
||||
# ---
|
||||
rootPwd=$(mkpasswd2 -m SHA-512)
|
||||
sed -i \
|
||||
"s|rootHash_placeholder|${rootPwd}|" \
|
||||
"${MNT}"/etc/nixos/configuration.nix
|
||||
|
||||
|
||||
log Commiting changes to local repo
|
||||
# ---
|
||||
git -C "${MNT}"/etc/nixos commit -asm 'initial installation'
|
||||
|
||||
log Updating flake lock file to track latest system version
|
||||
# ---
|
||||
nix flake update --commit-lock-file \
|
||||
"git+file://${MNT}/etc/nixos"
|
||||
|
||||
log Installing system and apply configuration
|
||||
# ---
|
||||
nixos-install \
|
||||
--root "${MNT}" \
|
||||
--no-root-passwd \
|
||||
--flake "git+file://${MNT}/etc/nixos#nixos"
|
||||
|
||||
|
||||
log Setuping encrypted swap. This is useful if the available memory is small
|
||||
# ---
|
||||
for i in ${DISK}; do
|
||||
cryptsetup open --type plain --key-file /dev/random "${i}"1 "${i##*/}"1
|
||||
mkswap /dev/mapper/"${i##*/}"1
|
||||
swapon /dev/mapper/"${i##*/}"1
|
||||
done
|
||||
|
||||
log Unmounting filesystems
|
||||
# ---
|
||||
umount -Rl "${MNT}"
|
||||
zpool export -a
|
||||
|
||||
|
||||
log The installation is done, enjoy
|
||||
+35
-59
@@ -11,6 +11,11 @@ in {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
luks.enable = mkOption {
|
||||
description = "Use luks encryption";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
devNodes = mkOption {
|
||||
description = "Specify where to discover ZFS pools";
|
||||
type = types.str;
|
||||
@@ -24,15 +29,7 @@ in {
|
||||
description = "Specify boot devices";
|
||||
type = types.nonEmptyListOf types.str;
|
||||
};
|
||||
availableKernelModules = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = [ "uas" "nvme" "ahci" ];
|
||||
};
|
||||
kernelParams = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
immutable = mkOption {
|
||||
immutable.enable = mkOption {
|
||||
description = "Enable root on ZFS immutable root support";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -44,56 +41,61 @@ in {
|
||||
};
|
||||
partitionScheme = mkOption {
|
||||
default = {
|
||||
biosBoot = "-part5";
|
||||
efiBoot = "-part1";
|
||||
swap = "-part4";
|
||||
bootPool = "-part2";
|
||||
rootPool = "-part3";
|
||||
swap = "1";
|
||||
rootPool = "2";
|
||||
bootPool = "3";
|
||||
efiBoot = "4";
|
||||
biosBoot = "5";
|
||||
};
|
||||
description = "Describe on disk partitions";
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
sshUnlock = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
authorizedKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable) (mkMerge [
|
||||
{
|
||||
zfs-root.fileSystems.datasets = {
|
||||
# rpool/path/to/dataset = "/path/to/mountpoint"
|
||||
"rpool/nixos/home" = mkDefault "/home";
|
||||
"rpool/nixos/var/lib" = mkDefault "/var/lib";
|
||||
"rpool/nixos/var/log" = mkDefault "/var/log";
|
||||
"bpool/nixos/root" = "/boot";
|
||||
};
|
||||
}
|
||||
(mkIf (!cfg.immutable) {
|
||||
(mkIf cfg.luks.enable {
|
||||
boot.initrd.luks.devices = mkMerge (map (diskName: {
|
||||
"luks-rpool-${diskName}${cfg.partitionScheme.rootPool}" = {
|
||||
device = (cfg.devNodes + diskName + cfg.partitionScheme.rootPool);
|
||||
allowDiscards = true;
|
||||
bypassWorkqueues = true;
|
||||
};
|
||||
}) cfg.bootDevices);
|
||||
})
|
||||
(mkIf (!cfg.immutable.enable) {
|
||||
zfs-root.fileSystems.datasets = { "rpool/nixos/root" = "/"; };
|
||||
})
|
||||
(mkIf cfg.immutable {
|
||||
(mkIf cfg.immutable.enable {
|
||||
zfs-root.fileSystems = {
|
||||
datasets = {
|
||||
# rpool/path/to/dataset = "/path/to/mountpoint"
|
||||
"rpool/nixos/empty" = "/";
|
||||
"rpool/nixos/root" = "/oldroot";
|
||||
};
|
||||
bindmounts = {
|
||||
# /bindmount/source = /bindmount/target
|
||||
"/oldroot/nix" = "/nix";
|
||||
"/oldroot/etc/nixos" = "/etc/nixos";
|
||||
};
|
||||
};
|
||||
boot.initrd.postDeviceCommands = ''
|
||||
if ! grep -q zfs_no_rollback /proc/cmdline; then
|
||||
zpool import -N rpool
|
||||
zfs rollback -r rpool/nixos/empty@start
|
||||
zpool export -a
|
||||
fi
|
||||
'';
|
||||
boot.initrd.systemd.services.immutable-zfs-root = {
|
||||
description = "Rollback root filesystem to an empty snapshot";
|
||||
unitConfig.DefaultDependencies = false;
|
||||
wantedBy = [ "zfs.target" ];
|
||||
after = [ "zfs-import-rpool.service" ];
|
||||
before = [ "sysroot.mount" ];
|
||||
path = [ pkgs.zfs ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = "zfs rollback -r rpool/nixos/empty@start";
|
||||
};
|
||||
})
|
||||
{
|
||||
zfs-root.fileSystems = {
|
||||
@@ -104,10 +106,6 @@ in {
|
||||
(map (diskName: diskName + cfg.partitionScheme.swap) cfg.bootDevices);
|
||||
};
|
||||
boot = {
|
||||
kernelPackages =
|
||||
mkDefault config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||
initrd.availableKernelModules = cfg.availableKernelModules;
|
||||
kernelParams = cfg.kernelParams;
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
zfs = {
|
||||
devNodes = cfg.devNodes;
|
||||
@@ -136,27 +134,5 @@ in {
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf cfg.sshUnlock.enable {
|
||||
boot.initrd = {
|
||||
network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
enable = true;
|
||||
hostKeys = [
|
||||
"/var/lib/ssh_unlock_zfs_ed25519_key"
|
||||
"/var/lib/ssh_unlock_zfs_rsa_key"
|
||||
];
|
||||
authorizedKeys = cfg.sshUnlock.authorizedKeys;
|
||||
};
|
||||
postCommands = ''
|
||||
tee -a /root/.profile >/dev/null <<EOF
|
||||
if zfs load-key rpool/nixos; then
|
||||
pkill zfs
|
||||
fi
|
||||
exit
|
||||
EOF'';
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,3 +1 @@
|
||||
{ config, lib, pkgs, ... }: {
|
||||
imports = [ ./boot ./fileSystems ./networking ./my-config ];
|
||||
}
|
||||
{ config, lib, pkgs, ... }: { imports = [ ./boot ./fileSystems ]; }
|
||||
|
||||
@@ -41,7 +41,7 @@ in {
|
||||
};
|
||||
}) cfg.bindmounts ++ map (esp: {
|
||||
"/boot/efis/${esp}" = {
|
||||
device = "${config.zfs-root.boot.devNodes}/${esp}";
|
||||
device = "${config.zfs-root.boot.devNodes}${esp}";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"x-systemd.idle-timeout=1min"
|
||||
@@ -54,7 +54,7 @@ in {
|
||||
};
|
||||
}) cfg.efiSystemPartitions);
|
||||
config.swapDevices = mkDefault (map (swap: {
|
||||
device = "${config.zfs-root.boot.devNodes}/${swap}";
|
||||
device = "${config.zfs-root.boot.devNodes}${swap}";
|
||||
discardPolicy = mkDefault "both";
|
||||
randomEncryption = {
|
||||
enable = true;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let inherit (lib) types mkIf mkDefault mkOption;
|
||||
in {
|
||||
options.my-config = {
|
||||
template.desktop.gnome.enable = mkOption {
|
||||
description = "Enable my customized GNOME desktop";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
|
||||
# if my-config.template.desktop.gnome.enable is set to true
|
||||
# set the following options
|
||||
config = mkIf config.my-config.template.desktop.gnome.enable {
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
desktopManager.gnome.enable = true;
|
||||
displayManager.gdm.enable = true;
|
||||
};
|
||||
|
||||
# GNOME must be used with a non-root user,
|
||||
# add a non-root user
|
||||
users.users.alice = {
|
||||
# Generate hashed password with "mkpasswd -m sha-512" command,
|
||||
# "!" disables login.
|
||||
# "mkpasswd" without "-m sha-512" will not work
|
||||
initialHashedPassword = "!";
|
||||
description = "Full Name";
|
||||
# Users in "wheel" group are allowed to use "doas" command
|
||||
# to obtain root permissions.
|
||||
extraGroups = [ "wheel" ];
|
||||
packages = builtins.attrValues {
|
||||
inherit (pkgs)
|
||||
mg # emacs-like editor
|
||||
jq # other programs
|
||||
;
|
||||
};
|
||||
isNormalUser = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -7,7 +7,7 @@ in {
|
||||
hostName = mkOption {
|
||||
description = "The name of the machine. Used by nix flake.";
|
||||
type = types.str;
|
||||
default = "exampleHost";
|
||||
default = "nixos";
|
||||
};
|
||||
timeZone = mkOption {
|
||||
type = types.str;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
print STDOUT $initrdAvailableKernelModules
|
||||
Reference in New Issue
Block a user