commit b6c435d0651fe52d23712ad27213aed7c50d2197 Author: Jakob Lechner Date: Fri Sep 19 16:43:25 2025 +0200 initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..184e2e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.env +.direnv diff --git a/initrd-find-nixos-closure.sh b/initrd-find-nixos-closure.sh new file mode 100644 index 0000000..c508d53 --- /dev/null +++ b/initrd-find-nixos-closure.sh @@ -0,0 +1 @@ +false diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..4555259 --- /dev/null +++ b/run.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +source .env + +script="$(mktemp)" +files="$(mktemp)" +result="$(mktemp -d)" + +git ls-files > "$files" + +trap 'rm -f "$script" "$files"; rm -rf "$result"' EXIT + +cat > "$script" << EOF + if nix build -f system.nix -o "$result/out"; then + [ "$LIBVIRT_DOMAIN" ] && virsh reset $LIBVIRT_DOMAIN + "$result/out/bin/pixiecore" + else + echo "Build failed" >&2 + exit 1 + fi +EOF +chmod +x "$script" + +watchexec -w . -r --filter-file "$files" -- "$script" diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..39110b0 --- /dev/null +++ b/shell.nix @@ -0,0 +1,6 @@ +{ pkgs ? import {} }: + pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + watchexec + ]; +} diff --git a/system.nix b/system.nix new file mode 100644 index 0000000..756ec5d --- /dev/null +++ b/system.nix @@ -0,0 +1,216 @@ +let + nixpkgs = builtins.getFlake "github:nixos/nixpkgs/e9b7f2ff62b35f711568b1f0866243c7c302028d"; + + sys = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ({ + pkgs, + config, + lib, + ... + }: { + config = let + busybox = (pkgs.busybox.override { enableStatic = true; }); + path = pkgs.lib.makeBinPath config.boot.initrd.systemd.initrdBin; + in + { + console.keyMap = "neo"; + + fileSystems."/" = { + fsType = "tmpfs"; + options = [ "mode=0755" ]; + }; + + systemd.repart.partitions = { + "10-esp" = { + Type = "esp"; + SizeMinBytes = "1G"; + SizeMaxBytes = "1G"; + }; + "20-btrfs" = { + Type = "linux-generic"; + }; + }; + + boot.loader.grub.enable = false; + boot.initrd = { + availableKernelModules = [ + "ahci" + "ata_piix" + "nvme" + "pata_marvell" + "sata_nv" + "sata_sis" + "sata_uli" + "sata_via" + "scsi_mod" + "sd_mod" + "sg" + "virtio_blk" + "virtio_pci" + "virtio_scsi" + "virtio_net" + "qxl" + ]; + kernelModules = [ + "loop" + "btrfs" + "zram" + ]; + systemd = { + enable = true; + repart = { + enable = true; + empty = "require"; + #empty = "force"; + device = "/dev/vda"; + discard = true; + }; + root = "fstab"; + + initrdBin = [ + busybox + pkgs.btrfs-progs + pkgs.nixStatic + pkgs.systemd + pkgs.util-linux + pkgs.git + ]; + + storePaths = [ + { + source = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + target = "/etc/ssl/certs/ca-bundle.crt"; + } + { + source = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + target = "/etc/ssl/certs/ca-certificates.crt"; + } + { + source = "${pkgs.ncurses}/share/terminfo"; + target = "/run/current-system/sw/share/terminfo"; + } + { + source = pkgs.writeText "nix.conf" '' + experimental-features = nix-command flakes + download-buffer-size = 536870912 + max-jobs = 1 + build-users-group = + sandbox = true + ''; + target = "/etc/nix/nix.conf"; + } + pkgs.git + ]; + + network = { + enable = true; + wait-online.enable = true; + networks."10-lan" = { + enable = true; + matchConfig.Name = "enp1s0"; + address = [ "192.168.122.110/24" ]; + gateway = [ "192.168.122.1" ]; + linkConfig.RequiredForOnline = "routable"; + }; + }; + + mounts = [ + { + type = "btrfs"; + what = "/dev/vda2"; + where = "/sysroot/nix"; + options = "nodev,noatime,compress-force=zstd:1,discard=async"; + before = [ "initrd-root-fs.target" ]; + } + ]; + + services = { + initrd-nixos-activation.unitConfig.RequiresMountsFor = ["/sysroot/nix"]; + + initrd-parse-etc = { + after = ["initrd-find-nixos-closure.service"]; + }; + + systemd-tmpfiles-setup-sysroot = { + after = ["initrd-find-nixos-closure.service"]; + unitConfig.RequiresMountsFor = lib.mkForce ["/sysroot"]; + }; + + zramswap = { + description = "Create zram swap"; + before = ["initrd-find-nixos-closure.service"]; + script = '' + export PATH="$PATH:${path}" + mem_total_kb=$(sed -n -r 's/^MemTotal:\s*([0-9]*) kB$/\1/p' /proc/meminfo) + zramctl /dev/zram0 --algorithm zstd --size "$((mem_total_kb / 10 * 6))KiB" + mkswap -U clear /dev/zram0 + swapon --discard --priority 100 /dev/zram0 + ''; + }; + + emergency.serviceConfig.AmbientCapabilities = "~"; + + initrd-find-nixos-closure = { + description = lib.mkForce "Build NixOS closure"; + after = [ "dbus.service" ]; + bindsTo = ["initrd-root-fs.target"]; + requires = [ "dbus.service" ]; + unitConfig.RequiresMountsFor = lib.mkForce ["/sysroot/nix"]; + serviceConfig = { + KillMode = "process"; + RemainAfterExit = true; + StandardOutput = "tty"; + TTYPath = "/dev/tty1"; + }; + script = lib.mkForce ( + '' + export PATH="$PATH:${path}" + set -x + set -e + '' + (builtins.readFile ./initrd-find-nixos-closure.sh) + ); + }; + }; + }; + }; + }; + }) + ]; + }; + + run-pixiecore = let + hostPkgs = if sys.pkgs.system == builtins.currentSystem + then sys.pkgs + else nixpkgs.legacyPackages.${builtins.currentSystem}; + inherit (sys.config.system) build; + inherit (sys) pkgs; + inherit (pkgs) lib; + kernel = "${pkgs.linux}/bzImage"; + initrd = "${build.initialRamdisk}/initrd"; + cmdLine = lib.strings.concatStringsSep " " [ + "loglevel=4" + "systemd.setenv=SYSTEMD_SULOGIN_FORCE=1" + "rd.systemd.debug_shell" + "nonroot_initramfs" + ]; + in ( + hostPkgs.writeShellApplication { + name = "pixiecore"; + runtimeInputs = [ hostPkgs.pixiecore ]; + text = lib.strings.concatStringsSep " " [ "exec ${hostPkgs.pixiecore}/bin/pixiecore" + "boot ${kernel} ${initrd}" + "--cmdline '${cmdLine}'" + "--debug" + "--dhcp-no-bind" + "--port 64172" + "--status-port 64172" + ''"$@"'' + ]; + } + ).overrideAttrs (old: { + meta.mainProgram = "pixiecore"; + }); +in + run-pixiecore