Compare commits
4 commits
Author | SHA1 | Date | |
---|---|---|---|
|
9fce4547bb | ||
|
9f1133ce59 | ||
|
dd36fcf195 | ||
|
699075d52c |
32 changed files with 282 additions and 1036 deletions
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
|
@ -11,18 +11,15 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
tag:
|
tag:
|
||||||
- nixos-24.05
|
- nixos-23.05
|
||||||
- nixos-unstable
|
- nixos-unstable
|
||||||
os:
|
runs-on: ubuntu-latest
|
||||||
- nscloud-ubuntu-22.04-arm64-4x16
|
|
||||||
- ubuntu-latest
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: cachix/install-nix-action@v30
|
- uses: cachix/install-nix-action@v21
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixpkgs-unstable.tar.gz
|
nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixpkgs-unstable.tar.gz
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: ./build-images.sh "${{ matrix.tag }}" "$(nix eval --raw --impure --expr builtins.currentSystem)"
|
run: ./build-images.sh "${{matrix.tag}}"
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
6
.github/workflows/update-flake-lock.yml
vendored
6
.github/workflows/update-flake-lock.yml
vendored
|
@ -9,11 +9,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v30
|
uses: cachix/install-nix-action@v21
|
||||||
- name: Update flake.lock
|
- name: Update flake.lock
|
||||||
uses: DeterminateSystems/update-flake-lock@v24
|
uses: DeterminateSystems/update-flake-lock@v19
|
||||||
with:
|
with:
|
||||||
pr-labels: |
|
pr-labels: |
|
||||||
merge-queue
|
merge-queue
|
||||||
|
|
25
.mergify.yml
25
.mergify.yml
|
@ -1,11 +1,32 @@
|
||||||
queue_rules:
|
queue_rules:
|
||||||
- name: default
|
- name: default
|
||||||
merge_conditions:
|
merge_conditions:
|
||||||
- check-success=buildbot/nix-build
|
- check-success=Evaluate flake.nix
|
||||||
|
- check-success=check kexec-installer-2305 [x86_64-linux]
|
||||||
|
- check-success=check kexec-installer-unstable [x86_64-linux]
|
||||||
|
- check-success=check shellcheck [x86_64-linux]
|
||||||
|
- check-success=images (nixos-23.05)
|
||||||
|
- check-success=images (nixos-unstable)
|
||||||
|
- check-success=package kexec-installer-nixos-2305 [aarch64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-2305 [x86_64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-2305-noninteractive [aarch64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-2305-noninteractive [x86_64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-unstable [aarch64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-unstable [x86_64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-unstable-noninteractive [aarch64-linux]
|
||||||
|
- check-success=package kexec-installer-nixos-unstable-noninteractive [x86_64-linux]
|
||||||
|
- check-success=package netboot-installer-nixos-2305 [aarch64-linux]
|
||||||
|
- check-success=package netboot-installer-nixos-2305 [x86_64-linux]
|
||||||
|
- check-success=package netboot-installer-nixos-unstable [aarch64-linux]
|
||||||
|
- check-success=package netboot-installer-nixos-unstable [x86_64-linux]
|
||||||
|
- check-success=package netboot-nixos-2305 [aarch64-linux]
|
||||||
|
- check-success=package netboot-nixos-2305 [x86_64-linux]
|
||||||
|
- check-success=package netboot-nixos-unstable [aarch64-linux]
|
||||||
|
- check-success=package netboot-nixos-unstable [x86_64-linux]
|
||||||
defaults:
|
defaults:
|
||||||
actions:
|
actions:
|
||||||
queue:
|
queue:
|
||||||
merge_method: rebase
|
allow_merging_configuration_change: true
|
||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
- name: merge using the merge queue
|
- name: merge using the merge queue
|
||||||
conditions:
|
conditions:
|
||||||
|
|
43
README.md
43
README.md
|
@ -3,6 +3,11 @@
|
||||||
Automatically weekly updated images for NixOS. This project is intended to extend the images created by hydra.nixos.org.
|
Automatically weekly updated images for NixOS. This project is intended to extend the images created by hydra.nixos.org.
|
||||||
We are currently creating the images listed below:
|
We are currently creating the images listed below:
|
||||||
|
|
||||||
|
## Netboot images
|
||||||
|
|
||||||
|
You can boot the netboot image using this [ipxe script](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/netboot-x86_64-linux.ipxe).
|
||||||
|
It consists of the [kernel image](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/bzImage-x86_64-linux) and [initrd](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/bzImage-x86_64-linux).
|
||||||
|
|
||||||
## Kexec tarballs
|
## Kexec tarballs
|
||||||
|
|
||||||
These images are used for unattended remote installation in [nixos-anywhere](https://github.com/numtide/nixos-anywhere).
|
These images are used for unattended remote installation in [nixos-anywhere](https://github.com/numtide/nixos-anywhere).
|
||||||
|
@ -11,10 +16,10 @@ Kexec is a mechanism in Linux to load a new kernel from a running Linux to
|
||||||
replace the current kernel. This is useful for booting the Nixos installer from
|
replace the current kernel. This is useful for booting the Nixos installer from
|
||||||
existing Linux distributions, such as server provider that do not offer a NixOS
|
existing Linux distributions, such as server provider that do not offer a NixOS
|
||||||
option. After running kexec, the NixOS installer exists only in memory. At the
|
option. After running kexec, the NixOS installer exists only in memory. At the
|
||||||
time of writing, this requires secure boot off in BIOS settings and at least 1GB
|
time of writing, this requires at least 1.5GB of physical RAM (swap does not
|
||||||
of physical RAM (swap does not count) in the system. If not enough RAM is available,
|
count) in the system. If not enough RAM is available, the initrd cannot be
|
||||||
the initrd cannot be loaded. Because the NixOS runs only in RAM, users can reformat
|
loaded. Because the NixOS runs only in RAM, users can reformat all the system's
|
||||||
all the system's discs to prepare for a new NixOS installation.
|
discs to prepare for a new NixOS installation.
|
||||||
|
|
||||||
It can be booted as follows by running these commands as root:
|
It can be booted as follows by running these commands as root:
|
||||||
|
|
||||||
|
@ -27,32 +32,12 @@ The kexec installer comes with the following features:
|
||||||
|
|
||||||
- Re-uses ssh host keys from the sshd to not break `.ssh/known_hosts`
|
- Re-uses ssh host keys from the sshd to not break `.ssh/known_hosts`
|
||||||
- Authorized ssh keys are read from `/root/.ssh/authorized_keys`, `/root/.ssh/authorized_keys2` and `/etc/ssh/authorized_keys.d/root`
|
- Authorized ssh keys are read from `/root/.ssh/authorized_keys`, `/root/.ssh/authorized_keys2` and `/etc/ssh/authorized_keys.d/root`
|
||||||
- Static ip addresses and routes are restored after reboot.
|
- (experimental, only tested for nixos-unstable) Static ip addresses and routes
|
||||||
Interface that had dynamic addresses before are configured with DHCP and
|
are restored after reboot. Interface that had dynamic addresses before are
|
||||||
to accept prefixes from ipv6 router advertisement
|
configured with DHCP and to accept prefixes from ipv6 router advertisment
|
||||||
|
|
||||||
The actual kexec happens with a slight delay (6s). This allows for easier
|
|
||||||
|
The actual kexec happens with a slight delay (6s). This allows for easier
|
||||||
integration into automated nixos installation scripts, since you can cleanly
|
integration into automated nixos installation scripts, since you can cleanly
|
||||||
disconnect from the running machine before the kexec takes place. The tarball
|
disconnect from the running machine before the kexec takes place. The tarball
|
||||||
is also designed to be run from NixOS, which can be useful for new installations
|
is also designed to be run from NixOS, which can be useful for new installations
|
||||||
|
|
||||||
## Iso installer images
|
|
||||||
|
|
||||||
This image allows to boot a NixOS installer off a USB-Stick.
|
|
||||||
This installer has been optimized for remote installation i.e.
|
|
||||||
with [nixos-anywhere](https://github.com/numtide/nixos-anywhere) and [clan](https://docs.clan.lol/getting-started/installer/) notably:
|
|
||||||
|
|
||||||
* Enables openssh by default
|
|
||||||
* Generates a random root password on each login
|
|
||||||
* Enables a Tor hidden SSH service so that by using the `torify ssh <hash>.onion`,
|
|
||||||
one can log in from remote machines.
|
|
||||||
* Prints a QR-Code that contains local addresses, the root password
|
|
||||||
* Includes the [IWD](https://wiki.archlinux.org/title/iwd) deamon for easier wifi setups:
|
|
||||||
* Run `iwctl` in the terminal for an interactive wifi setup interface.
|
|
||||||
|
|
||||||
![Screenshot of the installer](https://github.com/nix-community/nixos-images/releases/download/assets/image-installer-screenshot.jpg)
|
|
||||||
|
|
||||||
## Netboot images
|
|
||||||
|
|
||||||
You can boot the netboot image using this [ipxe script](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/netboot-x86_64-linux.ipxe).
|
|
||||||
It consists of the [kernel image](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/bzImage-x86_64-linux) and [initrd](https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/initrd-x86_64-linux).
|
|
||||||
|
|
|
@ -5,54 +5,45 @@ set -xeuo pipefail
|
||||||
shopt -s lastpipe
|
shopt -s lastpipe
|
||||||
|
|
||||||
build_netboot_image() {
|
build_netboot_image() {
|
||||||
declare -r tag=$1 channel=$2 arch=$3 tmp=$4
|
declare -r tag=$1 arch=$2 tmp=$3
|
||||||
img=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.netboot-nixos-${channel//./}")
|
img=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.netboot-${tag//.}")
|
||||||
kernel=$(echo "$img"/*Image)
|
ln -s "$img/bzImage" "$tmp/bzImage-$arch"
|
||||||
kernelName=$(basename "$kernel")
|
echo "$tmp/bzImage-$arch"
|
||||||
ln -s "$kernel" "$tmp/$kernelName-$arch"
|
|
||||||
echo "$tmp/$kernelName-$arch"
|
|
||||||
ln -s "$img/initrd" "$tmp/initrd-$arch"
|
ln -s "$img/initrd" "$tmp/initrd-$arch"
|
||||||
echo "$tmp/initrd-$arch"
|
echo "$tmp/initrd-$arch"
|
||||||
sed -e "s!^kernel $kernelName!kernel https://github.com/nix-community/nixos-images/releases/download/${tag}/$kernelName-${arch}!" \
|
sed -e "s!^kernel bzImage!kernel https://github.com/nix-community/nixos-images/releases/download/${tag}/bzImage-${arch}!" \
|
||||||
-e "s!^initrd initrd!initrd https://github.com/nix-community/nixos-images/releases/download/${tag}/initrd-${arch}!" \
|
-e "s!^initrd initrd!initrd https://github.com/nix-community/nixos-images/releases/download/${tag}/initrd-${arch}!" \
|
||||||
-e "s!initrd=initrd!initrd=initrd-${arch}!" \
|
-e "s!initrd=initrd!initrd=initrd-${arch}!" \
|
||||||
<"$img/netboot.ipxe" \
|
< "$img/netboot.ipxe" \
|
||||||
>"$tmp/netboot-$arch.ipxe"
|
> "$tmp/netboot-$arch.ipxe"
|
||||||
echo "$tmp/netboot-$arch.ipxe"
|
echo "$tmp/netboot-$arch.ipxe"
|
||||||
}
|
}
|
||||||
|
|
||||||
build_kexec_installer() {
|
build_kexec_installer() {
|
||||||
declare -r channel=$1 arch=$2 tmp=$3 variant=$4
|
declare -r tag=$1 arch=$2 tmp=$3 variant=$4
|
||||||
out=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.kexec-installer-nixos-${channel}${variant}")
|
out=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.kexec-installer-${tag//.}${variant}")
|
||||||
echo "$out/nixos-kexec-installer${variant}-$arch.tar.gz"
|
echo "$out/nixos-kexec-installer${variant}-$arch.tar.gz"
|
||||||
}
|
}
|
||||||
|
|
||||||
build_image_installer() {
|
|
||||||
declare -r channel=$1 arch=$2 tmp=$3
|
|
||||||
out=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.image-installer-nixos-${channel//./}")
|
|
||||||
echo "$out/iso/nixos-installer-${arch}.iso"
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
declare -r tag=${1:-nixos-unstable} arch=${2:-x86_64-linux}
|
declare -r tag=${1:-nixos-unstable} arch=${2:-x86_64-linux}
|
||||||
tmp="$(mktemp -d)"
|
tmp="$(mktemp -d)"
|
||||||
trap 'rm -rf -- "$tmp"' EXIT
|
trap 'rm -rf -- "$tmp"' EXIT
|
||||||
(
|
(
|
||||||
channel=$(if [[ "$tag" == nixos-unstable ]]; then echo "unstable"; else echo "stable"; fi)
|
build_kexec_installer "$tag" "$arch" "$tmp" ""
|
||||||
build_kexec_installer "$channel" "$arch" "$tmp" ""
|
build_kexec_installer "$tag" "$arch" "$tmp" "-noninteractive"
|
||||||
build_kexec_installer "$channel" "$arch" "$tmp" "-noninteractive"
|
build_netboot_image "$tag" "$arch" "$tmp"
|
||||||
build_netboot_image "$tag" "$channel" "$arch" "$tmp"
|
|
||||||
build_image_installer "$channel" "$arch" "$tmp"
|
|
||||||
) | readarray -t assets
|
) | readarray -t assets
|
||||||
for asset in "${assets[@]}"; do
|
for asset in "${assets[@]}"; do
|
||||||
pushd "$(dirname "$asset")"
|
pushd "$(dirname "$asset")"
|
||||||
|
sha256sum "$(basename "$asset")" >> "$TMP/sha256sums"
|
||||||
popd
|
popd
|
||||||
done
|
done
|
||||||
|
assets+=("$TMP/sha256sums")
|
||||||
|
|
||||||
if ! gh release view "$tag"; then
|
# Since we cannot atomically update a release, we delete the old one before
|
||||||
gh release create --title "$tag (build $(date +"%Y-%m-%d"))" "$tag"
|
gh release delete "$tag" </dev/null || true
|
||||||
fi
|
gh release create --title "$tag (build $(date +"%Y-%m-%d"))" "$tag" "${assets[@]}" </dev/null
|
||||||
gh release upload --clobber "$tag" "${assets[@]}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|
18
flake.lock
18
flake.lock
|
@ -1,28 +1,28 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixos-stable": {
|
"nixos-2305": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729181673,
|
"lastModified": 1686780367,
|
||||||
"narHash": "sha256-LDiPhQ3l+fBjRATNtnuDZsBS7hqoBtPkKBkhpoBHv3I=",
|
"narHash": "sha256-hEn8ebT32APeDSoT80VUGktqQ4zqI4gCFLzbIZdSuoo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "4eb33fe664af7b41a4c446f87d20c9a0a6321fa3",
|
"rev": "75eb7c2d47fdc01a0d477e9a89eac7ed366fe898",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.05",
|
"ref": "release-23.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixos-unstable": {
|
"nixos-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729450260,
|
"lastModified": 1686718773,
|
||||||
"narHash": "sha256-3GNZr0V4b19RZ5mlyiY/4F8N2pzitvjDU6aHMWjAqLI=",
|
"narHash": "sha256-x+4xs6+jWhFaYwt6REH7e91rm5vt2GCPEfmRdNcHyi4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e3f55158e7587c5a5fdb0e86eb7ca4f455f0928f",
|
"rev": "ba1a6ec548000d4a50719d14e6f73f63016674d5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixos-stable": "nixos-stable",
|
"nixos-2305": "nixos-2305",
|
||||||
"nixos-unstable": "nixos-unstable"
|
"nixos-unstable": "nixos-unstable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
128
flake.nix
128
flake.nix
|
@ -2,84 +2,62 @@
|
||||||
description = "NixOS images";
|
description = "NixOS images";
|
||||||
|
|
||||||
inputs.nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
inputs.nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
||||||
inputs.nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
|
inputs.nixos-2305.url = "github:NixOS/nixpkgs/release-23.05";
|
||||||
|
|
||||||
nixConfig.extra-substituters = [ "https://nix-community.cachix.org" ];
|
nixConfig.extra-substituters = [
|
||||||
nixConfig.extra-trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ];
|
"https://cache.garnix.io"
|
||||||
|
];
|
||||||
|
nixConfig.extra-trusted-public-keys = [
|
||||||
|
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||||
|
];
|
||||||
|
|
||||||
outputs = { self, nixos-unstable, nixos-stable }:
|
outputs = { self, nixos-unstable, nixos-2305 }: let
|
||||||
let
|
supportedSystems = [ "aarch64-linux" "x86_64-linux" ];
|
||||||
supportedSystems = [ "riscv64-linux" ];
|
forAllSystems = nixos-unstable.lib.genAttrs supportedSystems;
|
||||||
forAllSystems = nixos-unstable.lib.genAttrs supportedSystems;
|
in {
|
||||||
in
|
packages = forAllSystems (system: let
|
||||||
{
|
netboot = nixpkgs: (import (nixpkgs + "/nixos/release.nix") {}).netboot.${system};
|
||||||
hydraJobs = { inherit (self) checks; };
|
kexec-installer = nixpkgs: modules: (nixpkgs.legacyPackages.${system}.nixos (modules ++ [self.nixosModules.kexec-installer])).config.system.build.kexecTarball;
|
||||||
packages = forAllSystems (system:
|
netboot-installer = nixpkgs: (nixpkgs.legacyPackages.${system}.nixos [self.nixosModules.netboot-installer]).config.system.build.netboot;
|
||||||
let
|
in {
|
||||||
netboot = nixpkgs: (import (nixpkgs + "/nixos/release.nix") { }).netboot.${system};
|
netboot-nixos-unstable = netboot nixos-unstable;
|
||||||
kexec-installer = nixpkgs: module: (nixpkgs.legacyPackages.${system}.nixos [ module self.nixosModules.kexec-installer ]).config.system.build.kexecTarball;
|
netboot-nixos-2305 = netboot nixos-2305;
|
||||||
netboot-installer = nixpkgs: (nixpkgs.legacyPackages.${system}.nixos [ self.nixosModules.netboot-installer ]).config.system.build.netboot;
|
kexec-installer-nixos-unstable = kexec-installer nixos-unstable [];
|
||||||
image-installer = nixpkgs: (nixpkgs.legacyPackages.${system}.nixos [ self.nixosModules.image-installer ]).config.system.build.isoImage;
|
kexec-installer-nixos-2305 = kexec-installer nixos-2305 [];
|
||||||
in
|
|
||||||
{
|
|
||||||
netboot-nixos-unstable = netboot nixos-unstable;
|
|
||||||
netboot-nixos-stable = netboot nixos-stable;
|
|
||||||
kexec-installer-nixos-unstable = kexec-installer nixos-unstable {};
|
|
||||||
kexec-installer-nixos-stable = kexec-installer nixos-stable {};
|
|
||||||
|
|
||||||
image-installer-nixos-unstable = image-installer nixos-unstable;
|
kexec-installer-nixos-unstable-noninteractive = kexec-installer nixos-unstable [
|
||||||
image-installer-nixos-stable = image-installer nixos-stable;
|
{ system.kexec-installer.name = "nixos-kexec-installer-noninteractive"; }
|
||||||
|
self.nixosModules.noninteractive
|
||||||
|
];
|
||||||
|
kexec-installer-nixos-2305-noninteractive = kexec-installer nixos-2305 [
|
||||||
|
{ system.kexec-installer.name = "nixos-kexec-installer-noninteractive"; }
|
||||||
|
self.nixosModules.noninteractive
|
||||||
|
];
|
||||||
|
|
||||||
kexec-installer-nixos-unstable-noninteractive = kexec-installer nixos-unstable {
|
netboot-installer-nixos-unstable = netboot-installer nixos-unstable;
|
||||||
_file = __curPos.file;
|
netboot-installer-nixos-2305 = netboot-installer nixos-2305;
|
||||||
system.kexec-installer.name = "nixos-kexec-installer-noninteractive";
|
});
|
||||||
imports = [
|
nixosModules = {
|
||||||
self.nixosModules.noninteractive
|
kexec-installer = ./nix/kexec-installer/module.nix;
|
||||||
];
|
noninteractive = ./nix/noninteractive.nix;
|
||||||
};
|
# TODO: also add a test here once we have https://github.com/NixOS/nixpkgs/pull/228346 merged
|
||||||
kexec-installer-nixos-stable-noninteractive = kexec-installer nixos-stable {
|
netboot-installer = ./nix/netboot-installer/module.nix;
|
||||||
_file = __curPos.file;
|
|
||||||
system.kexec-installer.name = "nixos-kexec-installer-noninteractive";
|
|
||||||
imports = [
|
|
||||||
self.nixosModules.noninteractive
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
netboot-installer-nixos-unstable = netboot-installer nixos-unstable;
|
|
||||||
netboot-installer-nixos-stable = netboot-installer nixos-stable;
|
|
||||||
});
|
|
||||||
nixosModules = {
|
|
||||||
kexec-installer = ./nix/kexec-installer/module.nix;
|
|
||||||
noninteractive = ./nix/noninteractive.nix;
|
|
||||||
# TODO: also add a test here once we have https://github.com/NixOS/nixpkgs/pull/228346 merged
|
|
||||||
netboot-installer = ./nix/netboot-installer/module.nix;
|
|
||||||
image-installer = ./nix/image-installer/module.nix;
|
|
||||||
};
|
|
||||||
checks =
|
|
||||||
let
|
|
||||||
# re-export the packages as checks
|
|
||||||
packages = forAllSystems (system: nixos-unstable.lib.mapAttrs' (n: nixos-unstable.lib.nameValuePair "package-${n}") self.packages.${system});
|
|
||||||
checks =
|
|
||||||
let
|
|
||||||
pkgsUnstable = nixos-unstable.legacyPackages.riscv64-linux;
|
|
||||||
pkgsStable = nixos-stable.legacyPackages.riscv64-linux;
|
|
||||||
|
|
||||||
bootTests = pkgs: channel: suffix: pkgs.lib.mapAttrs' (name: pkgs.lib.nameValuePair "${name}${suffix}") (pkgs.callPackages ./nix/image-installer/tests.nix {
|
|
||||||
nixpkgs = channel;
|
|
||||||
nixosModules = self.nixosModules;
|
|
||||||
});
|
|
||||||
in
|
|
||||||
{
|
|
||||||
kexec-installer-unstable = pkgsUnstable.callPackage ./nix/kexec-installer/test.nix {
|
|
||||||
kexecTarball = self.packages.riscv64-linux.kexec-installer-nixos-unstable-noninteractive;
|
|
||||||
};
|
|
||||||
|
|
||||||
kexec-installer-stable = nixos-stable.legacyPackages.riscv64-linux.callPackage ./nix/kexec-installer/test.nix {
|
|
||||||
kexecTarball = self.packages.riscv64-linux.kexec-installer-nixos-stable-noninteractive;
|
|
||||||
};
|
|
||||||
} // (bootTests pkgsUnstable nixos-unstable "-nixos-unstable")
|
|
||||||
// (bootTests pkgsStable nixos-stable "-nixos-stable");
|
|
||||||
in
|
|
||||||
nixos-unstable.lib.recursiveUpdate packages { riscv64-linux = checks; };
|
|
||||||
};
|
};
|
||||||
|
checks.x86_64-linux = let
|
||||||
|
pkgs = nixos-unstable.legacyPackages.x86_64-linux;
|
||||||
|
in {
|
||||||
|
kexec-installer-unstable = pkgs.callPackage ./nix/kexec-installer/test.nix {
|
||||||
|
kexecTarball = self.packages.x86_64-linux.kexec-installer-nixos-unstable-noninteractive;
|
||||||
|
};
|
||||||
|
shellcheck = pkgs.runCommand "shellcheck" {
|
||||||
|
nativeBuildInputs = [ pkgs.shellcheck ];
|
||||||
|
} ''
|
||||||
|
shellcheck ${(pkgs.nixos [self.nixosModules.kexec-installer]).config.system.build.kexecRun}
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
kexec-installer-2305 = nixos-2305.legacyPackages.x86_64-linux.callPackage ./nix/kexec-installer/test.nix {
|
||||||
|
kexecTarball = self.packages.x86_64-linux.kexec-installer-nixos-2305-noninteractive;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
5
garnix.yaml
Normal file
5
garnix.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
builds:
|
||||||
|
include:
|
||||||
|
- '*.x86_64-linux.*'
|
||||||
|
- '*.aarch64-linux.*'
|
||||||
|
- nixosConfigurations.*
|
|
@ -1,63 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
options.hidden-ssh-announce = {
|
|
||||||
enable = lib.mkEnableOption "hidden-ssh-announce";
|
|
||||||
script = lib.mkOption {
|
|
||||||
type = lib.types.package;
|
|
||||||
default = pkgs.writers.writeDash "test-output" "echo $1";
|
|
||||||
description = ''
|
|
||||||
script to run when the hidden tor service was started and they hostname is known.
|
|
||||||
takes the hostname as $1
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf config.hidden-ssh-announce.enable {
|
|
||||||
services.openssh.enable = true;
|
|
||||||
services.tor = {
|
|
||||||
enable = true;
|
|
||||||
relay.onionServices.hidden-ssh = {
|
|
||||||
version = 3;
|
|
||||||
map = [
|
|
||||||
{
|
|
||||||
port = 22;
|
|
||||||
target.port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
client.enable = true;
|
|
||||||
};
|
|
||||||
systemd.services.hidden-ssh-announce = {
|
|
||||||
description = "announce hidden ssh";
|
|
||||||
after = [
|
|
||||||
"tor.service"
|
|
||||||
"network-online.target"
|
|
||||||
];
|
|
||||||
wants = [
|
|
||||||
"tor.service"
|
|
||||||
"network-online.target"
|
|
||||||
];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
# ${pkgs.tor}/bin/torify
|
|
||||||
ExecStart = pkgs.writeShellScript "announce-hidden-service" ''
|
|
||||||
set -efu
|
|
||||||
until test -e ${config.services.tor.settings.DataDirectory}/onion/hidden-ssh/hostname; do
|
|
||||||
echo "still waiting for ${config.services.tor.settings.DataDirectory}/onion/hidden-ssh/hostname"
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
${config.hidden-ssh-announce.script} "$(cat ${config.services.tor.settings.DataDirectory}/onion/hidden-ssh/hostname)"
|
|
||||||
'';
|
|
||||||
PrivateTmp = "true";
|
|
||||||
User = "tor";
|
|
||||||
Type = "oneshot";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
network-status = pkgs.writeShellScriptBin "network-status" ''
|
|
||||||
export PATH=${
|
|
||||||
lib.makeBinPath (
|
|
||||||
with pkgs;
|
|
||||||
[
|
|
||||||
iproute2
|
|
||||||
coreutils
|
|
||||||
gnugrep
|
|
||||||
nettools
|
|
||||||
gum
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
set -efu -o pipefail
|
|
||||||
msgs=()
|
|
||||||
if [[ -e /var/shared/qrcode.utf8 ]]; then
|
|
||||||
qrcode=$(gum style --border-foreground 240 --border normal "$(< /var/shared/qrcode.utf8)")
|
|
||||||
msgs+=("$qrcode")
|
|
||||||
fi
|
|
||||||
network_status="Root password: $(cat /var/shared/root-password)
|
|
||||||
Local network addresses:
|
|
||||||
$(ip -brief -color addr | grep -v 127.0.0.1)
|
|
||||||
$([[ -e /var/shared/onion-hostname ]] && echo "Onion address: $(cat /var/shared/onion-hostname)" || echo "Onion address: Waiting for tor network to be ready...")
|
|
||||||
Multicast DNS: $(hostname).local"
|
|
||||||
network_status=$(gum style --border-foreground 240 --border normal "$network_status")
|
|
||||||
msgs+=("$network_status")
|
|
||||||
msgs+=("Press 'Ctrl-C' for console access")
|
|
||||||
|
|
||||||
gum join --vertical "''${msgs[@]}"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/cd-dvd/installation-cd-base.nix")
|
|
||||||
../installer.nix
|
|
||||||
../noveau-workaround.nix
|
|
||||||
./hidden-ssh-announcement.nix
|
|
||||||
./wifi.nix
|
|
||||||
];
|
|
||||||
systemd.tmpfiles.rules = [ "d /var/shared 0777 root root - -" ];
|
|
||||||
services.openssh.settings.PermitRootLogin = "yes";
|
|
||||||
system.activationScripts.root-password = ''
|
|
||||||
mkdir -p /var/shared
|
|
||||||
${pkgs.xkcdpass}/bin/xkcdpass --numwords 3 --delimiter - --count 1 > /var/shared/root-password
|
|
||||||
echo "root:$(cat /var/shared/root-password)" | chpasswd
|
|
||||||
'';
|
|
||||||
hidden-ssh-announce = {
|
|
||||||
enable = true;
|
|
||||||
script = pkgs.writeShellScript "write-hostname" ''
|
|
||||||
set -efu
|
|
||||||
export PATH=${
|
|
||||||
lib.makeBinPath (
|
|
||||||
with pkgs;
|
|
||||||
[
|
|
||||||
iproute2
|
|
||||||
coreutils
|
|
||||||
jq
|
|
||||||
qrencode
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
mkdir -p /var/shared
|
|
||||||
echo "$1" > /var/shared/onion-hostname
|
|
||||||
local_addrs=$(ip -json addr | jq '[map(.addr_info) | flatten | .[] | select(.scope == "global") | .local]')
|
|
||||||
jq -nc \
|
|
||||||
--arg password "$(cat /var/shared/root-password)" \
|
|
||||||
--arg onion_address "$(cat /var/shared/onion-hostname)" \
|
|
||||||
--argjson local_addrs "$local_addrs" \
|
|
||||||
'{ pass: $password, tor: $onion_address, addrs: $local_addrs }' \
|
|
||||||
> /var/shared/login.json
|
|
||||||
cat /var/shared/login.json | qrencode -s 2 -m 2 -t utf8 -o /var/shared/qrcode.utf8
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.getty.autologinUser = lib.mkForce "root";
|
|
||||||
|
|
||||||
console.earlySetup = true;
|
|
||||||
console.font = lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-u22n.psf.gz";
|
|
||||||
|
|
||||||
environment.systemPackages = [ network-status ];
|
|
||||||
|
|
||||||
# Less ipv6 addresses to reduce the noise
|
|
||||||
networking.tempAddresses = "disabled";
|
|
||||||
|
|
||||||
# Tango theme: https://yayachiken.net/en/posts/tango-colors-in-terminal/
|
|
||||||
console.colors = lib.mkDefault [
|
|
||||||
"000000"
|
|
||||||
"CC0000"
|
|
||||||
"4E9A06"
|
|
||||||
"C4A000"
|
|
||||||
"3465A4"
|
|
||||||
"75507B"
|
|
||||||
"06989A"
|
|
||||||
"D3D7CF"
|
|
||||||
"555753"
|
|
||||||
"EF2929"
|
|
||||||
"8AE234"
|
|
||||||
"FCE94F"
|
|
||||||
"739FCF"
|
|
||||||
"AD7FA8"
|
|
||||||
"34E2E2"
|
|
||||||
"EEEEEC"
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.bash.interactiveShellInit = ''
|
|
||||||
if [[ "$(tty)" =~ /dev/(tty1|hvc0|ttyS0)$ ]]; then
|
|
||||||
# workaround for https://github.com/NixOS/nixpkgs/issues/219239
|
|
||||||
systemctl restart systemd-vconsole-setup.service
|
|
||||||
|
|
||||||
watch --no-title --color ${network-status}/bin/network-status
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
# No one got time for xz compression.
|
|
||||||
isoImage.squashfsCompression = "zstd";
|
|
||||||
isoImage.isoName = lib.mkForce "nixos-installer-${pkgs.system}.iso";
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
nixpkgs,
|
|
||||||
nixos,
|
|
||||||
nixosModules,
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
testConfig = (
|
|
||||||
nixos [
|
|
||||||
(
|
|
||||||
{ modulesPath, ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
nixosModules.image-installer
|
|
||||||
"${modulesPath}/testing/test-instrumentation.nix"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
iso = testConfig.config.system.build.isoImage;
|
|
||||||
mkStartCommand =
|
|
||||||
{
|
|
||||||
memory ? 2048,
|
|
||||||
cdrom ? null,
|
|
||||||
usb ? null,
|
|
||||||
uefi ? false,
|
|
||||||
extraFlags ? [ ],
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
qemu-common = import (nixpkgs + "/nixos/lib/qemu-common.nix") { inherit lib pkgs; };
|
|
||||||
qemu = qemu-common.qemuBinary pkgs.qemu_test;
|
|
||||||
|
|
||||||
flags =
|
|
||||||
[
|
|
||||||
"-m"
|
|
||||||
(toString memory)
|
|
||||||
"-netdev"
|
|
||||||
"user,id=net0"
|
|
||||||
"-device"
|
|
||||||
"virtio-net-pci,netdev=net0"
|
|
||||||
]
|
|
||||||
++ lib.optionals (cdrom != null) [
|
|
||||||
"-cdrom"
|
|
||||||
cdrom
|
|
||||||
]
|
|
||||||
++ lib.optionals (usb != null) [
|
|
||||||
"-device"
|
|
||||||
"usb-ehci"
|
|
||||||
"-drive"
|
|
||||||
"id=usbdisk,file=${usb},if=none,readonly"
|
|
||||||
"-device"
|
|
||||||
"usb-storage,drive=usbdisk"
|
|
||||||
]
|
|
||||||
++ lib.optionals uefi [
|
|
||||||
"-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}"
|
|
||||||
]
|
|
||||||
++ extraFlags;
|
|
||||||
|
|
||||||
flagsStr = lib.concatStringsSep " " flags;
|
|
||||||
in
|
|
||||||
"${qemu} ${flagsStr}";
|
|
||||||
|
|
||||||
makeBootTest =
|
|
||||||
name: config:
|
|
||||||
let
|
|
||||||
startCommand = mkStartCommand config;
|
|
||||||
in
|
|
||||||
pkgs.testers.runNixOSTest {
|
|
||||||
name = "boot-${name}";
|
|
||||||
nodes = { };
|
|
||||||
testScript = ''
|
|
||||||
machine = create_machine("${startCommand}")
|
|
||||||
machine.start()
|
|
||||||
machine.wait_for_unit("multi-user.target")
|
|
||||||
machine.succeed("nix store verify --no-trust -r --option experimental-features nix-command /run/current-system")
|
|
||||||
|
|
||||||
machine.shutdown()
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
uefi-cdrom = makeBootTest "uefi-cdrom" {
|
|
||||||
uefi = true;
|
|
||||||
cdrom = "${iso}/iso/nixos-installer-${pkgs.hostPlatform.system}.iso";
|
|
||||||
};
|
|
||||||
|
|
||||||
uefi-usb = makeBootTest "uefi-usb" {
|
|
||||||
uefi = true;
|
|
||||||
usb = "${iso}/iso/nixos-installer-${pkgs.hostPlatform.system}.iso";
|
|
||||||
};
|
|
||||||
|
|
||||||
bios-cdrom = makeBootTest "bios-cdrom" {
|
|
||||||
cdrom = "${iso}/iso/nixos-installer-${pkgs.hostPlatform.system}.iso";
|
|
||||||
};
|
|
||||||
|
|
||||||
bios-usb = makeBootTest "bios-usb" {
|
|
||||||
usb = "${iso}/iso/nixos-installer-${pkgs.hostPlatform.system}.iso";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
imports = [ ../networkd.nix ];
|
|
||||||
# use iwd instead of wpa_supplicant
|
|
||||||
networking.wireless.enable = false;
|
|
||||||
|
|
||||||
# Use iwd instead of wpa_supplicant. It has a user friendly CLI
|
|
||||||
networking.wireless.iwd = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
Network = {
|
|
||||||
EnableIPv6 = true;
|
|
||||||
RoutePriorityOffset = 300;
|
|
||||||
};
|
|
||||||
Settings.AutoConnect = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,45 +1,56 @@
|
||||||
{
|
{ config, lib, pkgs, ... }: {
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
# ./latest-zfs-kernel.nix
|
|
||||||
./nix-settings.nix
|
|
||||||
];
|
|
||||||
# more descriptive hostname than just "nixos"
|
|
||||||
networking.hostName = lib.mkDefault "nixos-installer";
|
|
||||||
|
|
||||||
# We are stateless, so just default to latest.
|
# We are stateless, so just default to latest.
|
||||||
system.stateVersion = config.system.nixos.version;
|
system.stateVersion = config.system.nixos.version;
|
||||||
|
|
||||||
# Enable bcachefs support
|
|
||||||
boot.supportedFilesystems.bcachefs = lib.mkDefault true;
|
|
||||||
|
|
||||||
# use latest kernel we can support to get more hardware support
|
# use latest kernel we can support to get more hardware support
|
||||||
# boot.zfs.package = pkgs.zfsUnstable;
|
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||||
|
|
||||||
|
# IPMI SOL console redirection stuff
|
||||||
|
boot.kernelParams =
|
||||||
|
[ "console=tty0" ] ++
|
||||||
|
(lib.optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) "console=ttyAMA0,115200") ++
|
||||||
|
(lib.optional (pkgs.stdenv.hostPlatform.isRiscV) "console=ttySIF0,115200") ++
|
||||||
|
[ "console=ttyS0,115200" ];
|
||||||
|
|
||||||
documentation.enable = false;
|
documentation.enable = false;
|
||||||
documentation.man.man-db.enable = false;
|
# Not really needed. Saves a few bytes and the only service we are running is sshd, which we want to be reachable.
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
|
||||||
# make it easier to debug boot failures
|
systemd.network.enable = true;
|
||||||
boot.initrd.systemd.emergencyAccess = true;
|
networking.dhcpcd.enable = false;
|
||||||
|
|
||||||
environment.systemPackages = [
|
# for zapping of disko
|
||||||
pkgs.nixos-install-tools
|
environment.systemPackages = [ pkgs.jq ];
|
||||||
# for zapping of disko
|
|
||||||
pkgs.jq
|
|
||||||
# for copying extra files of nixos-anywhere
|
|
||||||
pkgs.rsync
|
|
||||||
# alternative to nixos-generate-config
|
|
||||||
# TODO: use nixpkgs again after next nixos release
|
|
||||||
(pkgs.callPackage ./nixos-facter.nix {})
|
|
||||||
|
|
||||||
pkgs.disko
|
systemd.services.log-network-status = {
|
||||||
];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
# No point in restarting this. We just need this after boot
|
||||||
|
restartIfChanged = false;
|
||||||
|
|
||||||
# Don't add nixpkgs to the image to save space, for our intended use case we don't need it
|
serviceConfig = {
|
||||||
system.installer.channel.enable = false;
|
Type = "oneshot";
|
||||||
|
StandardOutput = "journal+console";
|
||||||
|
ExecStart = [
|
||||||
|
# Allow failures, so it still prints what interfaces we have even if we
|
||||||
|
# not get online
|
||||||
|
"-${pkgs.systemd}/lib/systemd/systemd-networkd-wait-online"
|
||||||
|
"${pkgs.iproute2}/bin/ip -c addr"
|
||||||
|
"${pkgs.iproute2}/bin/ip -c -6 route"
|
||||||
|
"${pkgs.iproute2}/bin/ip -c -4 route"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Restore ssh host and user keys if they are available.
|
||||||
|
# This avoids warnings of unknown ssh keys.
|
||||||
|
boot.initrd.postMountCommands = ''
|
||||||
|
mkdir -m 700 -p /mnt-root/root/.ssh
|
||||||
|
mkdir -m 755 -p /mnt-root/etc/ssh
|
||||||
|
mkdir -m 755 -p /mnt-root/root/network
|
||||||
|
if [[ -f ssh/authorized_keys ]]; then
|
||||||
|
install -m 400 ssh/authorized_keys /mnt-root/root/.ssh
|
||||||
|
fi
|
||||||
|
install -m 400 ssh/ssh_host_* /mnt-root/etc/ssh
|
||||||
|
cp *.json /mnt-root/root/network/
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
44
nix/kexec-installer/kexec-run.sh
Executable file → Normal file
44
nix/kexec-installer/kexec-run.sh
Executable file → Normal file
|
@ -1,19 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
kexec_extra_flags=""
|
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--kexec-extra-flags)
|
|
||||||
kexec_extra_flags="$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
# provided by nix
|
# provided by nix
|
||||||
init="@init@"
|
init="@init@"
|
||||||
kernelParams="@kernelParams@"
|
kernelParams="@kernelParams@"
|
||||||
|
@ -34,16 +21,12 @@ extractPubKeys() {
|
||||||
key="$home/$file"
|
key="$home/$file"
|
||||||
if test -e "$key"; then
|
if test -e "$key"; then
|
||||||
# workaround for debian shenanigans
|
# workaround for debian shenanigans
|
||||||
grep -o '\(\(ssh\|ecdsa\|sk\)-[^ ]* .*\)' "$key" >> ssh/authorized_keys || true
|
grep -o '\(ssh-[^ ]* .*\)' "$key" >> ssh/authorized_keys || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
extractPubKeys /root
|
extractPubKeys /root
|
||||||
|
|
||||||
if test -n "${DOAS_USER-}"; then
|
|
||||||
SUDO_USER="$DOAS_USER"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -n "${SUDO_USER-}"; then
|
if test -n "${SUDO_USER-}"; then
|
||||||
sudo_home=$(sh -c "echo ~$SUDO_USER")
|
sudo_home=$(sh -c "echo ~$SUDO_USER")
|
||||||
extractPubKeys "$sudo_home"
|
extractPubKeys "$sudo_home"
|
||||||
|
@ -67,36 +50,25 @@ done
|
||||||
"$SCRIPT_DIR/ip" -4 --json route > routes-v4.json
|
"$SCRIPT_DIR/ip" -4 --json route > routes-v4.json
|
||||||
"$SCRIPT_DIR/ip" -6 --json route > routes-v6.json
|
"$SCRIPT_DIR/ip" -6 --json route > routes-v6.json
|
||||||
|
|
||||||
[ -f /etc/machine-id ] && cp /etc/machine-id machine-id
|
|
||||||
|
|
||||||
find . | cpio -o -H newc | gzip -9 >> "$SCRIPT_DIR/initrd"
|
find . | cpio -o -H newc | gzip -9 >> "$SCRIPT_DIR/initrd"
|
||||||
|
|
||||||
kexecSyscallFlags=""
|
# Dropped --kexec-syscall-auto because it broke on GCP...
|
||||||
# only do kexec-syscall-auto on kernels newer than 6.0.
|
if ! "$SCRIPT_DIR/kexec" --load "$SCRIPT_DIR/bzImage" \
|
||||||
# On older kernel we often get errors like: https://github.com/nix-community/nixos-anywhere/issues/264
|
--initrd="$SCRIPT_DIR/initrd" --no-checks \
|
||||||
if printf "%s\n" "6.1" "$(uname -r)" | sort -c -V 2>&1; then
|
--command-line "init=$init $kernelParams"; then
|
||||||
kexecSyscallFlags="--kexec-syscall-auto"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! sh -c "'$SCRIPT_DIR/kexec' --load '$SCRIPT_DIR/bzImage' \
|
|
||||||
$kexecSyscallFlags \
|
|
||||||
$kexec_extra_flags \
|
|
||||||
--initrd='$SCRIPT_DIR/initrd' --no-checks \
|
|
||||||
--command-line 'init=$init $kernelParams'"
|
|
||||||
then
|
|
||||||
echo "kexec failed, dumping dmesg"
|
echo "kexec failed, dumping dmesg"
|
||||||
dmesg | tail -n 100
|
dmesg | tail -n 100
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disconnect our background kexec from the terminal
|
# Disconnect our background kexec from the terminal
|
||||||
echo "machine will boot into nixos in 6s..."
|
echo "machine will boot into nixos in in 6s..."
|
||||||
if test -e /dev/kmsg; then
|
if test -e /dev/kmsg; then
|
||||||
# this makes logging visible in `dmesg`, or the system console or tools like journald
|
# this makes logging visible in `dmesg`, or the system consol or tools like journald
|
||||||
exec > /dev/kmsg 2>&1
|
exec > /dev/kmsg 2>&1
|
||||||
else
|
else
|
||||||
exec > /dev/null 2>&1
|
exec > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
# We will kexec in background so we can cleanly finish the script before the hosts go down.
|
# We will kexec in background so we can cleanly finish the script before the hosts go down.
|
||||||
# This makes integration with tools like terraform easier.
|
# This makes integration with tools like terraform easier.
|
||||||
nohup sh -c "sleep 6 && '$SCRIPT_DIR/kexec' -e ${kexec_extra_flags}" &
|
nohup sh -c "sleep 6 && '$SCRIPT_DIR/kexec' -e" &
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env -S nix shell --inputs-from .# nixos-unstable#bash nixos-unstable#iproute2 nixos-unstable#findutils nixos-unstable#coreutils nixos-unstable#python3 nixos-unstable#jq --command bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
||||||
|
|
||||||
# This script can be used to see what network configuration would be restored by the restore_routes.py script for the current system.
|
|
||||||
|
|
||||||
tmp=$(mktemp -d)
|
|
||||||
trap "rm -rf $tmp" EXIT
|
|
||||||
ip --json address >"$tmp/addrs.json"
|
|
||||||
ip -6 --json route >"$tmp/routes-v6.json"
|
|
||||||
ip -4 --json route >"$tmp/routes-v4.json"
|
|
||||||
python3 "$SCRIPT_DIR/restore_routes.py" "$tmp/addrs.json" "$tmp/routes-v4.json" "$tmp/routes-v6.json" "$tmp"
|
|
||||||
ls -la "$tmp"
|
|
||||||
|
|
||||||
find "$tmp" -type f -name "*.json" -print0 | while IFS= read -r -d '' file; do
|
|
||||||
echo -e "\033[0;31m$(basename "$file")\033[0m"
|
|
||||||
jq . "$file"
|
|
||||||
echo ""
|
|
||||||
done
|
|
||||||
|
|
||||||
find "$tmp" -type f -name "*.network" -print0 | while IFS= read -r -d '' file; do
|
|
||||||
echo -e "\033[0;31m$(basename "$file")\033[0m"
|
|
||||||
cat "$file"
|
|
||||||
echo ""
|
|
||||||
done
|
|
|
@ -1,14 +1,7 @@
|
||||||
{ config, lib, modulesPath, pkgs, ... }:
|
{ config, lib, modulesPath, pkgs, ... }:
|
||||||
let
|
let
|
||||||
writePython3 = pkgs.writers.makePythonWriter
|
restore-network = pkgs.writers.writePython3 "restore-network" { flakeIgnore = [ "E501" ]; }
|
||||||
pkgs.python3Minimal pkgs.python3Packages pkgs.buildPackages.python3Packages;
|
./restore_routes.py;
|
||||||
|
|
||||||
# writePython3Bin takes the same arguments as writePython3 but outputs a directory (like writeScriptBin)
|
|
||||||
writePython3Bin = name: writePython3 "/bin/${name}";
|
|
||||||
|
|
||||||
restore-network = writePython3Bin "restore-network" {
|
|
||||||
flakeIgnore = [ "E501" ];
|
|
||||||
} ./restore_routes.py;
|
|
||||||
|
|
||||||
# does not link with iptables enabled
|
# does not link with iptables enabled
|
||||||
iprouteStatic = pkgs.pkgsStatic.iproute2.override { iptables = null; };
|
iprouteStatic = pkgs.pkgsStatic.iproute2.override { iptables = null; };
|
||||||
|
@ -17,11 +10,7 @@ in
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/installer/netboot/netboot-minimal.nix")
|
(modulesPath + "/installer/netboot/netboot-minimal.nix")
|
||||||
../installer.nix
|
../installer.nix
|
||||||
../networkd.nix
|
|
||||||
../serial.nix
|
|
||||||
../restore-remote-access.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
system.kexec-installer.name = lib.mkOption {
|
system.kexec-installer.name = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
|
@ -33,7 +22,6 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
boot.initrd.compressor = "xz";
|
|
||||||
# This is a variant of the upstream kexecScript that also allows embedding
|
# This is a variant of the upstream kexecScript that also allows embedding
|
||||||
# a ssh key.
|
# a ssh key.
|
||||||
system.build.kexecRun = pkgs.runCommand "kexec-run" { } ''
|
system.build.kexecRun = pkgs.runCommand "kexec-run" { } ''
|
||||||
|
@ -73,7 +61,7 @@ in
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStart = [
|
ExecStart = [
|
||||||
"${restore-network}/bin/restore-network /root/network/addrs.json /root/network/routes-v4.json /root/network/routes-v6.json /etc/systemd/network"
|
"${restore-network} /root/network/addrs.json /root/network/routes-v4.json /root/network/routes-v6.json /etc/systemd/network"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,86 +1,40 @@
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Iterator
|
from typing import Any
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
def filter_interfaces(network: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||||
class Address:
|
output = []
|
||||||
address: str
|
|
||||||
family: str
|
|
||||||
prefixlen: int
|
|
||||||
preferred_life_time: int = 0
|
|
||||||
valid_life_time: int = 0
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Interface:
|
|
||||||
name: str
|
|
||||||
ifname: str | None
|
|
||||||
mac_address: str
|
|
||||||
dynamic_addresses: list[Address]
|
|
||||||
static_addresses: list[Address]
|
|
||||||
static_routes: list[dict[str, Any]]
|
|
||||||
|
|
||||||
|
|
||||||
def filter_interfaces(network: list[dict[str, Any]]) -> list[Interface]:
|
|
||||||
interfaces = []
|
|
||||||
for net in network:
|
for net in network:
|
||||||
if net.get("link_type") == "loopback":
|
if net.get("link_type") == "loopback":
|
||||||
continue
|
continue
|
||||||
if not (mac_address := net.get("address")):
|
if not net.get("address"):
|
||||||
# We need a mac address to match devices reliable
|
# We need a mac address to match devices reliable
|
||||||
continue
|
continue
|
||||||
static_addresses = []
|
addr_info = []
|
||||||
dynamic_addresses = []
|
has_dynamic_address = False
|
||||||
for info in net.get("addr_info", []):
|
for addr in net.get("addr_info", []):
|
||||||
# no link-local ipv4/ipv6
|
# no link-local ipv4/ipv6
|
||||||
if info.get("scope") == "link":
|
if addr.get("scope") == "link":
|
||||||
continue
|
continue
|
||||||
if (preferred_life_time := info.get("preferred_life_time")) is None:
|
# do not explicitly configure addresses from dhcp or router advertisment
|
||||||
|
if addr.get("dynamic", False):
|
||||||
|
has_dynamic_address = True
|
||||||
continue
|
continue
|
||||||
if (valid_life_time := info.get("valid_life_time")) is None:
|
|
||||||
continue
|
|
||||||
if (prefixlen := info.get("prefixlen")) is None:
|
|
||||||
continue
|
|
||||||
if (family := info.get("family")) not in ["inet", "inet6"]:
|
|
||||||
continue
|
|
||||||
if (local := info.get("local")) is None:
|
|
||||||
continue
|
|
||||||
if (dynamic := info.get("dynamic", False)) is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
address = Address(
|
|
||||||
address=local,
|
|
||||||
family=family,
|
|
||||||
prefixlen=prefixlen,
|
|
||||||
preferred_life_time=preferred_life_time,
|
|
||||||
valid_life_time=valid_life_time,
|
|
||||||
)
|
|
||||||
|
|
||||||
if dynamic:
|
|
||||||
dynamic_addresses.append(address)
|
|
||||||
else:
|
else:
|
||||||
static_addresses.append(address)
|
addr_info.append(addr)
|
||||||
interfaces.append(
|
if addr_info != [] or has_dynamic_address:
|
||||||
Interface(
|
net["addr_info"] = addr_info
|
||||||
name=net.get("ifname", mac_address.replace(":", "-")),
|
output.append(net)
|
||||||
ifname=net.get("ifname"),
|
|
||||||
mac_address=mac_address,
|
|
||||||
dynamic_addresses=dynamic_addresses,
|
|
||||||
static_addresses=static_addresses,
|
|
||||||
static_routes=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return interfaces
|
return output
|
||||||
|
|
||||||
|
|
||||||
def filter_routes(routes: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
def filter_routes(routes: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||||
filtered = []
|
filtered = []
|
||||||
for route in routes:
|
for route in routes:
|
||||||
# Filter out routes set by addresses with subnets, dhcp and router advertisement
|
# Filter out routes set by addresses with subnets, dhcp and router advertisment
|
||||||
if route.get("protocol") in ["dhcp", "kernel", "ra"]:
|
if route.get("protocol") in ["dhcp", "kernel", "ra"]:
|
||||||
continue
|
continue
|
||||||
filtered.append(route)
|
filtered.append(route)
|
||||||
|
@ -88,81 +42,46 @@ def filter_routes(routes: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
def find_most_recent_v4_lease(addresses: list[Address]) -> Address | None:
|
|
||||||
most_recent_address = None
|
|
||||||
most_recent_lifetime = -1
|
|
||||||
for addr in addresses:
|
|
||||||
if addr.family == "inet6":
|
|
||||||
continue
|
|
||||||
lifetime = max(addr.preferred_life_time, addr.valid_life_time)
|
|
||||||
if lifetime > most_recent_lifetime:
|
|
||||||
most_recent_lifetime = lifetime
|
|
||||||
most_recent_address = addr
|
|
||||||
return most_recent_address
|
|
||||||
|
|
||||||
|
|
||||||
def generate_routes(
|
|
||||||
interface: Interface, routes: list[dict[str, Any]]
|
|
||||||
) -> Iterator[str]:
|
|
||||||
for route in routes:
|
|
||||||
if interface.ifname is None or route.get("dev") != interface.ifname:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# we may ignore on-link default routes here, but I don't see how
|
|
||||||
# they would be useful for internet connectivity anyway
|
|
||||||
|
|
||||||
yield "[Route]"
|
|
||||||
if route.get("dst") != "default":
|
|
||||||
# can be skipped for default routes
|
|
||||||
yield f"Destination = {route['dst']}"
|
|
||||||
gateway = route.get("gateway")
|
|
||||||
# route v4 via v6
|
|
||||||
route_via = route.get("via")
|
|
||||||
if route_via and route_via.get("family") == "inet6":
|
|
||||||
gateway = route_via.get("host")
|
|
||||||
if route.get("dst") == "default":
|
|
||||||
yield "Destination = 0.0.0.0/0"
|
|
||||||
if gateway:
|
|
||||||
yield f"Gateway = {gateway}"
|
|
||||||
|
|
||||||
|
|
||||||
def generate_networkd_units(
|
def generate_networkd_units(
|
||||||
interfaces: list[Interface], routes: list[dict[str, Any]], directory: Path
|
interfaces: list[dict[str, Any]], routes: list[dict[str, Any]], directory: Path
|
||||||
) -> None:
|
) -> None:
|
||||||
directory.mkdir(exist_ok=True)
|
directory.mkdir(exist_ok=True)
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
# FIXME in some networks we might not want to trust dhcp or router advertisements
|
name = f"{interface['ifname']}.network"
|
||||||
unit_sections = [
|
addresses = [
|
||||||
f"""
|
f"Address = {addr['local']}/{addr['prefixlen']}"
|
||||||
|
for addr in interface.get("addr_info", [])
|
||||||
|
]
|
||||||
|
|
||||||
|
route_sections = []
|
||||||
|
for route in routes:
|
||||||
|
if route.get("dev", "nodev") != interface.get("ifname", "noif"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
route_section = "[Route]\n"
|
||||||
|
if route.get("dst") != "default":
|
||||||
|
# can be skipped for default routes
|
||||||
|
route_section += f"Destination = {route['dst']}\n"
|
||||||
|
gateway = route.get("gateway")
|
||||||
|
if gateway:
|
||||||
|
route_section += f"Gateway = {gateway}\n"
|
||||||
|
|
||||||
|
# we may ignore on-link default routes here, but I don't see how
|
||||||
|
# they would be useful for internet connectivity anyway
|
||||||
|
route_sections.append(route_section)
|
||||||
|
|
||||||
|
# FIXME in some networks we might not want to trust dhcp or router advertisments
|
||||||
|
unit = f"""
|
||||||
[Match]
|
[Match]
|
||||||
MACAddress = {interface.mac_address}
|
MACAddress = {interface["address"]}
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
# both ipv4 and ipv6
|
|
||||||
DHCP = yes
|
DHCP = yes
|
||||||
# lets us discover the switch port we're connected to
|
|
||||||
LLDP = yes
|
|
||||||
# ipv6 router advertisements
|
|
||||||
IPv6AcceptRA = yes
|
IPv6AcceptRA = yes
|
||||||
# allows us to ping "nixos.local"
|
"""
|
||||||
MulticastDNS = yes"""
|
unit += "\n".join(addresses)
|
||||||
]
|
unit += "\n" + "\n".join(route_sections)
|
||||||
unit_sections.extend(
|
(directory / name).write_text(unit)
|
||||||
f"Address = {addr.address}/{addr.prefixlen}"
|
|
||||||
for addr in interface.static_addresses
|
|
||||||
)
|
|
||||||
unit_sections.extend(generate_routes(interface, routes))
|
|
||||||
most_recent_v4_lease = find_most_recent_v4_lease(interface.dynamic_addresses)
|
|
||||||
if most_recent_v4_lease:
|
|
||||||
unit_sections.append("[DHCPv4]")
|
|
||||||
unit_sections.append(f"RequestAddress = {most_recent_v4_lease.address}")
|
|
||||||
|
|
||||||
# trailing newline at the end
|
|
||||||
unit_sections.append("")
|
|
||||||
|
|
||||||
(directory / f"00-{interface.name}.network").write_text(
|
|
||||||
"\n".join(unit_sections)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
|
|
@ -1,24 +1,30 @@
|
||||||
{ pkgs
|
{ pkgs
|
||||||
, lib
|
|
||||||
, kexecTarball
|
, kexecTarball
|
||||||
, nixos-facter ? null
|
|
||||||
}:
|
}:
|
||||||
|
|
||||||
pkgs.testers.runNixOSTest {
|
let
|
||||||
|
makeTest = import (pkgs.path + "/nixos/tests/make-test-python.nix");
|
||||||
|
makeTest' = args: makeTest args {
|
||||||
|
inherit pkgs;
|
||||||
|
inherit (pkgs) system;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
makeTest' {
|
||||||
name = "kexec-installer";
|
name = "kexec-installer";
|
||||||
meta = with pkgs.lib.maintainers; {
|
meta = with pkgs.lib.maintainers; {
|
||||||
maintainers = [ mic92 ];
|
maintainers = [ mic92 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
node1 = { modulesPath, pkgs, ... }: {
|
node1 = { modulesPath, ... }: {
|
||||||
virtualisation.vlans = [ ];
|
virtualisation.vlans = [ ];
|
||||||
|
environment.noXlibs = false; # avoid recompilation
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/profiles/minimal.nix")
|
(modulesPath + "/profiles/minimal.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
system.extraDependencies = [ kexecTarball ];
|
system.extraDependencies = [ kexecTarball ];
|
||||||
virtualisation.memorySize = 1 * 1024;
|
virtualisation.memorySize = 1 * 1024 + 512;
|
||||||
virtualisation.diskSize = 4 * 1024;
|
virtualisation.diskSize = 4 * 1024;
|
||||||
virtualisation.forwardPorts = [{
|
virtualisation.forwardPorts = [{
|
||||||
host.port = 2222;
|
host.port = 2222;
|
||||||
|
@ -27,8 +33,10 @@ pkgs.testers.runNixOSTest {
|
||||||
|
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
|
|
||||||
networking.useNetworkd = true;
|
networking = {
|
||||||
networking.useDHCP = false;
|
useNetworkd = true;
|
||||||
|
useDHCP = false;
|
||||||
|
};
|
||||||
|
|
||||||
users.users.root.openssh.authorizedKeys.keyFiles = [ ./ssh-keys/id_ed25519.pub ];
|
users.users.root.openssh.authorizedKeys.keyFiles = [ ./ssh-keys/id_ed25519.pub ];
|
||||||
|
|
||||||
|
@ -44,20 +52,12 @@ pkgs.testers.runNixOSTest {
|
||||||
name = "eth0";
|
name = "eth0";
|
||||||
address = [
|
address = [
|
||||||
# Some static addresses that we want to see in the kexeced image
|
# Some static addresses that we want to see in the kexeced image
|
||||||
"192.168.42.1/24"
|
"192.168.42.1/24" "42::1/64"
|
||||||
"42::1/64"
|
|
||||||
];
|
];
|
||||||
routes = if pkgs.lib.versionAtLeast lib.version "24.11" then [
|
routes = [
|
||||||
{ Destination = "192.168.43.0/24"; }
|
|
||||||
{ Destination = "192.168.44.0/24"; Gateway = "192.168.43.1"; }
|
|
||||||
{ Destination = "192.168.45.0/24"; Gateway = "43::1"; }
|
|
||||||
{ Destination = "43::0/64"; }
|
|
||||||
{ Destination = "44::1/64"; Gateway = "43::1"; }
|
|
||||||
] else [
|
|
||||||
# Some static routes that we want to see in the kexeced image
|
# Some static routes that we want to see in the kexeced image
|
||||||
{ routeConfig = { Destination = "192.168.43.0/24"; }; }
|
{ routeConfig = { Destination = "192.168.43.0/24"; }; }
|
||||||
{ routeConfig = { Destination = "192.168.44.0/24"; Gateway = "192.168.43.1"; }; }
|
{ routeConfig = { Destination = "192.168.44.0/24"; Gateway = "192.168.43.1"; }; }
|
||||||
{ routeConfig = { Destination = "192.168.45.0/24"; Gateway = "43::1"; }; }
|
|
||||||
{ routeConfig = { Destination = "43::0/64"; }; }
|
{ routeConfig = { Destination = "43::0/64"; }; }
|
||||||
{ routeConfig = { Destination = "44::1/64"; Gateway = "43::1"; }; }
|
{ routeConfig = { Destination = "44::1/64"; Gateway = "43::1"; }; }
|
||||||
];
|
];
|
||||||
|
@ -65,14 +65,10 @@ pkgs.testers.runNixOSTest {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // lib.optionalAttrs (lib.versionOlder lib.version "24.11pre") {
|
|
||||||
# avoid second overlay
|
|
||||||
environment.noXlibs = false;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = /*python*/ ''
|
testScript = ''
|
||||||
import json
|
|
||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
import socket
|
import socket
|
||||||
|
@ -106,19 +102,19 @@ pkgs.testers.runNixOSTest {
|
||||||
node1.succeed("ip -6 route >&2")
|
node1.succeed("ip -6 route >&2")
|
||||||
node1.succeed("networkctl status eth0 >&2")
|
node1.succeed("networkctl status eth0 >&2")
|
||||||
|
|
||||||
def ssh(cmd: list[str], check: bool = True, stdout: Optional[int] = None) -> subprocess.CompletedProcess[str]:
|
def ssh(cmd: list[str], check: bool = True, stdout: Optional[int] = None) -> subprocess.CompletedProcess:
|
||||||
ssh_cmd = [
|
ssh_cmd = [
|
||||||
"${pkgs.openssh}/bin/ssh",
|
"${pkgs.openssh}/bin/ssh",
|
||||||
"-o", "StrictHostKeyChecking=no",
|
"-o", "StrictHostKeyChecking=no",
|
||||||
"-o", "ConnectTimeout=1",
|
"-o", "ConnectTimeout=1",
|
||||||
"-i", "${./ssh-keys/id_ed25519}",
|
"-i", "${./ssh-keys/id_ed25519}",
|
||||||
"-p", "2222",
|
"-p", "2222",
|
||||||
"root@127.0.0.1",
|
"root@127.0.0.1",
|
||||||
"--"
|
"--"
|
||||||
] + cmd
|
] + cmd
|
||||||
print(" ".join(ssh_cmd))
|
print(" ".join(ssh_cmd))
|
||||||
return subprocess.run(ssh_cmd,
|
return subprocess.run(ssh_cmd,
|
||||||
text=True,
|
text=True,
|
||||||
check=check,
|
check=check,
|
||||||
stdout=stdout)
|
stdout=stdout)
|
||||||
|
|
||||||
|
@ -133,7 +129,6 @@ pkgs.testers.runNixOSTest {
|
||||||
|
|
||||||
# Kexec node1 to the toplevel of node2 via the kexec-boot script
|
# Kexec node1 to the toplevel of node2 via the kexec-boot script
|
||||||
node1.succeed('touch /run/foo')
|
node1.succeed('touch /run/foo')
|
||||||
old_machine_id = node1.succeed("cat /etc/machine-id").strip()
|
|
||||||
node1.fail('parted --version >&2')
|
node1.fail('parted --version >&2')
|
||||||
node1.succeed('tar -xf ${kexecTarball}/nixos-kexec-installer-noninteractive-${pkgs.system}.tar.gz -C /root')
|
node1.succeed('tar -xf ${kexecTarball}/nixos-kexec-installer-noninteractive-${pkgs.system}.tar.gz -C /root')
|
||||||
node1.succeed('/root/kexec/ip -V >&2')
|
node1.succeed('/root/kexec/ip -V >&2')
|
||||||
|
@ -141,36 +136,23 @@ pkgs.testers.runNixOSTest {
|
||||||
node1.succeed('/root/kexec/run >&2')
|
node1.succeed('/root/kexec/run >&2')
|
||||||
|
|
||||||
# wait for kexec to finish
|
# wait for kexec to finish
|
||||||
while ssh(["true"], check=False).returncode == 0:
|
while ssh(["true"], check=False).returncode == 0:
|
||||||
print("Waiting for kexec to finish...")
|
print("Waiting for kexec to finish...")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
while ssh(["true"], check=False).returncode != 0:
|
while ssh(["true"], check=False).returncode != 0:
|
||||||
print("Waiting for node2 to come up...")
|
print("Waiting for node2 to come up...")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
while ssh(["systemctl is-active restore-network"], check=False).returncode != 0:
|
|
||||||
print("Waiting for network to be restored...")
|
|
||||||
time.sleep(1)
|
|
||||||
ssh(["systemctl", "status", "restore-network"])
|
|
||||||
|
|
||||||
print(ssh(["ip", "addr"]))
|
print(ssh(["ip", "addr"]))
|
||||||
print(ssh(["ip", "route"]))
|
print(ssh(["ip", "route"]))
|
||||||
print(ssh(["ip", "-6", "route"]))
|
print(ssh(["ip", "-6", "route"]))
|
||||||
print(ssh(["networkctl", "status"]))
|
print(ssh(["networkctl", "status"]))
|
||||||
|
|
||||||
new_machine_id = ssh(["cat", "/etc/machine-id"], stdout=subprocess.PIPE).stdout.strip()
|
|
||||||
assert old_machine_id == new_machine_id, f"{old_machine_id} != {new_machine_id}, machine-id changed"
|
|
||||||
|
|
||||||
assert ssh(["ls", "-la", "/run/foo"], check=False).returncode != 0, "kexeced node1 still has /run/foo"
|
assert ssh(["ls", "-la", "/run/foo"], check=False).returncode != 0, "kexeced node1 still has /run/foo"
|
||||||
print(ssh(["parted", "--version"]))
|
print(ssh(["parted", "--version"]))
|
||||||
host = ssh(["hostname"], stdout=subprocess.PIPE).stdout.strip()
|
host = ssh(["hostname"], stdout=subprocess.PIPE).stdout.strip()
|
||||||
assert host == "nixos-installer", f"hostname is {host}, not nixos-installer"
|
assert host == "nixos", f"hostname is {host}, not nixos"
|
||||||
|
|
||||||
has_nixos_facter=${if nixos-facter != null then "True" else "False"}
|
|
||||||
if has_nixos_facter == True:
|
|
||||||
data = json.loads(ssh(["nixos-facter"], stdout=subprocess.PIPE).stdout)
|
|
||||||
assert data["virtualisation"] == "kvm", f"virtualisation is {data['virtualisation']}, not kvm"
|
|
||||||
|
|
||||||
host_ed25519_after = ssh(["cat", "/etc/ssh/ssh_host_ed25519_key.pub"], stdout=subprocess.PIPE).stdout.strip()
|
host_ed25519_after = ssh(["cat", "/etc/ssh/ssh_host_ed25519_key.pub"], stdout=subprocess.PIPE).stdout.strip()
|
||||||
assert host_ed25519_before == host_ed25519_after, f"'{host_ed25519_before}' != '{host_ed25519_after}'"
|
assert host_ed25519_before == host_ed25519_after, f"'{host_ed25519_before}' != '{host_ed25519_after}'"
|
||||||
|
@ -178,7 +160,7 @@ pkgs.testers.runNixOSTest {
|
||||||
root_ed25519_after = ssh(["cat", "/root/.ssh/authorized_keys"], stdout=subprocess.PIPE).stdout.strip()
|
root_ed25519_after = ssh(["cat", "/root/.ssh/authorized_keys"], stdout=subprocess.PIPE).stdout.strip()
|
||||||
assert root_ed25519_before in root_ed25519_after, f"'{root_ed25519_before}' not included in '{root_ed25519_after}'"
|
assert root_ed25519_before in root_ed25519_after, f"'{root_ed25519_before}' not included in '{root_ed25519_after}'"
|
||||||
|
|
||||||
print(ssh(["cat", "/etc/systemd/network/00-eth0.network"]))
|
print(ssh(["cat", "/etc/systemd/network/eth0.network"]))
|
||||||
ssh(["curl", "-v", "-I", f"http://10.0.2.2:{port}"])
|
ssh(["curl", "-v", "-I", f"http://10.0.2.2:{port}"])
|
||||||
ssh(["curl", "-v", "-I", f"http://[fec0::2]:{port}"])
|
ssh(["curl", "-v", "-I", f"http://[fec0::2]:{port}"])
|
||||||
|
|
||||||
|
@ -194,10 +176,6 @@ pkgs.testers.runNixOSTest {
|
||||||
print(out)
|
print(out)
|
||||||
assert "192.168.44.2 via 192.168.43.1" in out, f"route to `192.168.44.2 via 192.168.43.1` not found: {out}"
|
assert "192.168.44.2 via 192.168.43.1" in out, f"route to `192.168.44.2 via 192.168.43.1` not found: {out}"
|
||||||
|
|
||||||
out = ssh(["ip", "route", "get", "192.168.45.2"], stdout=subprocess.PIPE).stdout
|
|
||||||
print(out)
|
|
||||||
assert "192.168.45.2 via inet6 43::1" in out, f"route to `192.168.45.2 via inet6 43::1` not found: {out}"
|
|
||||||
|
|
||||||
out = ssh(["ip", "route", "get", "43::2"], stdout=subprocess.PIPE).stdout
|
out = ssh(["ip", "route", "get", "43::2"], stdout=subprocess.PIPE).stdout
|
||||||
print(out)
|
print(out)
|
||||||
assert "43::2 from :: dev" in out, f"route `43::2 from dev` not found: {out}"
|
assert "43::2 from :: dev" in out, f"route `43::2 from dev` not found: {out}"
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
isUnstable = config.boot.zfs.package == pkgs.zfsUnstable;
|
|
||||||
zfsCompatibleKernelPackages = lib.filterAttrs (
|
|
||||||
name: kernelPackages:
|
|
||||||
(builtins.match "linux_[0-9]+_[0-9]+" name) != null
|
|
||||||
&& (builtins.tryEval kernelPackages).success
|
|
||||||
&& (
|
|
||||||
(!isUnstable && !kernelPackages.zfs.meta.broken)
|
|
||||||
|| (isUnstable && !kernelPackages.zfs_unstable.meta.broken)
|
|
||||||
)
|
|
||||||
) pkgs.linuxKernel.packages;
|
|
||||||
latestKernelPackage = lib.last (
|
|
||||||
lib.sort (a: b: (lib.versionOlder a.kernel.version b.kernel.version)) (builtins.attrValues zfsCompatibleKernelPackages)
|
|
||||||
);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Note this might jump back and worth as kernel get added or removed.
|
|
||||||
boot.kernelPackages = latestKernelPackage;
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
systemd.services.log-network-status = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
# No point in restarting this. We just need this after boot
|
|
||||||
restartIfChanged = false;
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
StandardOutput = "journal+console";
|
|
||||||
ExecStart = [
|
|
||||||
# Allow failures, so it still prints what interfaces we have even if we
|
|
||||||
# not get online
|
|
||||||
"-${pkgs.systemd}/lib/systemd/systemd-networkd-wait-online"
|
|
||||||
"${pkgs.iproute2}/bin/ip -c addr"
|
|
||||||
"${pkgs.iproute2}/bin/ip -c -6 route"
|
|
||||||
"${pkgs.iproute2}/bin/ip -c -4 route"
|
|
||||||
"${pkgs.systemd}/bin/networkctl status"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
0
nix/netboot-installer/installer.nix
Normal file
0
nix/netboot-installer/installer.nix
Normal file
|
@ -3,9 +3,6 @@
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/installer/netboot/netboot-minimal.nix")
|
(modulesPath + "/installer/netboot/netboot-minimal.nix")
|
||||||
../installer.nix
|
../installer.nix
|
||||||
../networkd.nix
|
|
||||||
../serial.nix
|
|
||||||
../restore-remote-access.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# We are stateless, so just default to latest.
|
# We are stateless, so just default to latest.
|
||||||
|
@ -16,7 +13,7 @@
|
||||||
paths = with config.system.build; [
|
paths = with config.system.build; [
|
||||||
netbootRamdisk
|
netbootRamdisk
|
||||||
kernel
|
kernel
|
||||||
(pkgs.runCommand "kernel-params" { } ''
|
(pkgs.runCommand "kernel-params" {} ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
ln -s "${config.system.build.toplevel}/kernel-params" $out/kernel-params
|
ln -s "${config.system.build.toplevel}/kernel-params" $out/kernel-params
|
||||||
ln -s "${config.system.build.toplevel}/init" $out/init
|
ln -s "${config.system.build.toplevel}/init" $out/init
|
||||||
|
@ -28,8 +25,9 @@
|
||||||
matchConfig.Type = "ether";
|
matchConfig.Type = "ether";
|
||||||
networkConfig = {
|
networkConfig = {
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
|
LLMNR = "yes";
|
||||||
EmitLLDP = "yes";
|
EmitLLDP = "yes";
|
||||||
IPv6AcceptRA = "yes";
|
IPv6AcceptRA = "no";
|
||||||
MulticastDNS = "yes";
|
MulticastDNS = "yes";
|
||||||
LinkLocalAddressing = "yes";
|
LinkLocalAddressing = "yes";
|
||||||
LLDP = "yes";
|
LLDP = "yes";
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
# Not really needed. Saves a few bytes and the only service we are running is sshd, which we want to be reachable.
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
|
|
||||||
networking.useNetworkd = true;
|
|
||||||
systemd.network.enable = true;
|
|
||||||
|
|
||||||
# mdns
|
|
||||||
networking.firewall.allowedUDPPorts = [ 5353 ];
|
|
||||||
systemd.network.networks."99-ethernet-default-dhcp".networkConfig.MulticastDNS = lib.mkDefault "yes";
|
|
||||||
systemd.network.networks."99-wireless-client-dhcp".networkConfig.MulticastDNS = lib.mkDefault "yes";
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
# take from srvos
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
# Fallback quickly if substituters are not available.
|
|
||||||
nix.settings.connect-timeout = 5;
|
|
||||||
|
|
||||||
# Enable flakes
|
|
||||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
|
||||||
|
|
||||||
# The default at 10 is rarely enough.
|
|
||||||
nix.settings.log-lines = lib.mkDefault 25;
|
|
||||||
|
|
||||||
# Avoid disk full issues
|
|
||||||
nix.settings.max-free = lib.mkDefault (3000 * 1024 * 1024);
|
|
||||||
nix.settings.min-free = lib.mkDefault (512 * 1024 * 1024);
|
|
||||||
|
|
||||||
# TODO: cargo culted.
|
|
||||||
nix.daemonCPUSchedPolicy = lib.mkDefault "batch";
|
|
||||||
nix.daemonIOSchedClass = lib.mkDefault "idle";
|
|
||||||
nix.daemonIOSchedPriority = lib.mkDefault 7;
|
|
||||||
|
|
||||||
# Avoid copying unnecessary stuff over SSH
|
|
||||||
nix.settings.builders-use-substitutes = true;
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
buildGoModule,
|
|
||||||
fetchFromGitHub,
|
|
||||||
hwinfo,
|
|
||||||
libusb1,
|
|
||||||
gcc,
|
|
||||||
pkg-config,
|
|
||||||
util-linux,
|
|
||||||
pciutils,
|
|
||||||
stdenv,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
# We are waiting on some changes to be merged upstream: https://github.com/openSUSE/hwinfo/pulls
|
|
||||||
hwinfoOverride = hwinfo.overrideAttrs {
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "numtide";
|
|
||||||
repo = "hwinfo";
|
|
||||||
rev = "a559f34934098d54096ed2078e750a8245ae4044";
|
|
||||||
hash = "sha256-3abkWPr98qXXQ17r1Z43gh2M5hl/DHjW2hfeWl+GSAs=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
buildGoModule rec {
|
|
||||||
pname = "nixos-facter";
|
|
||||||
version = "0.1.1";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "numtide";
|
|
||||||
repo = "nixos-facter";
|
|
||||||
rev = "v${version}";
|
|
||||||
hash = "sha256-vlPmvCrgX64dcf//BPtQszBt7dkq35JpgQg+/LW0AqM=";
|
|
||||||
};
|
|
||||||
|
|
||||||
vendorHash = "sha256-5leiTNp3FJmgFd0SKhu18hxYZ2G9SuQPhZJjki2SDVs=";
|
|
||||||
|
|
||||||
CGO_ENABLED = 1;
|
|
||||||
|
|
||||||
buildInputs = [
|
|
||||||
libusb1
|
|
||||||
hwinfoOverride
|
|
||||||
];
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
||||||
gcc
|
|
||||||
pkg-config
|
|
||||||
];
|
|
||||||
|
|
||||||
runtimeInputs = [
|
|
||||||
libusb1
|
|
||||||
util-linux
|
|
||||||
pciutils
|
|
||||||
];
|
|
||||||
|
|
||||||
ldflags = [
|
|
||||||
"-s"
|
|
||||||
"-w"
|
|
||||||
"-X git.numtide.com/numtide/nixos-facter/build.Name=nixos-facter"
|
|
||||||
"-X git.numtide.com/numtide/nixos-facter/build.Version=v${version}"
|
|
||||||
"-X github.com/numtide/nixos-facter/pkg/build.System=${stdenv.hostPlatform.system}"
|
|
||||||
];
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
description = "Declarative hardware configuration for NixOS";
|
|
||||||
homepage = "https://github.com/numtide/nixos-facter";
|
|
||||||
license = lib.licenses.gpl3Plus;
|
|
||||||
maintainers = [ lib.maintainers.brianmcgee ];
|
|
||||||
mainProgram = "nixos-facter";
|
|
||||||
platforms = lib.platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{ lib, ... }: {
|
|
||||||
# HACK: Drop this, once we have 24.11 everywhere
|
|
||||||
nixpkgs.overlays = lib.optionals (lib.versionOlder lib.version "24.11pre") [
|
|
||||||
# Both syslinux and grub also reference perl
|
|
||||||
(final: prev: {
|
|
||||||
# we don't need grub: save ~ 60MB
|
|
||||||
grub2 = prev.coreutils;
|
|
||||||
grub2_efi = prev.coreutils;
|
|
||||||
syslinux = prev.coreutils;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,25 +1,13 @@
|
||||||
# This module optimizes for non-interactive deployments by remove some store paths
|
# This module optimizes for non-interactive deployments by remove some store paths
|
||||||
# which are primarily useful for interactive installations.
|
# which are primarily useful for interactive installations.
|
||||||
|
|
||||||
{ lib, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, ... }: {
|
||||||
{
|
|
||||||
disabledModules = [
|
disabledModules = [
|
||||||
# This module adds values to multiple lists (systemPackages, supportedFilesystems)
|
# This module adds values to multiple lists (systemPackages, supportedFilesystems)
|
||||||
# which are impossible/unpractical to remove, so we disable the entire module.
|
# which are impossible/unpractical to remove, so we disable the entire module.
|
||||||
"profiles/base.nix"
|
"profiles/base.nix"
|
||||||
];
|
];
|
||||||
|
|
||||||
imports = [
|
|
||||||
# ./zfs-minimal.nix
|
|
||||||
./no-bootloaders.nix
|
|
||||||
./python-minimal.nix
|
|
||||||
./noveau-workaround.nix
|
|
||||||
# reduce closure size by removing perl
|
|
||||||
"${modulesPath}/profiles/perlless.nix"
|
|
||||||
# FIXME: we still are left with nixos-generate-config due to nixos-install-tools
|
|
||||||
{ system.forbiddenDependenciesRegexes = lib.mkForce []; }
|
|
||||||
];
|
|
||||||
|
|
||||||
# among others, this prevents carrying a stdenv with gcc in the image
|
# among others, this prevents carrying a stdenv with gcc in the image
|
||||||
system.extraDependencies = lib.mkForce [ ];
|
system.extraDependencies = lib.mkForce [ ];
|
||||||
|
|
||||||
|
@ -27,32 +15,20 @@
|
||||||
nix.registry = lib.mkForce { };
|
nix.registry = lib.mkForce { };
|
||||||
|
|
||||||
# would pull in nano
|
# would pull in nano
|
||||||
programs.nano.enable = false;
|
programs.nano.syntaxHighlight = lib.mkForce false;
|
||||||
|
|
||||||
# prevents strace
|
# prevents nano, strace
|
||||||
environment.defaultPackages = lib.mkForce [
|
environment.defaultPackages = lib.mkForce [
|
||||||
pkgs.rsync
|
pkgs.rsync
|
||||||
pkgs.parted
|
pkgs.parted
|
||||||
pkgs.gptfdisk
|
(pkgs.zfs.override {
|
||||||
pkgs.e2fsprogs
|
# this overrides saves 10MB
|
||||||
|
samba = pkgs.coreutils;
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
# normal users are not allowed with sys-users
|
|
||||||
# see https://github.com/NixOS/nixpkgs/pull/328926
|
|
||||||
users.users.nixos = {
|
|
||||||
isSystemUser = true;
|
|
||||||
isNormalUser = lib.mkForce false;
|
|
||||||
shell = "/run/current-system/sw/bin/bash";
|
|
||||||
group = "nixos";
|
|
||||||
};
|
|
||||||
users.groups.nixos = {};
|
|
||||||
|
|
||||||
# we prefer root as this is also what we use in nixos-anywhere
|
|
||||||
services.getty.autologinUser = lib.mkForce "root";
|
|
||||||
|
|
||||||
# we are missing this from base.nix
|
# we are missing this from base.nix
|
||||||
boot.supportedFilesystems = [
|
boot.supportedFilesystems = [
|
||||||
"ext4"
|
|
||||||
"btrfs"
|
"btrfs"
|
||||||
# probably not needed but does not seem to increase closure size
|
# probably not needed but does not seem to increase closure size
|
||||||
"cifs"
|
"cifs"
|
||||||
|
@ -65,9 +41,15 @@
|
||||||
"vfat"
|
"vfat"
|
||||||
"xfs"
|
"xfs"
|
||||||
];
|
];
|
||||||
boot.kernelModules = [
|
boot = {
|
||||||
# we have to explicitly enable this, otherwise it is not loaded even when creating a raid:
|
kernelModules = [ "zfs" ];
|
||||||
# https://github.com/nix-community/nixos-anywhere/issues/249
|
extraModulePackages = [
|
||||||
"dm-raid"
|
config.boot.kernelPackages.zfs
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.hostId = lib.mkDefault "8425e349";
|
||||||
|
|
||||||
|
# we can drop this after 23.05 has been released, which has this set by default
|
||||||
|
hardware.enableRedistributableFirmware = lib.mkForce false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
# fixes blank screen on boot for some cards
|
|
||||||
boot.kernelParams = [ "nouveau.modeset=0" ];
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
nixpkgs.overlays = [
|
|
||||||
(final: prev: {
|
|
||||||
bcachefs-tools = prev.bcachefs-tools.override { python3 = final.python3Minimal; };
|
|
||||||
cifs-utils = prev.cifs-utils.override { python3 = final.python3Minimal; };
|
|
||||||
nfs-utils = prev.nfs-utils.override { python3 = final.python3Minimal; };
|
|
||||||
talloc = prev.talloc.override { python3 = final.python3Minimal; };
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
# We have a bug in 23.11 in combination with netboot.
|
|
||||||
boot.initrd.systemd.enable = true;
|
|
||||||
boot.initrd.systemd.services.restore-state-from-initrd = {
|
|
||||||
unitConfig = {
|
|
||||||
DefaultDependencies = false;
|
|
||||||
RequiresMountsFor = "/sysroot /dev";
|
|
||||||
};
|
|
||||||
wantedBy = [ "initrd.target" ];
|
|
||||||
requiredBy = [ "rw-etc.service" ];
|
|
||||||
before = [ "rw-etc.service" ];
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
# Restore ssh host and user keys if they are available.
|
|
||||||
# This avoids warnings of unknown ssh keys.
|
|
||||||
script = ''
|
|
||||||
mkdir -m 700 -p /sysroot/root/.ssh
|
|
||||||
mkdir -m 755 -p /sysroot/etc/ssh
|
|
||||||
mkdir -m 755 -p /sysroot/root/network
|
|
||||||
if [[ -f ssh/authorized_keys ]]; then
|
|
||||||
install -m 400 ssh/authorized_keys /sysroot/root/.ssh
|
|
||||||
fi
|
|
||||||
install -m 400 ssh/ssh_host_* /sysroot/etc/ssh
|
|
||||||
cp *.json /sysroot/root/network/
|
|
||||||
if [[ -f machine-id ]]; then
|
|
||||||
cp machine-id /sysroot/etc/machine-id
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
# IPMI SOL console redirection stuff
|
|
||||||
boot.kernelParams =
|
|
||||||
[ "console=tty0" ]
|
|
||||||
++ (lib.optional (
|
|
||||||
pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64
|
|
||||||
) "console=ttyAMA0,115200")
|
|
||||||
++ (lib.optional (pkgs.stdenv.hostPlatform.isRiscV) "console=ttySIF0,115200")
|
|
||||||
++ [ "console=ttyS0,115200" ];
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
# incorperate a space-optimized version of zfs
|
|
||||||
let
|
|
||||||
zfs = pkgs.zfsUnstable.override {
|
|
||||||
# this overrides saves 10MB
|
|
||||||
samba = pkgs.coreutils;
|
|
||||||
|
|
||||||
python3 = pkgs.python3Minimal;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.udev.packages = [ zfs ]; # to hook zvol naming, etc.
|
|
||||||
# unsure if need this, but in future udev rules could potentially point to systemd services.
|
|
||||||
systemd.packages = [ zfs ];
|
|
||||||
environment.defaultPackages = lib.mkForce [ zfs ]; # this merges with outer noninteractive module.
|
|
||||||
|
|
||||||
boot.kernelModules = [ "zfs" ];
|
|
||||||
boot.extraModulePackages = [ config.boot.kernelPackages.zfs_unstable ];
|
|
||||||
|
|
||||||
networking.hostId = lib.mkDefault "8425e349";
|
|
||||||
}
|
|
Loading…
Reference in a new issue