summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configuration.nix28
-rw-r--r--install.nix90
-rw-r--r--kexec.nix72
-rw-r--r--release.nix37
-rw-r--r--target-config.nix26
5 files changed, 253 insertions, 0 deletions
diff --git a/configuration.nix b/configuration.nix
new file mode 100644
index 0000000..da4d3b1
--- /dev/null
+++ b/configuration.nix
@@ -0,0 +1,28 @@
+# new cmd: nix-build '<nixpkgs/nixos>' -A config.system.build.kexec_tarball -I nixos-config=./configuration.nix -Q -j 4
+
+{ lib, pkgs, config, ... }:
+
+with lib;
+
+{
+ imports = [
+ <nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix>
+ ./kexec.nix
+ ./install.nix
+ ];
+
+ # nixos-install doesn't work with nixUnstable
+ nix.package = mkForce pkgs.nixStable;
+
+ boot.loader.grub.enable = false;
+ boot.kernelParams = [
+ "console=ttyS0,115200" # allows certain forms of remote access, if the hardware is setup right
+ "panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
+ ];
+
+ networking.hostName = "kexec";
+ hardware = {
+ enableRedistributableFirmware = mkForce false;
+ opengl.driSupport = mkForce false;
+ };
+}
diff --git a/install.nix b/install.nix
new file mode 100644
index 0000000..f4186c7
--- /dev/null
+++ b/install.nix
@@ -0,0 +1,90 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+let
+ cfg = config.kexec.justdoit;
+in {
+ options = {
+ kexec.justdoit = {
+ rootDevice = mkOption {
+ type = types.str;
+ default = "/dev/sda";
+ description = "the root block device that justdoit will nuke from orbit and force nixos onto";
+ };
+ bootSize = mkOption {
+ type = types.int;
+ default = 256;
+ description = "size of /boot in mb";
+ };
+ swapSize = mkOption {
+ type = types.int;
+ default = 1024;
+ description = "size of swap in mb";
+ };
+ };
+ };
+
+ config = lib.mkIf true {
+ system.build.justdoit = pkgs.writeScriptBin "justdoit" ''
+ #!${pkgs.stdenv.shell}
+
+ set -e
+
+ vgchange -a n
+
+ dd if=/dev/zero of=${cfg.rootDevice} bs=512 count=10000
+
+ sfdisk ${cfg.rootDevice} <<EOF
+ label: dos
+ device: ${cfg.rootDevice}
+ unit: sectors
+ ${cfg.rootDevice}1 : size=${toString (2048 * cfg.bootSize)}, type=83
+ ${cfg.rootDevice}2 : size=${toString (2048 * cfg.swapSize)}, type=82
+ ${cfg.rootDevice}3 : type=83
+ EOF
+ export ROOT_DEVICE=${cfg.rootDevice}3
+ export SWAP_DEVICE=${cfg.rootDevice}2
+
+ mkdir -p /mnt
+
+ mkfs.ext4 ${cfg.rootDevice}1 -L NIXOS_BOOT
+ mkswap $SWAP_DEVICE -L NIXOS_SWAP
+ mkfs.ext4 $ROOT_DEVICE -L NIXOS_ROOT
+
+ swapon $SWAP_DEVICE
+ mount $ROOT_DEVICE /mnt/
+ mkdir -p /mnt/boot/
+ mount -t ext4 ${cfg.rootDevice}1 /mnt/boot/
+
+ nixos-generate-config --root /mnt/
+
+ hostId=$(echo $(head -c4 /dev/urandom | od -A none -t x4))
+ cp ${./target-config.nix} /mnt/etc/nixos/configuration.nix
+
+ cat > /mnt/etc/nixos/generated.nix <<EOF
+ { ... }: {
+ boot.loader.grub.device = "${cfg.rootDevice}";
+ networking.hostId = "$hostId"; # required for zfs use
+ }
+ EOF
+
+ nixos-install --no-root-passwd -j 4
+ reboot
+ '';
+ environment.systemPackages = [ config.system.build.justdoit ];
+
+ systemd.services.performInstall = {
+ requiredBy = [ "multi-user.target" ];
+
+ path = with pkgs; [
+ nixStable lvm2 utillinux e2fsprogs
+ ] ++ (with config.system.build; [
+ nixos-install nixos-generate-config
+ ]);
+
+ environment.NIX_PATH = lib.concatStringsSep ":" config.nix.nixPath;
+
+ script = "${config.system.build.justdoit}/bin/justdoit";
+ };
+ };
+}
diff --git a/kexec.nix b/kexec.nix
new file mode 100644
index 0000000..3556f28
--- /dev/null
+++ b/kexec.nix
@@ -0,0 +1,72 @@
+{ pkgs, config, ... }:
+
+{
+ system.build = rec {
+ image = pkgs.runCommand "image" { buildInputs = [ pkgs.nukeReferences ]; } ''
+ mkdir $out
+ cp ${config.system.build.kernel}/bzImage $out/kernel
+ cp ${config.system.build.netbootRamdisk}/initrd $out/initrd
+ echo "init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}" > $out/cmdline
+ nuke-refs $out/kernel
+ '';
+
+ kexec_script = pkgs.writeTextFile {
+ executable = true;
+ name = "kexec-nixos";
+ text = ''
+ #!${pkgs.stdenv.shell}
+ export PATH=${pkgs.kexectools}/bin:${pkgs.cpio}/bin:$PATH
+ set -x
+ cd $(mktemp -d)
+ pwd
+ mkdir initrd
+ pushd initrd
+ cat /ssh_pubkey >> authorized_keys
+ find -type f | cpio -o -H newc | gzip -9 > ../extra.gz
+ popd
+ cat ${image}/initrd extra.gz > final.gz
+
+ kexec -l ${image}/kernel --initrd=final.gz --append="init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}"
+ sync
+ echo "executing kernel, filesystems will be improperly umounted"
+ kexec -e
+ '';
+ };
+
+ kexec_tarball = pkgs.callPackage <nixpkgs/nixos/lib/make-system-tarball.nix> {
+ storeContents = [
+ { object = config.system.build.kexec_script; symlink = "/kexec_nixos"; }
+ ];
+ contents = [];
+ };
+
+ kexec_tarball_self_extract_script = pkgs.writeTextFile {
+ executable = true;
+ name = "kexec-nixos";
+ text = ''
+ #!/bin/sh
+ ARCHIVE=`awk '/^__ARCHIVE_BELOW__/ { print NR + 1; exit 0; }' $0`
+
+ tail -n+$ARCHIVE $0 | tar xJ -C /
+ /kexec_nixos
+
+ exit 0
+
+ __ARCHIVE_BELOW__
+ '';
+ };
+
+ kexec_bundle = pkgs.runCommand "kexec_bundle" {} ''
+ cat \
+ ${kexec_tarball_self_extract_script} \
+ ${kexec_tarball}/tarball/nixos-system-${kexec_tarball.system}.tar.xz \
+ > $out
+ chmod +x $out
+ '';
+ };
+
+ boot.initrd.postMountCommands = ''
+ mkdir -p /mnt-root/root/.ssh/
+ cp /authorized_keys /mnt-root/root/.ssh/
+ '';
+}
diff --git a/release.nix b/release.nix
new file mode 100644
index 0000000..7dd11aa
--- /dev/null
+++ b/release.nix
@@ -0,0 +1,37 @@
+let
+ pkgs = import <nixpkgs> { config = {}; };
+ callPackage = pkgs.newScope self;
+ self = {
+ kexec_tarball = (import <nixpkgs/nixos> {
+ configuration = ./configuration.nix;
+ }).config.system.build.kexec_tarball;
+
+ kexec_bundle = (import <nixpkgs/nixos> {
+ configuration = ./configuration.nix;
+ }).config.system.build.kexec_bundle;
+
+ qemu_test1 = let
+ config = (import <nixpkgs/nixos> { configuration = ./configuration.nix; }).config;
+ image = config.system.build.image;
+ in pkgs.writeScriptBin "qemu_test1" ''
+ #!${pkgs.stdenv.shell}
+ export PATH=${pkgs.qemu_kvm}/bin/:$PATH
+
+ if ! test -e dummy_root.qcow2; then
+ qemu-img create -f qcow2 dummy_root.qcow2 20G
+ fi
+
+ qemu-kvm -kernel ${image}/kernel -initrd ${image}/initrd -m 2048 -append "init=${builtins.unsafeDiscardStringContext config.system.build.toplevel}/init ${toString config.boot.kernelParams}" -monitor stdio -drive index=0,id=drive1,file=dummy_root.qcow2,cache=writeback,werror=report,if=virtio
+ '';
+ qemu_test2 = pkgs.writeScriptBin "qemu_test2" ''
+ #!${pkgs.stdenv.shell}
+ export PATH=${pkgs.qemu_kvm}/bin/:$PATH
+
+ qemu-kvm -monitor stdio -drive index=0,id=drive1,file=dummy_root.qcow2,cache=writeback,werror=report,if=virtio
+ '';
+ qemu_test = pkgs.buildEnv {
+ name = "qemu_test";
+ paths = with self; [ qemu_test1 qemu_test2 ];
+ };
+ };
+in self
diff --git a/target-config.nix b/target-config.nix
new file mode 100644
index 0000000..8243786
--- /dev/null
+++ b/target-config.nix
@@ -0,0 +1,26 @@
+{ ... }:
+
+{
+ imports = [
+ ./hardware-configuration.nix
+ ./generated.nix
+ ];
+
+ boot.loader.grub = {
+ enable = true;
+ version = 2;
+ };
+
+ services.openssh = {
+ enable = true;
+ permitRootLogin = "yes";
+ };
+
+ users.users.root.openssh.authorizedKeys.keys = [
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDuNResYJNUNlReRIxPMMnI3hAaW5dNs3E2qoeqHsU/nwnL+czVKOkHnG8gQaKSN7q0wVP3o3ozSsGHdYBJ0YrAYMccOPGkPJ6Aua/7LBkxTc1bVbGrPAEVDYfvNKTU0KjbOfUt6bAbtx1KzbzttBHRR14AxHSUH3ELja6a1foATQWyArLmykmo8aFp75n9+b8XVkmtVtSB0VFibMGwLekNgTD1zOZfzqjxD2EQop279Y8s9kfadpxznONLBNgNUZEzkk++MTh2a6OXW4WA2+dH8WaG2hwjghYbqSDlYe9yjyxhRS0ZtUuVlxlMlTsn0MIt/fYlYNSJts4I11ehBQFkzWUv/i/BgKFKX2M1A5fZTI9emlKJ/Iz3EyXNg1VNc/8iCVaWMpKUbT8Hao8qvwihoZegyVZRmCbUDyxVpjy2Qyl3/dl8mjsYbzYK6CyLo198rCeSrYlF7c81KikPmNuibzSL0UHvA94HK7hVWfu+iZKPZOYVdIle25+hZcL+s7GROy5iGWA9qwgaqXShbqhyyg/lXCY8MdyDBdomWrdk9SvQ0hbNLwSrNlcHAoO3H8/HRcoW4/faiFsm8SFF4RnsIYfVNKCUYlf4kspbHUxUWuEMtOxpo/uu3Zs7hI+TQL9FKwrLRgnu72sx0Y1o4PIGHUldSgzoYAxL+EaF3qgYhoOyiVFa5IRioaG9FRFJ1hboq+0XxQXYzJ8z9CrRa/Gxrp/Etqdevm8IjuOWelDAR4UPgeQsvjHvZVxLOGay8wBtA0/My9meouPDn7jzPjfFUcmdB99PM/PfrqJBC+WdldEfURrAeax6b2LidFl3bN4BLGwK0BlPybjgj7jm1THMnnM4F7BmhzA8MN1tmcEIiZSbW3lRjMxTikGkhvq1NbMp/k6ZmMkwJcwORSJRVdji3wYOuQxl2/u+Ey2NtBXyA5TomPvkWR/h9us+2/8WOxVlpjs6PtYEguehLbuqPWANM1FG9ngAMc1yGMp9YXPKQn+xVvOssOK6VoAu57q9zHJ5GQe8Pm6+2Qpq7hWRDkxIfnDGAeLDIlHa4JunX+okSCH14fx2PpwRfQ1UUhp5wnDtcAfkWGmq82HQknAigNWih5LqPthfjMuhUUcgYsciWYFKZbum4/yecfXUUx9SlcAwVrEZ+kwvNw1UsjrRtITsCBaBlSDpioyXYmJ6ldxUOKZiqAvAKeB0zRF3xpALWZuADh22BzWaNeLL8Gw5uR9TV7PGQ9wpd07SRsdabqLtYqg2P0/t+zPlKHNkL80vZjmuYJeHZ6Zmv3K4PsKEsHG3nXcA8PUI09IfvBbUnzlUb46V5K2O6E3iiSeQBRv7jWEkwGZy9/lBMUM7Qxw3a9Hv till@hoeppner.ws"
+ ];
+
+ boot.kernelParams = [
+ "panic=30" "boot.panic_on_fail" # reboot the machine upon fatal boot issues
+ ];
+}