Merge pull request 'Build image from scratch / without NixOS.' (#14) from dln/push-wxvqmqvrsxzv into main
Some checks are pending
ci/woodpecker/push/ci Pipeline is pending
Some checks are pending
ci/woodpecker/push/ci Pipeline is pending
Reviewed-on: #14
This commit is contained in:
commit
0f7958b596
30 changed files with 3152 additions and 1198 deletions
|
@ -1 +1,3 @@
|
|||
nix_direnv_manual_reload
|
||||
use flake
|
||||
dotenv_if_exists
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,6 +4,8 @@
|
|||
.task
|
||||
/result
|
||||
/target
|
||||
/out
|
||||
/initrd.gz
|
||||
.*.swp
|
||||
.*.swo
|
||||
.nixos-test-history
|
||||
|
|
34
flake.lock
generated
34
flake.lock
generated
|
@ -1,5 +1,23 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1739020877,
|
||||
|
@ -18,8 +36,24 @@
|
|||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
|
256
flake.nix
256
flake.nix
|
@ -2,90 +2,200 @@
|
|||
description = "PatOS is a minimal, immutable Linux distribution specialized for the Patagia Platform.";
|
||||
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs }:
|
||||
let
|
||||
releaseVersion = "0.0.1";
|
||||
system = "x86_64-linux";
|
||||
updateUrl = "https://images.dl.patagia.dev/patos/";
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
nixosModules.devel.imports = [
|
||||
./modules/profiles/devel.nix
|
||||
];
|
||||
self,
|
||||
flake-utils,
|
||||
nixpkgs,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
packages = {
|
||||
default = self.packages.${system}.image;
|
||||
image = pkgs.writeShellScriptBin "image" ''
|
||||
echo "make UKI..."
|
||||
echo ${self.packages.${system}.kernel.kernel}/bzImage
|
||||
${self.packages.${system}.systemd.out}/usr/bin/ukify build \
|
||||
--linux ${self.packages.${system}.kernel.kernel}/bzImage \
|
||||
--initrd ./initrd.gz \
|
||||
--cmdline "console=ttyS0" \
|
||||
-o patos.efi
|
||||
'';
|
||||
|
||||
nixosModules.server.imports = [
|
||||
./modules/profiles/server.nix
|
||||
];
|
||||
kernel = pkgs.callPackage ./kernel { };
|
||||
glibc = pkgs.callPackage ./glibc { };
|
||||
systemd = pkgs.callPackage ./systemd { };
|
||||
|
||||
nixosModules.image.imports = [
|
||||
./modules
|
||||
./modules/profiles/base.nix
|
||||
./modules/image
|
||||
];
|
||||
mkinitrd = pkgs.writeShellScriptBin "mkinitrd" ''
|
||||
echo "make initrd..."
|
||||
mkdir -p out
|
||||
|
||||
packages.${system} = {
|
||||
devel =
|
||||
(nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
(
|
||||
{ ... }:
|
||||
{
|
||||
nixpkgs.hostPlatform = system;
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
)
|
||||
{
|
||||
system.image.updates.url = "${updateUrl}";
|
||||
system.image.id = "patos";
|
||||
system.image.version = releaseVersion;
|
||||
image.compress = false;
|
||||
}
|
||||
self.nixosModules.image
|
||||
self.nixosModules.devel
|
||||
];
|
||||
}).config.system.build.updatePackage;
|
||||
# copy systemd
|
||||
cp -Pr ${self.packages.${system}.systemd.out}/* out/
|
||||
pushd out
|
||||
|
||||
patos =
|
||||
(nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
(
|
||||
{ ... }:
|
||||
{
|
||||
nixpkgs.hostPlatform = system;
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
)
|
||||
{
|
||||
system.image.updates.url = "${updateUrl}";
|
||||
system.image.id = "patos";
|
||||
system.image.version = releaseVersion;
|
||||
}
|
||||
self.nixosModules.image
|
||||
self.nixosModules.server
|
||||
];
|
||||
}).config.system.build.updatePackage;
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
|
||||
qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { inherit pkgs; };
|
||||
};
|
||||
# Copy kernel modules
|
||||
cp -Pr ${self.packages.${system}.kernel.kernel}/lib/modules ./usr/lib/
|
||||
find usr/lib/modules -type d -exec chmod 755 {} \;
|
||||
|
||||
checks.${system} = {
|
||||
podman = import ./tests/podman.nix { inherit pkgs self; };
|
||||
system-update = import ./tests/system-update.nix { inherit pkgs self; };
|
||||
};
|
||||
mkdir -p dev proc sys tmp root
|
||||
ln -sf usr/bin bin
|
||||
ln -sf usr/bin sbin
|
||||
ln -sf usr/lib lib
|
||||
ln -sf usr/lib lib64
|
||||
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
erofs-utils
|
||||
just
|
||||
self.packages.${system}.qemu-uefi-tpm
|
||||
squashfs-tools-ng
|
||||
];
|
||||
};
|
||||
ln -sf ../proc/self/mounts etc/mtab
|
||||
ln -sf ../usr/lib/systemd/systemd init
|
||||
|
||||
};
|
||||
echo patos > ./etc/hostname
|
||||
cat <<EOF > ./etc/os-release
|
||||
NAME="PatOS"
|
||||
PRETTY_NAME="PatOS Platform"
|
||||
ID=patos
|
||||
EOF
|
||||
|
||||
cat <<EOF > ./etc/passwd
|
||||
root::0:0:root:/root:/bin/sh
|
||||
bin:x:1:1:bin:/bin:/usr/bin/nologin
|
||||
daemon:x:2:2:daemon:/:/usr/bin/nologin
|
||||
mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin
|
||||
ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin
|
||||
http:x:33:33:http:/srv/http:/usr/bin/nologin
|
||||
uuidd:x:68:68:uuidd:/:/usr/bin/nologin
|
||||
dbus:x:81:81:dbus:/:/usr/bin/nologin
|
||||
nobody:x:99:99:nobody:/:/usr/bin/nologin
|
||||
EOF
|
||||
chmod 644 ./etc/passwd
|
||||
|
||||
cat <<EOF > ./etc/group
|
||||
root:x:0:root
|
||||
bin:x:1:root,bin,daemon
|
||||
daemon:x:2:root,bin,daemon
|
||||
sys:x:3:root,bin
|
||||
adm:x:4:root,daemon
|
||||
tty:x:5:
|
||||
disk:x:6:root
|
||||
lp:x:7:daemon
|
||||
mem:x:8:
|
||||
kmem:x:9:
|
||||
wheel:x:10:root
|
||||
ftp:x:11:
|
||||
mail:x:12:
|
||||
uucp:x:14:
|
||||
log:x:19:root
|
||||
utmp:x:20:
|
||||
locate:x:21:
|
||||
rfkill:x:24:
|
||||
smmsp:x:25:
|
||||
proc:x:26:
|
||||
http:x:33:
|
||||
games:x:50:
|
||||
lock:x:54:
|
||||
uuidd:x:68:
|
||||
dbus:x:81:
|
||||
network:x:90:
|
||||
video:x:91:
|
||||
audio:x:92:
|
||||
optical:x:93:
|
||||
floppy:x:94:
|
||||
storage:x:95:
|
||||
scanner:x:96:
|
||||
input:x:97:
|
||||
power:x:98:
|
||||
nobody:x:99:
|
||||
EOF
|
||||
chmod 644 ./etc/group
|
||||
|
||||
# FIXME: remove this
|
||||
cat <<EOF > usr/lib/systemd/system/demo.service
|
||||
[Unit]
|
||||
Description=Debug Shell (/bin/sulogin)
|
||||
Conflicts=shutdown.target
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Environment=HOME=/root
|
||||
WorkingDirectory=/root
|
||||
ExecStart=/bin/sulogin
|
||||
Type=idle
|
||||
StandardInput=tty-force
|
||||
StandardOutput=inherit
|
||||
StandardError=inherit
|
||||
KillMode=process
|
||||
IgnoreSIGPIPE=no
|
||||
SendSIGHUP=yes
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
||||
EOF
|
||||
mkdir usr/lib/systemd/system/basic.target.wants
|
||||
ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service
|
||||
|
||||
# set default target
|
||||
ln -sf basic.target usr/lib/systemd/system/default.target
|
||||
# remove first boot
|
||||
rm -f usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service
|
||||
# remove vconsole setup
|
||||
rm -f usr/lib/udev/rules.d/90-vconsole.rules
|
||||
|
||||
# install busybox
|
||||
cp ${pkgs.busybox.out}/bin/busybox usr/bin/
|
||||
usr/bin/busybox --list | xargs -I {} ln -sf busybox usr/bin/{}
|
||||
|
||||
# install lib kmod
|
||||
cp -P ${pkgs.kmod.lib}/lib/* ./usr/lib
|
||||
cp -P ${pkgs.kmod.out}/bin/* ./usr/bin
|
||||
cp -P ${pkgs.libbpf.out}/lib/libbpf* ./usr/lib
|
||||
|
||||
# get shared libs
|
||||
find . -type f -executable | xargs ldd 2> /dev/null | awk '{print $3}' | grep -v systemd | sort -u | xargs cp -t usr/lib
|
||||
find . -type f -executable | xargs chmod 755
|
||||
|
||||
# FIXME: hacky(?) ELF patching. Is there a better way????????
|
||||
find . -type f -executable -print | xargs -I {} ${pkgs.lib.getExe pkgs.patchelf} --set-rpath /lib:/usr/lib:/usr/lib/systemd {} 2> /dev/null
|
||||
find . -type f -executable -print | xargs -I {} ${pkgs.lib.getExe pkgs.patchelf} --set-interpreter /lib/ld-linux-x86-64.so.2 {} 2> /dev/null
|
||||
cp ${
|
||||
self.packages.${system}.glibc.out
|
||||
}/lib/ld-linux-x86-64.so.2 lib/ && ${pkgs.lib.getExe pkgs.patchelf} --remove-rpath lib/ld-linux-x86-64.so.2
|
||||
|
||||
# strip binaries
|
||||
find . -type f -executable | xargs strip 2> /dev/null
|
||||
|
||||
# gen initrd
|
||||
find . -print0 | ${pkgs.lib.getExe pkgs.cpio} --null --owner=root:root -o --format=newc | ${pkgs.lib.getExe pkgs.gzip} -9 > ../initrd.gz
|
||||
'';
|
||||
};
|
||||
|
||||
checks = {
|
||||
simple-test = pkgs.runCommand "simple-test" { } ''
|
||||
${self.packages.${system}.default}/bin/my-program
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
|
||||
formatter = pkgs.nixpkgs-fmt;
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
erofs-utils
|
||||
just
|
||||
nixd
|
||||
nixfmt-rfc-style
|
||||
squashfs-tools-ng
|
||||
];
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
57
glibc/default.nix
Normal file
57
glibc/default.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
fetchurl,
|
||||
pkgs,
|
||||
stdenv,
|
||||
|
||||
...
|
||||
}:
|
||||
let
|
||||
version = "2.40";
|
||||
pname = "glibcStandalone";
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
inherit version;
|
||||
|
||||
pname = pname;
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnu/glibc/glibc-${version}.tar.xz";
|
||||
sha256 = "sha256-GaiQF16SY9dI9ieZPeb0sa+c0h4D8IDkv7Oh+sECBaI=";
|
||||
};
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
configureFlags = [
|
||||
"--prefix=/"
|
||||
"--libdir=/lib"
|
||||
"--bindir=/bin"
|
||||
"--sysconfdir=/etc"
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
export PWD_P=$(type -tP pwd)
|
||||
for i in configure io/ftwtest-sh; do
|
||||
sed -i "$i" -e "s^/bin/pwd^$PWD_P^g"
|
||||
done
|
||||
|
||||
mkdir ../build
|
||||
cd ../build
|
||||
|
||||
configureScript="`pwd`/../$sourceRoot/configure"
|
||||
'';
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
bison
|
||||
python3Minimal
|
||||
];
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
];
|
||||
|
||||
preInstall = ''
|
||||
export DESTDIR=${placeholder "out"}
|
||||
'';
|
||||
|
||||
})
|
16
kernel/default.nix
Normal file
16
kernel/default.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ pkgs, ... }:
|
||||
let
|
||||
version = "6.13.2";
|
||||
in
|
||||
pkgs.linuxPackagesFor (
|
||||
pkgs.linuxManualConfig {
|
||||
version = "${version}-patos1";
|
||||
modDirVersion = version;
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz";
|
||||
hash = "sha256-zfYpgZBru+lwGutzxPn8yAegmEbCiHMWY9YnF+0a5wU=";
|
||||
};
|
||||
configfile = ./generic.config;
|
||||
allowImportFromDerivation = true;
|
||||
}
|
||||
)
|
2513
kernel/generic.config
Normal file
2513
kernel/generic.config
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,15 +0,0 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
boot = {
|
||||
bootspec.enable = false;
|
||||
initrd.kernelModules = config.boot.kernelModules;
|
||||
kernel.enable = false; # No kernel or modules in the rootfs
|
||||
modprobeConfig.enable = false;
|
||||
};
|
||||
|
||||
system.build = {
|
||||
inherit (config.boot.kernelPackages) kernel;
|
||||
};
|
||||
|
||||
system.modulesTree = [ config.boot.kernelPackages.kernel ] ++ config.boot.extraModulePackages;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
|
||||
composefs = final.callPackage ../../pkgs/composefs.nix { inherit prev; };
|
||||
qemu_tiny = final.callPackage ../../pkgs/qemu.nix { inherit prev; };
|
||||
|
||||
systemd = prev.systemd.overrideAttrs (oldAttrs: {
|
||||
mesonFlags = oldAttrs.mesonFlags ++ [
|
||||
"-Dsysupdated=enabled"
|
||||
];
|
||||
});
|
||||
## minimal inherit from systemd pkg, need to explicitly disable sysupdated
|
||||
systemdMinimal = prev.systemdMinimal.overrideAttrs (oldAttrs: {
|
||||
mesonFlags = oldAttrs.mesonFlags ++ [
|
||||
"-Dsysupdated=disabled"
|
||||
];
|
||||
});
|
||||
|
||||
})
|
||||
];
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
imports = [
|
||||
./config/minimal-modules.nix
|
||||
./config/minimal-system.nix
|
||||
];
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) efiArch;
|
||||
|
||||
initialPartitions = {
|
||||
"10-root" = {
|
||||
storePaths = [ config.system.build.toplevel ];
|
||||
repartConfig = {
|
||||
Type = "root";
|
||||
Minimize = "best";
|
||||
Format = "erofs";
|
||||
MakeDirectories = "/home /root /etc /dev /sys /bin /var /proc /run /usr /usr/bin /srv /tmp /mnt /lib /boot";
|
||||
Verity = "data";
|
||||
VerityMatchKey = "root";
|
||||
SplitName = "root";
|
||||
};
|
||||
};
|
||||
|
||||
"20-root-verity" = {
|
||||
repartConfig = {
|
||||
Type = "root-verity";
|
||||
Minimize = "best";
|
||||
Verity = "hash";
|
||||
VerityMatchKey = "root";
|
||||
SplitName = "verity";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: We don't need a combined image here - add dry-run flag to repart invocation
|
||||
verityRepart = import (pkgs.path + "/nixos/lib/eval-config.nix") {
|
||||
inherit lib pkgs;
|
||||
system = null;
|
||||
modules = [
|
||||
(
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/image/repart.nix") ];
|
||||
image.repart = {
|
||||
name = "verity";
|
||||
split = true;
|
||||
mkfsOptions = lib.mkIf config.image.compress {
|
||||
erofs = [
|
||||
"-zlz4hc,level=12"
|
||||
"-Efragments,dedupe,ztailpacking"
|
||||
];
|
||||
};
|
||||
partitions = initialPartitions;
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
|
||||
rootPart = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.root.raw";
|
||||
verityPart = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.verity.raw";
|
||||
|
||||
verityImgAttrs = builtins.fromJSON (
|
||||
builtins.readFile "${verityRepart.config.system.build.image}/repart-output.json"
|
||||
);
|
||||
rootAttrs = builtins.elemAt verityImgAttrs 0;
|
||||
verityAttrs = builtins.elemAt verityImgAttrs 1;
|
||||
|
||||
rootUuid = rootAttrs.uuid;
|
||||
verityUuid = verityAttrs.uuid;
|
||||
verityRootHash = rootAttrs.roothash;
|
||||
|
||||
finalPartitions = {
|
||||
"10-esp" = {
|
||||
contents = {
|
||||
"/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = "${pkgs.systemdUkify}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
|
||||
"/EFI/Linux/${config.system.boot.loader.ukiFile}".source = "${config.system.build.uki}/${config.system.boot.loader.ukiFile}";
|
||||
"/EFI/memtest86/memtest86.efi".source = "${pkgs.memtest86plus}/memtest.efi";
|
||||
"/loader/entries/patos-factory-reset.conf".source = pkgs.writeText "patos-factory-reset.conf" ''
|
||||
title Patos Factory Reset
|
||||
efi /EFI/Linux/${config.system.boot.loader.ukiFile}
|
||||
options ${toString config.boot.kernelParams} systemd.factory_reset=yes
|
||||
sort-key z_factory_reset
|
||||
'';
|
||||
"/loader/entries/memtest86.conf".source = pkgs.writeText "memtest86.conf" ''
|
||||
title Memtest86+
|
||||
efi /EFI/memtest86/memtest86.efi
|
||||
options console=ttyS0
|
||||
sort-key z_memtest
|
||||
'';
|
||||
"/loader/loader.conf".source = pkgs.writeText "loader.conf" ''
|
||||
timeout 2
|
||||
'';
|
||||
};
|
||||
repartConfig = {
|
||||
Type = "esp";
|
||||
Format = "vfat";
|
||||
SizeMinBytes = "96M";
|
||||
SizeMaxBytes = "96M";
|
||||
SplitName = "-";
|
||||
};
|
||||
};
|
||||
"20-root-verity-a" = {
|
||||
repartConfig = {
|
||||
Type = "root-verity";
|
||||
Label = "verity-${config.system.image.version}";
|
||||
CopyBlocks = "${verityPart}";
|
||||
SplitName = "-";
|
||||
SizeMinBytes = "64M";
|
||||
SizeMaxBytes = "64M";
|
||||
UUID = "${verityUuid}";
|
||||
ReadOnly = 1;
|
||||
};
|
||||
};
|
||||
# TODO: Add signature partition for systemd-nspawn
|
||||
"22-root-a" = {
|
||||
repartConfig = {
|
||||
Type = "root";
|
||||
Label = "root-${config.system.image.version}";
|
||||
CopyBlocks = "${rootPart}";
|
||||
SplitName = "-";
|
||||
UUID = "${rootUuid}";
|
||||
ReadOnly = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
finalRepart = import (pkgs.path + "/nixos/lib/eval-config.nix") {
|
||||
inherit lib pkgs;
|
||||
system = null;
|
||||
modules = [
|
||||
(
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/image/repart.nix") ];
|
||||
image.repart = {
|
||||
name = "${config.system.image.id}";
|
||||
partitions = finalPartitions;
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
# This fields is immutable by default, but can be overridden.
|
||||
options.system.nixos.codeName = lib.mkOption { readOnly = false; };
|
||||
options.system.nixos.release = lib.mkOption { readOnly = false; };
|
||||
|
||||
# FIXME: Should be configured somehow
|
||||
config.system.nixos = {
|
||||
codeName = "Finn";
|
||||
distroId = "patos";
|
||||
distroName = "PatOS";
|
||||
release = "2024-11";
|
||||
variant_id = "server";
|
||||
variantName = "Server";
|
||||
vendorName = "PatOS";
|
||||
};
|
||||
|
||||
options.image.compress = lib.mkEnableOption "image compression" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
config.system.build = {
|
||||
inherit verityRootHash;
|
||||
|
||||
image =
|
||||
(pkgs.linkFarm "image-release" [
|
||||
{
|
||||
name = "${config.system.image.id}_${config.system.image.version}.efi";
|
||||
path = "${config.system.build.uki}/${config.system.boot.loader.ukiFile}";
|
||||
}
|
||||
{
|
||||
name = "${config.system.image.id}_${config.system.image.version}_${verityUuid}.verity";
|
||||
path = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.verity.raw";
|
||||
}
|
||||
{
|
||||
name = "${config.system.image.id}_${config.system.image.version}_${rootUuid}.root";
|
||||
path = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.root.raw";
|
||||
}
|
||||
{
|
||||
name = "${config.system.image.id}_${config.system.image.version}.img";
|
||||
path = "${finalRepart.config.system.build.image}/${finalRepart.config.image.repart.imageFileBasename}.raw";
|
||||
}
|
||||
])
|
||||
// {
|
||||
imageFile = "${config.system.image.id}_${config.system.image.version}.img";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
imports = [
|
||||
./updater.nix
|
||||
./builder.nix
|
||||
./veritysetup.nix
|
||||
];
|
||||
|
||||
system.build.updatePackage = pkgs.runCommand "update-package" { } ''
|
||||
mkdir "$out"
|
||||
cd "$out"
|
||||
cp "${config.system.build.image}"/* .
|
||||
${pkgs.coreutils}/bin/sha256sum * > SHA256SUMS
|
||||
'';
|
||||
|
||||
systemd.repart.partitions = {
|
||||
"10-esp" = {
|
||||
Type = "esp";
|
||||
UUID = "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"; # Well known
|
||||
Format = "vfat";
|
||||
SizeMinBytes = "96M";
|
||||
SizeMaxBytes = "96M";
|
||||
};
|
||||
"20-root-verity-a" = {
|
||||
Type = "root-verity";
|
||||
SizeMinBytes = "64M";
|
||||
SizeMaxBytes = "64M";
|
||||
};
|
||||
"22-root-a" = {
|
||||
Type = "root";
|
||||
SizeMinBytes = "512M";
|
||||
SizeMaxBytes = "512M";
|
||||
};
|
||||
"30-root-verity-b" = {
|
||||
Type = "root-verity";
|
||||
SizeMinBytes = "64M";
|
||||
SizeMaxBytes = "64M";
|
||||
Label = "_empty";
|
||||
ReadOnly = 1;
|
||||
};
|
||||
"32-root-b" = {
|
||||
Type = "root";
|
||||
SizeMinBytes = "512M";
|
||||
SizeMaxBytes = "512M";
|
||||
Label = "_empty";
|
||||
ReadOnly = 1;
|
||||
};
|
||||
"40-var" = {
|
||||
Type = "var";
|
||||
UUID = "4d21b016-b534-45c2-a9fb-5c16e091fd2d"; # Well known
|
||||
Format = "btrfs";
|
||||
Label = "patos-state";
|
||||
Minimize = "off";
|
||||
FactoryReset = "yes";
|
||||
Encrypt = "tpm2";
|
||||
SizeMinBytes = "2G";
|
||||
SplitName = "-";
|
||||
};
|
||||
};
|
||||
|
||||
boot.loader.grub.enable = false;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.uki.name = "patos";
|
||||
|
||||
boot.initrd = {
|
||||
compressor = "zstd";
|
||||
compressorArgs = [ "-8" ];
|
||||
|
||||
luks.forceLuksSupportInInitrd = true;
|
||||
kernelModules = [
|
||||
"dm_mod"
|
||||
"dm_crypt"
|
||||
] ++ config.boot.initrd.luks.cryptoModules;
|
||||
|
||||
supportedFilesystems = {
|
||||
btrfs = true;
|
||||
erofs = true;
|
||||
};
|
||||
|
||||
systemd.enable = true;
|
||||
systemd.repart.enable = true;
|
||||
systemd.services.systemd-repart = {
|
||||
after = lib.mkForce [ "sysroot.mount" ];
|
||||
requires = [ "sysroot.mount" ];
|
||||
serviceConfig.Environment = [
|
||||
"SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
system.etc.overlay.mutable = false;
|
||||
users.mutableUsers = false;
|
||||
|
||||
boot.kernelParams = [
|
||||
"rootfstype=erofs"
|
||||
"rootflags=ro"
|
||||
"roothash=${config.system.build.verityRootHash}"
|
||||
];
|
||||
|
||||
fileSystems =
|
||||
let
|
||||
parts = config.systemd.repart.partitions;
|
||||
in
|
||||
{
|
||||
"/var" = {
|
||||
fsType = parts."40-var".Format;
|
||||
device = "/dev/mapper/var";
|
||||
encrypted = {
|
||||
enable = true;
|
||||
blkDev = "/dev/disk/by-partuuid/${parts."40-var".UUID}";
|
||||
label = "var";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Required to mount the efi partition
|
||||
boot.kernelModules = [
|
||||
"vfat"
|
||||
"nls_cp437"
|
||||
"nls_iso8859-1"
|
||||
];
|
||||
|
||||
environment.etc."machine-id" = {
|
||||
text = "";
|
||||
mode = "0755";
|
||||
};
|
||||
|
||||
# Refuse to boot on mount failure
|
||||
systemd.targets."sysinit".requires = [ "local-fs.target" ];
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
options.system.image.updates = {
|
||||
enable = lib.mkEnableOption "system updates via systemd-sysupdate" // {
|
||||
default = config.system.image.updates.url != null;
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.system.image.updates.enable {
|
||||
|
||||
assertions = [
|
||||
{ assertion = config.system.image.updates.url != null; }
|
||||
];
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-bless-boot.service"
|
||||
"boot-complete.target"
|
||||
"dbus-org.freedesktop.sysupdate1.service"
|
||||
"systemd-sysupdated.service"
|
||||
];
|
||||
|
||||
environment.etc."sysupdate.d/10-uki.transfer" = {
|
||||
text = ''
|
||||
[Source]
|
||||
Path=${config.system.image.updates.url}
|
||||
MatchPattern=${config.boot.uki.name}_@v.efi
|
||||
Type=url-file
|
||||
|
||||
[Target]
|
||||
InstancesMax=2
|
||||
MatchPattern=${config.boot.uki.name}_@v+@l-@d.efi ${config.boot.uki.name}_@v+@l.efi ${config.boot.uki.name}_@v.efi
|
||||
Mode=0444
|
||||
Path=/EFI/Linux
|
||||
PathRelativeTo=esp
|
||||
TriesDone=0
|
||||
TriesLeft=3
|
||||
Type=regular-file
|
||||
|
||||
[Transfer]
|
||||
Verify=no
|
||||
'';
|
||||
};
|
||||
|
||||
environment.etc."sysupdate.d/20-root.transfer" = {
|
||||
text = ''
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=${config.system.image.updates.url}
|
||||
MatchPattern=${config.system.image.id}_@v_@u.verity
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=verity-@v
|
||||
MatchPartitionType=root-verity
|
||||
ReadOnly=1
|
||||
|
||||
[Transfer]
|
||||
Verify=no
|
||||
'';
|
||||
};
|
||||
|
||||
environment.etc."sysupdate.d/22-root.transfer" = {
|
||||
text = ''
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=${config.system.image.updates.url}
|
||||
MatchPattern=${config.system.image.id}_@v_@u.root
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=root-@v
|
||||
MatchPartitionType=root
|
||||
ReadOnly=1
|
||||
|
||||
[Transfer]
|
||||
Verify=no
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
options.boot.initrd.systemd.root = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"fstab"
|
||||
"gpt-auto"
|
||||
""
|
||||
];
|
||||
};
|
||||
|
||||
config.boot.initrd = {
|
||||
|
||||
kernelModules = [
|
||||
"dm_mod"
|
||||
"dm_verity"
|
||||
];
|
||||
|
||||
systemd = {
|
||||
|
||||
# Required to activate systemd-fstab-generator
|
||||
root = "";
|
||||
|
||||
additionalUpstreamUnits = [
|
||||
"veritysetup-pre.target"
|
||||
"veritysetup.target"
|
||||
"remote-veritysetup.target"
|
||||
];
|
||||
|
||||
storePaths = [
|
||||
"${config.boot.initrd.systemd.package}/lib/systemd/systemd-veritysetup"
|
||||
"${config.boot.initrd.systemd.package}/lib/systemd/system-generators/systemd-veritysetup-generator"
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/image-based-appliance.nix")
|
||||
(modulesPath + "/profiles/perlless.nix")
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
# system.forbiddenDependenciesRegexes = lib.mkForce [ ];
|
||||
|
||||
nixpkgs.flake.setNixPath = false;
|
||||
nixpkgs.flake.setFlakeRegistry = false;
|
||||
boot.enableContainers = false;
|
||||
|
||||
boot.kernelModules = [
|
||||
"zram"
|
||||
"usb_storage"
|
||||
"uas"
|
||||
"sd_mod"
|
||||
"r8169"
|
||||
"ehci-hcd"
|
||||
"ehci-pci"
|
||||
"xhci-hcd"
|
||||
"xhci-pci"
|
||||
"xhci-pci-renesas"
|
||||
"nvme"
|
||||
"virtio_net"
|
||||
"9p"
|
||||
"9pnet_virtio"
|
||||
];
|
||||
|
||||
system.etc.overlay.mutable = lib.mkDefault false;
|
||||
|
||||
systemd.watchdog = lib.mkDefault {
|
||||
runtimeTime = "10s";
|
||||
rebootTime = "30s";
|
||||
};
|
||||
|
||||
zramSwap.enable = true;
|
||||
|
||||
# FIXME: fstrim should only be enabled for virtual machine images?
|
||||
services.fstrim.enable = true;
|
||||
|
||||
users.allowNoPasswordLogin = true;
|
||||
users.users.root.home = lib.mkForce "/";
|
||||
|
||||
security.sudo.enable = lib.mkDefault false;
|
||||
|
||||
security.polkit = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (subject.isInGroup("wheel")) {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
'';
|
||||
};
|
||||
|
||||
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ];
|
||||
|
||||
# Console
|
||||
|
||||
systemd.enableEmergencyMode = false;
|
||||
boot.consoleLogLevel = lib.mkDefault 1;
|
||||
boot.kernelParams = [
|
||||
"panic=1"
|
||||
"boot.panic_on_fail"
|
||||
# "nomodeset"
|
||||
"console=ttyS0,115200n8"
|
||||
"earlyprintk=ttyS0,115200n8"
|
||||
"systemd.mask=systemd-vconsole-setup.service" # FIXME: Figure out why vconsole-setup fails when loading keymap
|
||||
];
|
||||
|
||||
# This is vi country
|
||||
programs.nano.enable = false;
|
||||
programs.vim.enable = true;
|
||||
programs.vim.defaultEditor = lib.mkDefault true;
|
||||
|
||||
# Temporary file
|
||||
boot.tmp.useTmpfs = true;
|
||||
|
||||
# Logging
|
||||
services.journald = {
|
||||
storage = "volatile";
|
||||
extraConfig = ''
|
||||
SystemMaxUse=10M
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
imports = [ ./server.nix ];
|
||||
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.ip_unprivileged_port_start" = 0;
|
||||
};
|
||||
|
||||
boot.kernelParams = [
|
||||
"systemd.log_level=info"
|
||||
"systemd.log_target=console"
|
||||
"systemd.journald.forward_to_console"
|
||||
];
|
||||
|
||||
users.users."admin" = {
|
||||
isNormalUser = true;
|
||||
linger = true;
|
||||
extraGroups = [ "wheel" ];
|
||||
home = "/var/home/admin";
|
||||
};
|
||||
|
||||
environment.etc = {
|
||||
subuid = {
|
||||
text = "admin:100000:65536";
|
||||
mode = "0644";
|
||||
};
|
||||
|
||||
subgid = {
|
||||
text = "admin:100000:65536";
|
||||
mode = "0644";
|
||||
};
|
||||
};
|
||||
|
||||
services.getty.autologinUser = "admin";
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
# Use networkd
|
||||
networking.useNetworkd = true;
|
||||
systemd.network.wait-online.enable = true;
|
||||
|
||||
# Firewall
|
||||
networking.firewall.enable = false;
|
||||
networking.nftables.enable = lib.mkDefault true;
|
||||
|
||||
# DNS
|
||||
services.resolved = {
|
||||
fallbackDns = [ ]; # Disable fallback DNS. DNS will fail if resolvers are unconfigured
|
||||
extraConfig = ''
|
||||
DNSStubListener=no
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
# Configuration
|
||||
networking.hostName = "";
|
||||
|
||||
# Kernel
|
||||
boot.kernel.sysctl = {
|
||||
"net.core.default_qdisc" = "fq"; # FIXME: manage these with networkd?
|
||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
};
|
||||
|
||||
# Modules
|
||||
boot.kernelModules = [
|
||||
"ip_tables"
|
||||
"x_tables"
|
||||
"nf_tables"
|
||||
"nft_ct"
|
||||
"nft_log"
|
||||
"nf_log_syslog"
|
||||
"nft_fib"
|
||||
"nft_fib_inet"
|
||||
"nft_compat"
|
||||
"nft_nat"
|
||||
"nft_chain_nat"
|
||||
"nft_masq"
|
||||
"nfnetlink"
|
||||
"xt_conntrack"
|
||||
"nf_conntrack"
|
||||
"nf_log_syslog"
|
||||
"nf_nat"
|
||||
"af_packet"
|
||||
"bridge"
|
||||
"veth"
|
||||
"tcp_bbr"
|
||||
"sch_fq_codel"
|
||||
"ipt_rpfilter"
|
||||
"ip6t_rpfilter"
|
||||
"sch_fq"
|
||||
"tun"
|
||||
"tap"
|
||||
"xt_MASQUERADE"
|
||||
"xt_mark"
|
||||
"xt_comment"
|
||||
"xt_multiport"
|
||||
"xt_addrtype"
|
||||
];
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
imports = [
|
||||
(modulesPath + "/profiles/minimal.nix")
|
||||
./network.nix
|
||||
./sysext.nix
|
||||
];
|
||||
|
||||
boot.kernelParams = [
|
||||
"quiet"
|
||||
];
|
||||
|
||||
virtualisation.podman.enable = true;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
system.activationScripts.sysext = ''
|
||||
mkdir -p /var/lib/confexts
|
||||
mkdir -p /var/lib/extensions
|
||||
mkdir -p /etc/systemd/extensions
|
||||
'';
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-confext.service"
|
||||
"systemd-sysext.service"
|
||||
];
|
||||
|
||||
# systemd.services."systemd-confext" = {
|
||||
# enable = true;
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# };
|
||||
|
||||
# systemd.services."systemd-sysext.service" = {
|
||||
# enable = true;
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# };
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{ prev, ... }:
|
||||
|
||||
prev.composefs.overrideAttrs (final: prev: {
|
||||
doCheck = false;
|
||||
})
|
|
@ -1,12 +0,0 @@
|
|||
{ stdenv, lib
|
||||
, linux-firmware
|
||||
, fwDirs
|
||||
}: stdenv.mkDerivation {
|
||||
pname = "linux-firmware-minimal";
|
||||
version = linux-firmware.version;
|
||||
buildCommand = lib.concatStringsSep "\n" (
|
||||
[''mkdir -p "$out/lib/firmware"'']
|
||||
++ (map (name: ''
|
||||
cp -r "${linux-firmware}/lib/firmware/${name}" "$out/lib/firmware/${name}"
|
||||
'') fwDirs));
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
{ prev, pkgs, ... }:
|
||||
|
||||
(prev.qemu_test.override {
|
||||
enableDocs = false;
|
||||
capstoneSupport = false;
|
||||
guestAgentSupport = false;
|
||||
tpmSupport = false;
|
||||
libiscsiSupport = false;
|
||||
usbredirSupport = false;
|
||||
canokeySupport = false;
|
||||
hostCpuTargets = [ "x86_64-softmmu" ];
|
||||
}).overrideDerivation (old: {
|
||||
postFixup = ''
|
||||
rm -r "$out/share/icons"
|
||||
cp "${pkgs.OVMF.fd + "/FV/OVMF.fd"}" "$out/share/qemu/"
|
||||
'';
|
||||
configureFlags = old.configureFlags ++ [
|
||||
"--disable-tcg"
|
||||
"--disable-tcg-interpreter"
|
||||
"--disable-docs"
|
||||
"--disable-install-blobs"
|
||||
"--disable-slirp"
|
||||
"--disable-virtfs"
|
||||
"--disable-virtfs-proxy-helper"
|
||||
"--disable-vhost-user-blk-server"
|
||||
"--without-default-features"
|
||||
"--enable-kvm"
|
||||
"--disable-tools"
|
||||
];
|
||||
})
|
|
@ -1,48 +0,0 @@
|
|||
{ prev, ... }:
|
||||
|
||||
prev.systemd.override {
|
||||
withAcl = false;
|
||||
withAnalyze = false;
|
||||
withApparmor = false;
|
||||
withAudit = false;
|
||||
withEfi = true;
|
||||
withCompression = false;
|
||||
withCoredump = false;
|
||||
withCryptsetup = false;
|
||||
withRepart = false;
|
||||
withDocumentation = false;
|
||||
withFido2 = false;
|
||||
withFirstboot = false;
|
||||
withHomed = false;
|
||||
withHostnamed = false;
|
||||
withHwdb = false;
|
||||
withImportd = false;
|
||||
withIptables = false;
|
||||
withKmod = false;
|
||||
withLibBPF = false;
|
||||
withLibidn2 = false;
|
||||
withLocaled = false;
|
||||
withLogind = false;
|
||||
withMachined = false;
|
||||
withNetworkd = false;
|
||||
withNss = false;
|
||||
withOomd = false;
|
||||
withPam = false;
|
||||
withPasswordQuality = false;
|
||||
withPCRE2 = false;
|
||||
withPolkit = false;
|
||||
withPortabled = false;
|
||||
withQrencode = false;
|
||||
withRemote = false;
|
||||
withResolved = false;
|
||||
withShellCompletions = false;
|
||||
withSysusers = false;
|
||||
withSysupdate = false;
|
||||
withTimedated = false;
|
||||
withTimesyncd = false;
|
||||
withTpm2Tss = false;
|
||||
withUkify = true;
|
||||
withUserDb = false;
|
||||
withUtmp = false;
|
||||
withVmspawn = false;
|
||||
}
|
21
systemd/0017-meson.build-do-not-create-systemdstatedir.patch
Normal file
21
systemd/0017-meson.build-do-not-create-systemdstatedir.patch
Normal file
|
@ -0,0 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: nikstur <nikstur@outlook.com>
|
||||
Date: Mon, 6 Nov 2023 22:51:38 +0100
|
||||
Subject: [PATCH] meson.build: do not create systemdstatedir
|
||||
|
||||
---
|
||||
meson.build | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index bffda86845..cb5dcec0f9 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -2781,7 +2781,6 @@ install_data('LICENSE.GPL2',
|
||||
install_subdir('LICENSES',
|
||||
install_dir : docdir)
|
||||
|
||||
-install_emptydir(systemdstatedir)
|
||||
|
||||
#####################################################################
|
||||
|
324
systemd/default.nix
Normal file
324
systemd/default.nix
Normal file
|
@ -0,0 +1,324 @@
|
|||
{
|
||||
fetchFromGitHub,
|
||||
lib,
|
||||
pkgs,
|
||||
stdenv,
|
||||
targetPackages,
|
||||
...
|
||||
}:
|
||||
let
|
||||
version = "257.3";
|
||||
|
||||
# Use the command below to update `releaseTimestamp` on every (major) version
|
||||
# change. More details in the commentary at mesonFlags.
|
||||
# command:
|
||||
# $ curl -s https://api.github.com/repos/systemd/systemd/releases/latest | \
|
||||
# jq '.created_at|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime'
|
||||
releaseTimestamp = "1734643670";
|
||||
|
||||
pname = "systemd";
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
inherit version;
|
||||
|
||||
pname = pname;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "systemd";
|
||||
repo = "systemd";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-GvRn55grHWR6M+tA86RMzqinuXNpPZzRB4ApuGN/ZvU=";
|
||||
};
|
||||
|
||||
dontCheckForBrokenSymlinks = true;
|
||||
|
||||
patches = [
|
||||
./0017-meson.build-do-not-create-systemdstatedir.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
bash
|
||||
pkg-config
|
||||
makeBinaryWrapper
|
||||
gperf
|
||||
ninja
|
||||
meson
|
||||
glibcLocales
|
||||
getent
|
||||
m4
|
||||
autoPatchelfHook
|
||||
|
||||
intltool
|
||||
gettext
|
||||
|
||||
libxslt
|
||||
docbook_xsl
|
||||
docbook_xml_dtd_42
|
||||
docbook_xml_dtd_45
|
||||
bash
|
||||
(buildPackages.python3Packages.python.withPackages (
|
||||
ps: with ps; [
|
||||
lxml
|
||||
jinja2
|
||||
ps.pyelftools
|
||||
]
|
||||
))
|
||||
|
||||
bpftools
|
||||
buildPackages.llvmPackages.clang
|
||||
buildPackages.llvmPackages.libllvm
|
||||
];
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"dev"
|
||||
];
|
||||
|
||||
separateDebugInfo = true;
|
||||
|
||||
autoPatchelfFlags = [ "--keep-libc" ];
|
||||
|
||||
hardeningDisable = [
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111523
|
||||
"trivialautovarinit"
|
||||
# breaks clang -target bpf; should be fixed to filter target?
|
||||
"zerocallusedregs"
|
||||
"shadowstack"
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
libxcrypt
|
||||
libcap
|
||||
libuuid
|
||||
linuxHeaders
|
||||
bashInteractive # for patch shebangs
|
||||
libgcrypt
|
||||
libgpg-error
|
||||
openssl
|
||||
acl
|
||||
libapparmor
|
||||
audit
|
||||
zlib
|
||||
bzip2
|
||||
lz4
|
||||
xz
|
||||
zstd
|
||||
elfutils
|
||||
kexec-tools
|
||||
kmod
|
||||
libidn2
|
||||
libseccomp
|
||||
libselinux
|
||||
iptables
|
||||
p11-kit
|
||||
libfido2
|
||||
pam
|
||||
pcre2
|
||||
libbpf
|
||||
tpm2-tss
|
||||
qrencode
|
||||
libarchive
|
||||
(lib.getDev curl)
|
||||
(lib.getDev cryptsetup.dev)
|
||||
(python3Packages.python.withPackages (ps: with ps; [ pefile ]))
|
||||
(llvmPackages.compiler-rt.override {
|
||||
doFakeLibgcc = true;
|
||||
})
|
||||
];
|
||||
|
||||
mesonBuildType = "release";
|
||||
|
||||
doCheck = false; # fails a bunch of tests
|
||||
|
||||
preConfigure = ''
|
||||
mesonFlagsArray+=(-Dntp-servers="0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org")
|
||||
export LC_ALL="en_US.UTF-8";
|
||||
'';
|
||||
|
||||
postPatch =
|
||||
''
|
||||
substituteInPlace meson.build \
|
||||
--replace "find_program('clang'" "find_program('${stdenv.cc.targetPrefix}clang'"
|
||||
''
|
||||
+ ''
|
||||
substituteInPlace src/ukify/ukify.py \
|
||||
--replace \
|
||||
"'readelf'" \
|
||||
"'${targetPackages.stdenv.cc.bintools.targetPrefix}readelf'" \
|
||||
--replace \
|
||||
"/usr/lib/systemd/boot/efi" \
|
||||
"$out/usr/lib/systemd/boot/efi"
|
||||
''
|
||||
# Finally, patch shebangs in scripts used at build time. This must not patch
|
||||
# scripts that will end up in the output, to avoid build platform references
|
||||
# when cross-compiling.
|
||||
+ ''
|
||||
shopt -s extglob
|
||||
patchShebangs tools test src/!(rpm|kernel-install|ukify) src/kernel-install/test-kernel-install.sh
|
||||
'';
|
||||
|
||||
# trigger the test -n "$DESTDIR" || mutate in upstreams build system
|
||||
preInstall = ''
|
||||
export DESTDIR=${placeholder "out"}
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
|
||||
"--prefix=/usr"
|
||||
"--sysconfdir=/etc"
|
||||
"--localstatedir=/var"
|
||||
"--libdir=/usr/lib"
|
||||
"--bindir=/usr/bin"
|
||||
"--includedir=/usr/include"
|
||||
"--localedir=/usr/share/locale"
|
||||
|
||||
# Options
|
||||
|
||||
# We bump this attribute on every (major) version change to ensure that we
|
||||
# have known-good value for a timestamp that is in the (not so distant)
|
||||
# past. This serves as a lower bound for valid system timestamps during
|
||||
# startup. Systemd will reset the system timestamp if this date is +- 15
|
||||
# years from the system time.
|
||||
# See the systemd v250 release notes for further details:
|
||||
# https://github.com/systemd/systemd/blob/60e930fc3e6eb8a36fbc184773119eb8d2f30364/NEWS#L258-L266
|
||||
(lib.mesonOption "time-epoch" releaseTimestamp)
|
||||
|
||||
(lib.mesonOption "version-tag" version)
|
||||
(lib.mesonOption "mode" "release")
|
||||
(lib.mesonOption "tty-gid" "3") # tty in NixOS has gid 3
|
||||
|
||||
(lib.mesonOption "kmod-path" "/usr/bin/kmod")
|
||||
(lib.mesonOption "debug-shell" "/usr/bin/sh")
|
||||
(lib.mesonOption "pamconfdir" "/etc/pam.d")
|
||||
(lib.mesonOption "shellprofiledir" "/etc/profile.d")
|
||||
(lib.mesonOption "dbuspolicydir" "/usr/share/dbus-1/system.d")
|
||||
(lib.mesonOption "dbussessionservicedir" "/usr/share/dbus-1/services")
|
||||
(lib.mesonOption "dbussystemservicedir" "/usr/share/dbus-1/system-services")
|
||||
(lib.mesonOption "setfont-path" "/usr/bin/setfont")
|
||||
(lib.mesonOption "loadkeys-path" "/usr/bin/loadkeys")
|
||||
(lib.mesonOption "sulogin-path" "/usr/bin/sulogin")
|
||||
(lib.mesonOption "nologin-path" "/usr/bin/nologin")
|
||||
(lib.mesonOption "mount-path" "/usr/bin/mount")
|
||||
(lib.mesonOption "umount-path" "/usr/bin/umount")
|
||||
|
||||
# SBAT
|
||||
(lib.mesonOption "sbat-distro" "patos")
|
||||
(lib.mesonOption "sbat-distro-summary" "PatOS")
|
||||
(lib.mesonOption "sbat-distro-url" "https://patagia.io/")
|
||||
(lib.mesonOption "sbat-distro-pkgname" pname)
|
||||
(lib.mesonOption "sbat-distro-version" version)
|
||||
|
||||
# Users
|
||||
(lib.mesonOption "system-uid-max" "999")
|
||||
(lib.mesonOption "system-gid-max" "999")
|
||||
|
||||
# SysVinit
|
||||
(lib.mesonOption "sysvinit-path" "")
|
||||
(lib.mesonOption "sysvrcnd-path" "")
|
||||
|
||||
# SSH
|
||||
# Disabled for now until someone makes this work.
|
||||
(lib.mesonOption "sshconfdir" "no")
|
||||
(lib.mesonOption "sshdconfdir" "no")
|
||||
|
||||
# Features
|
||||
|
||||
# Tests
|
||||
(lib.mesonBool "tests" false)
|
||||
(lib.mesonEnable "glib" false)
|
||||
(lib.mesonEnable "dbus" false)
|
||||
|
||||
# Compression
|
||||
(lib.mesonEnable "bzip2" true)
|
||||
(lib.mesonEnable "lz4" true)
|
||||
(lib.mesonEnable "xz" true)
|
||||
(lib.mesonEnable "zstd" true)
|
||||
(lib.mesonEnable "zlib" true)
|
||||
|
||||
# NSS
|
||||
(lib.mesonEnable "nss-resolve" true)
|
||||
(lib.mesonBool "nss-myhostname" true)
|
||||
(lib.mesonBool "nss-systemd" true)
|
||||
|
||||
# Cryptsetup
|
||||
(lib.mesonEnable "libcryptsetup" true)
|
||||
(lib.mesonEnable "libcryptsetup-plugins" true)
|
||||
(lib.mesonEnable "p11kit" true)
|
||||
|
||||
# FIDO2
|
||||
(lib.mesonEnable "libfido2" true)
|
||||
(lib.mesonEnable "openssl" true)
|
||||
|
||||
# Password Quality
|
||||
(lib.mesonEnable "pwquality" false)
|
||||
(lib.mesonEnable "passwdqc" false)
|
||||
|
||||
# Remote
|
||||
(lib.mesonEnable "remote" false)
|
||||
(lib.mesonEnable "microhttpd" false)
|
||||
|
||||
(lib.mesonEnable "pam" false)
|
||||
(lib.mesonEnable "acl" true)
|
||||
(lib.mesonEnable "audit" true)
|
||||
(lib.mesonEnable "apparmor" true)
|
||||
(lib.mesonEnable "gcrypt" true)
|
||||
(lib.mesonEnable "importd" true)
|
||||
(lib.mesonEnable "homed" false)
|
||||
(lib.mesonEnable "polkit" true)
|
||||
(lib.mesonEnable "elfutils" true)
|
||||
(lib.mesonEnable "libcurl" true)
|
||||
(lib.mesonEnable "libidn" false)
|
||||
(lib.mesonEnable "libidn2" true)
|
||||
(lib.mesonEnable "libiptc" true)
|
||||
(lib.mesonEnable "repart" true)
|
||||
(lib.mesonEnable "sysupdate" true)
|
||||
(lib.mesonEnable "sysupdated" true)
|
||||
(lib.mesonEnable "seccomp" true)
|
||||
(lib.mesonEnable "selinux" true)
|
||||
(lib.mesonEnable "tpm2" true)
|
||||
(lib.mesonEnable "pcre2" true)
|
||||
(lib.mesonEnable "bpf-framework" true)
|
||||
(lib.mesonEnable "bootloader" true)
|
||||
(lib.mesonEnable "ukify" true)
|
||||
(lib.mesonEnable "kmod" true)
|
||||
(lib.mesonEnable "qrencode" true)
|
||||
(lib.mesonEnable "vmspawn" false)
|
||||
(lib.mesonEnable "libarchive" true)
|
||||
(lib.mesonEnable "xenctrl" false)
|
||||
(lib.mesonEnable "gnutls" false)
|
||||
(lib.mesonEnable "xkbcommon" false)
|
||||
(lib.mesonEnable "man" false)
|
||||
|
||||
(lib.mesonBool "analyze" true)
|
||||
(lib.mesonBool "logind" true)
|
||||
(lib.mesonBool "localed" false)
|
||||
(lib.mesonBool "hostnamed" true)
|
||||
(lib.mesonBool "machined" true)
|
||||
(lib.mesonBool "networkd" true)
|
||||
(lib.mesonBool "oomd" true)
|
||||
(lib.mesonBool "portabled" true)
|
||||
(lib.mesonBool "hwdb" true)
|
||||
(lib.mesonBool "timedated" true)
|
||||
(lib.mesonBool "timesyncd" true)
|
||||
(lib.mesonBool "userdb" false)
|
||||
(lib.mesonBool "coredump" true)
|
||||
(lib.mesonBool "firstboot" true)
|
||||
(lib.mesonBool "resolve" true)
|
||||
(lib.mesonBool "sysusers" true)
|
||||
(lib.mesonBool "efi" true)
|
||||
(lib.mesonBool "utmp" true)
|
||||
(lib.mesonBool "log-trace" true)
|
||||
|
||||
(lib.mesonBool "kernel-install" true)
|
||||
(lib.mesonBool "quotacheck" false)
|
||||
(lib.mesonBool "ldconfig" false)
|
||||
(lib.mesonBool "install-sysconfdir" true)
|
||||
(lib.mesonBool "create-log-dirs" true)
|
||||
(lib.mesonBool "smack" true)
|
||||
(lib.mesonBool "b_pie" true)
|
||||
|
||||
(lib.mesonOption "bashcompletiondir" "no")
|
||||
(lib.mesonOption "zshcompletiondir" "no")
|
||||
];
|
||||
|
||||
})
|
155
tests/common.nix
155
tests/common.nix
|
@ -1,155 +0,0 @@
|
|||
{
|
||||
self,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with import (pkgs.path + "/nixos/lib/testing-python.nix") {
|
||||
inherit pkgs;
|
||||
inherit (pkgs.hostPlatform) system;
|
||||
};
|
||||
|
||||
let
|
||||
qemu-common = import (pkgs.path + "/nixos/lib/qemu-common.nix") { inherit lib pkgs; };
|
||||
|
||||
in
|
||||
rec {
|
||||
|
||||
makeSystem =
|
||||
extraConfig:
|
||||
(import (pkgs.path + "/nixos/lib/eval-config.nix")) {
|
||||
inherit pkgs lib;
|
||||
system = null;
|
||||
modules = [
|
||||
{
|
||||
nixpkgs.hostPlatform = pkgs.hostPlatform;
|
||||
}
|
||||
{
|
||||
users.allowNoPasswordLogin = true;
|
||||
system.stateVersion = lib.versions.majorMinor lib.version;
|
||||
system.image.id = lib.mkDefault "test";
|
||||
system.image.version = lib.mkDefault "1";
|
||||
networking.hosts."10.0.2.1" = [ "server.test" ];
|
||||
}
|
||||
{
|
||||
boot.kernelParams = [
|
||||
"console=ttyS0,115200n8"
|
||||
"systemd.journald.forward_to_console=1"
|
||||
];
|
||||
image.compress = false;
|
||||
boot.uki.name = lib.mkForce "test";
|
||||
boot.initrd.compressor = lib.mkForce "zstd";
|
||||
boot.initrd.compressorArgs = lib.mkForce [ "-8" ];
|
||||
}
|
||||
(pkgs.path + "/nixos/modules/testing/test-instrumentation.nix")
|
||||
self.nixosModules.devel
|
||||
self.nixosModules.image
|
||||
extraConfig
|
||||
];
|
||||
};
|
||||
|
||||
makeImage =
|
||||
extraConfig:
|
||||
let
|
||||
system = makeSystem extraConfig;
|
||||
in
|
||||
"${system.config.system.build.image}/${system.config.system.build.image.imageFile}";
|
||||
|
||||
makeUpdatePackage =
|
||||
extraConfig:
|
||||
let
|
||||
system = makeSystem extraConfig;
|
||||
in
|
||||
"${system.config.system.build.updatePackage}";
|
||||
|
||||
makeImageTest =
|
||||
{
|
||||
name,
|
||||
image,
|
||||
script,
|
||||
httpRoot ? null,
|
||||
}:
|
||||
let
|
||||
qemu = qemu-common.qemuBinary pkgs.qemu_test;
|
||||
flags = [
|
||||
"-m"
|
||||
"512M"
|
||||
"-drive"
|
||||
"if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}"
|
||||
"-drive"
|
||||
"if=pflash,format=raw,unit=1,readonly=on,file=${pkgs.OVMF.variables}"
|
||||
"-drive"
|
||||
"if=virtio,file=${mutableImage}"
|
||||
"-chardev"
|
||||
"socket,id=chrtpm,path=${tpmFolder}/swtpm-sock"
|
||||
"-tpmdev"
|
||||
"emulator,id=tpm0,chardev=chrtpm"
|
||||
"-device"
|
||||
"tpm-tis,tpmdev=tpm0"
|
||||
"-netdev"
|
||||
(
|
||||
"'user,id=net0"
|
||||
+ (lib.optionalString (
|
||||
httpRoot != null
|
||||
) ",guestfwd=tcp:10.0.2.1:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${httpRoot}")
|
||||
+ "'"
|
||||
)
|
||||
"-device"
|
||||
"virtio-net-pci,netdev=net0"
|
||||
];
|
||||
flagsStr = lib.concatStringsSep " " flags;
|
||||
startCommand = "${qemu} ${flagsStr}";
|
||||
mutableImage = "/tmp/linked-image.qcow2";
|
||||
tpmFolder = "/tmp/emulated_tpm";
|
||||
indentLines = str: lib.concatLines (map (s: " " + s) (lib.splitString "\n" str));
|
||||
in
|
||||
makeTest {
|
||||
inherit name;
|
||||
nodes = { };
|
||||
testScript =
|
||||
''
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
subprocess.check_call(
|
||||
[
|
||||
"qemu-img",
|
||||
"create",
|
||||
"-f",
|
||||
"qcow2",
|
||||
"-F",
|
||||
"raw",
|
||||
"-b",
|
||||
"${image}",
|
||||
"${mutableImage}",
|
||||
]
|
||||
)
|
||||
subprocess.check_call(["qemu-img", "resize", "${mutableImage}", "4G"])
|
||||
|
||||
os.mkdir("${tpmFolder}")
|
||||
os.mkdir("${tpmFolder}/swtpm")
|
||||
|
||||
def start_tpm():
|
||||
subprocess.Popen(
|
||||
[
|
||||
"${pkgs.swtpm}/bin/swtpm",
|
||||
"socket",
|
||||
"--tpmstate", "dir=${tpmFolder}/swtpm",
|
||||
"--ctrl", "type=unixio,path=${tpmFolder}/swtpm-sock",
|
||||
"--tpm2"
|
||||
]
|
||||
)
|
||||
|
||||
machine = create_machine("${startCommand}")
|
||||
|
||||
try:
|
||||
''
|
||||
+ indentLines script
|
||||
+ ''
|
||||
finally:
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
test:
|
||||
{ pkgs, self }:
|
||||
let nixos-lib = import (pkgs.path + "/nixos/lib") {};
|
||||
in (nixos-lib.runTest {
|
||||
hostPkgs = pkgs;
|
||||
defaults.documentation.enable = false;
|
||||
node.specialArgs = { inherit self; };
|
||||
imports = [ test ];
|
||||
}).config.result
|
|
@ -1,22 +0,0 @@
|
|||
{ pkgs, self }: let
|
||||
|
||||
lib = pkgs.lib;
|
||||
test-common = import ./common.nix { inherit self lib pkgs; };
|
||||
|
||||
image = test-common.makeImage { };
|
||||
|
||||
in test-common.makeImageTest {
|
||||
name = "podman";
|
||||
inherit image;
|
||||
script = ''
|
||||
start_tpm()
|
||||
machine.start()
|
||||
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("network-online.target")
|
||||
|
||||
machine.succeed("tar cv --files-from /dev/null | su admin -l -c 'podman import - scratchimg'")
|
||||
|
||||
machine.succeed("su admin -l -c 'podman run --rm -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg true'")
|
||||
'';
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
{ pkgs, self }: let
|
||||
|
||||
lib = pkgs.lib;
|
||||
test-common = import ./common.nix { inherit self lib pkgs; };
|
||||
|
||||
initialImage = test-common.makeImage {
|
||||
system.image.version = "1";
|
||||
system.image.updates.url = "http://server.test/";
|
||||
# The default root-b is too small for uncompressed test images
|
||||
systemd.repart.partitions."32-root-b" = {
|
||||
SizeMinBytes = lib.mkForce "1G";
|
||||
SizeMaxBytes = lib.mkForce "1G";
|
||||
};
|
||||
};
|
||||
|
||||
updatePackage = test-common.makeUpdatePackage {
|
||||
system.image.version = "2";
|
||||
system.image.updates.url = "http://server.test/";
|
||||
};
|
||||
|
||||
in test-common.makeImageTest {
|
||||
name = "system-update";
|
||||
image = initialImage;
|
||||
httpRoot = updatePackage;
|
||||
script = ''
|
||||
start_tpm()
|
||||
machine.start()
|
||||
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("network-online.target")
|
||||
|
||||
machine.succeed("/run/current-system/sw/lib/systemd/systemd-sysupdate update")
|
||||
|
||||
machine.shutdown()
|
||||
|
||||
start_tpm()
|
||||
machine.start()
|
||||
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
machine.succeed('. /etc/os-release; [ "$IMAGE_VERSION" == "2" ]')
|
||||
|
||||
machine.wait_for_unit("systemd-bless-boot.service")
|
||||
'';
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
pkgs.writeShellApplication {
|
||||
name = "qemu-uefi-tpm";
|
||||
|
||||
runtimeInputs = with pkgs; [
|
||||
qemu
|
||||
swtpm
|
||||
];
|
||||
|
||||
text =
|
||||
let
|
||||
tpmOVMF = pkgs.OVMF.override { tpmSupport = true; };
|
||||
in
|
||||
''
|
||||
set -ex
|
||||
state="/tmp/patos-qemu-$USER"
|
||||
rm -rf "$state"
|
||||
mkdir -m 700 "$state"
|
||||
qemu-img create -f qcow2 -F raw -b "$(readlink -e "$1")" "$state/disk.qcow2" 10G
|
||||
|
||||
swtpm socket -d --tpmstate dir="$state" \
|
||||
--ctrl type=unixio,path="$state/swtpm-sock" \
|
||||
--tpm2 \
|
||||
--log level=20
|
||||
|
||||
qemu-system-x86_64 \
|
||||
-enable-kvm \
|
||||
-machine q35,accel=kvm \
|
||||
-cpu host \
|
||||
-smp 8 \
|
||||
-m 4G \
|
||||
-display none \
|
||||
-virtfs "local,path=/tmp,security_model=mapped,mount_tag=shared" \
|
||||
-chardev "stdio,id=char0,mux=on,logfile=$state/console.log,signal=off" \
|
||||
-serial chardev:char0 \
|
||||
-mon chardev=char0 \
|
||||
-drive "if=pflash,format=raw,unit=0,readonly=on,file=${tpmOVMF.firmware}" \
|
||||
-drive "if=pflash,format=raw,unit=1,readonly=on,file=${tpmOVMF.variables}" \
|
||||
-chardev socket,id=chrtpm,path="$state/swtpm-sock" \
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
-device tpm-tis,tpmdev=tpm0 \
|
||||
-netdev id=net00,type=user,hostfwd=tcp::2222-:22 \
|
||||
-device virtio-net-pci,netdev=net00 \
|
||||
-drive "format=qcow2,file=$state/disk.qcow2"
|
||||
'';
|
||||
}
|
Loading…
Add table
Reference in a new issue