592 lines
22 KiB
Org Mode
592 lines
22 KiB
Org Mode
:PROPERTIES:
|
|
:ID: cce/nixos_automatic_partitioning_installer
|
|
:ROAM_ALIASES: justdoit.nix
|
|
:END:
|
|
#+TITLE: NixOS Automatic Partitioning Installer
|
|
#+filetags: :Project:CCE:
|
|
|
|
#+PROPERTY: header-args :mkdirp yes
|
|
|
|
#+ARCOLOGY_KEY: cce/nixos-installer
|
|
#+ARCOLOGY_ALLOW_CRAWL: t
|
|
|
|
There are a few "Supported" methods for installing NixOS: you can use the [[https://nixos.org/manual/nixos/stable/index.html#sec-installation][installer image]] to manually partition and prepare a system, you can [[https://nixos.org/manual/nixos/stable/index.html#sec-installing-from-other-distro][LUSTRATE]] an existing Linux installation with Nix installed on it, or you can use a [[https://github.com/cleverca22/nix-tests/tree/master/kexec][kexec script]] generally referred to as =justdoit= which is distributed as a script which boots the system in to a NixOS system with a partitioning script which blindly partitions the =rootDevice= and installs NixOS on to that partition. I spent some time this month trying to get the [[https://github.com/cleverca22/nix-tests/tree/master/kexec][kexec method]] working and it was pretty frustrating. The auto-partitioner and the easy setup through =kexec.justdoit= is nice, but getting the =kexec= working out of the box was frustrating[fn:1:nothing worth complaining about: fedora couldn't kexec the images, fedora couldn't expand the images without doing =TMPDIR=/var/tmp= because tmp is a ramdisk... my mongrel [[id:fedora_linux][Fedora Linux]] plus [[id:cce/home-manager][home-manager]] environment struggled to get virtualization running, and the testing cycle was pretty painful. The [[https://github.com/cleverca22/nix-tests/tree/master/kexec][repository]] I based this around was broken OOTB and even the testing scripts included in it didn't work reliably. The =justdoit= itself took a fair bit of tweaking to get to booting, too. I'll reintegrate kexec some day.], so for now I'll stick with ISO and ISO-as-SD with the =justdoit= work included.
|
|
|
|
To build an ISO image: [[shell:pushd ~/arroyo-nix/kexec && nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixos-config=configuration.nix &]] The file will get symlinked to [[file:~/arroyo-nix/kexec/result/iso]].
|
|
|
|
* [[id:cce/my_nixos_configuration][My NixOS configuration]]
|
|
* Configuring the Installer
|
|
|
|
This record describes a basic NixOS installation which runs an installer script and can optionally be configured to automatically reboot (see below).
|
|
|
|
#+begin_src nix :tangle ~/arroyo-nix/kexec/configuration.nix :noweb yes
|
|
{ lib, pkgs, config, ... }:
|
|
|
|
let
|
|
overlayFn = import <arroyo/overlay.nix>;
|
|
pkgs' = overlayFn pkgs {};
|
|
in with lib;
|
|
{
|
|
imports = [
|
|
<nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix>
|
|
./kexec.nix ./justdoit.nix
|
|
];
|
|
|
|
nixpkgs.overlays = [
|
|
(overlayFn)
|
|
];
|
|
|
|
boot.supportedFilesystems = [ "zfs" ];
|
|
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
|
|
];
|
|
systemd.services.sshd.wantedBy = mkForce [ "multi-user.target" ];
|
|
networking.hostName = "kexec";
|
|
# for the children
|
|
networking.wireless.enable = false;
|
|
networking.networkmanager.enable = true;
|
|
# hahaha! yes!
|
|
users.users.root.openssh.authorizedKeys.keys = pkgs'.lib.publicKeys.rrix;
|
|
|
|
hardware.video.hidpi.enable = true;
|
|
|
|
isoImage = {
|
|
includeSystemBuildDependencies = false;
|
|
makeUsbBootable = true;
|
|
};
|
|
|
|
kexec.justdoit = {
|
|
hostName = "terra-firma";
|
|
rootDevice = "/dev/sde";
|
|
swapSize = 16384;
|
|
poolName = "terra-firma";
|
|
bootType = "vfat";
|
|
bootSize = 1024;
|
|
|
|
luksEncrypt = false;
|
|
uefi = false;
|
|
nvme = false;
|
|
|
|
zfsPools = {
|
|
terra-firma = {
|
|
devices = "$ROOT_DEVICE";
|
|
volumes = {
|
|
root = {
|
|
snapshot = false;
|
|
compression = false;
|
|
mountPoint = "/";
|
|
};
|
|
nix = {
|
|
snapshot = false;
|
|
compression = false;
|
|
mountPoint = "/nix";
|
|
};
|
|
};
|
|
};
|
|
tank = {
|
|
devices = "mirror /dev/sda /dev/sdb mirror /dev/sdc /dev/sdd";
|
|
volumes = {
|
|
home = {
|
|
snapshot = true;
|
|
compression = "lz4";
|
|
mountPoint = "/home";
|
|
};
|
|
media = {
|
|
snapshot = true;
|
|
compression = "lz4";
|
|
mountPoint = "/media";
|
|
};
|
|
srv = {
|
|
snapshot = true;
|
|
compression = false;
|
|
mountPoint = "/srv";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|
|
#+end_src
|
|
|
|
That [[id:09779ac0-4d5f-40db-a340-49595c717e03][noweb]] call [[(gen_call)]] gets my public ssh key this way. i should and could and will define this in my [[id:cce/ssh_configuration][SSH Configuration]]:
|
|
|
|
#+NAME: get_ssh_pubkey
|
|
#+begin_src shell :results drawer -n
|
|
[ -f ~/.ssh/id_rsa.pub ] && \
|
|
cat ~/.ssh/id_rsa.pub \
|
|
| awk 'BEGIN {print "["} {print "\"" $1 " " $2 "\"" } END {print "];"}' \ (ref:tr)
|
|
| tr \\n " "
|
|
#+end_src
|
|
|
|
LMAO there must be a way to get [[(tr)]]'s awk output on to one line but ORS doesn't do what i expect...
|
|
|
|
** Minimal =target-config.nix=
|
|
|
|
A subset of [[id:cce/my_nixos_configuration][My NixOS configuration]], enough to get the rest [[id:cce/morph][Morph]] deployed to it. Head over there for in-depth discussion.
|
|
|
|
#+begin_src nix :tangle ~/arroyo-nix/kexec/target-config.nix :noweb yes
|
|
{ config, pkgs, ... }:
|
|
|
|
{
|
|
imports = [ ./hardware-configuration.nix ./generated.nix ];
|
|
|
|
# boot.loader.systemd-boot.enable = true;
|
|
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
|
|
|
services.openssh.enable = true;
|
|
|
|
boot.zfs.forceImportRoot = true;
|
|
|
|
boot.kernelParams = [
|
|
"boot.shell_on_fail"
|
|
];
|
|
|
|
# less nix crap
|
|
nix.gc.automatic = true;
|
|
nix.gc.dates = "23:30";
|
|
|
|
# system clock
|
|
time.timeZone = "America/Los_Angeles";
|
|
|
|
users.groups.humans = {
|
|
name = "humans";
|
|
gid = 1000;
|
|
};
|
|
users.users.rrix = {
|
|
isNormalUser = true;
|
|
home = "/home/rrix";
|
|
description = "Ryan Rix";
|
|
extraGroups = [ "wheel" "networkmanager" "adbusers" ];
|
|
uid = 1000;
|
|
group = "humans";
|
|
initialPassword = "changeme!";
|
|
openssh.authorizedKeys.keys = <<get_ssh_pubkey()>>
|
|
};
|
|
users.users.root.openssh.authorizedKeys.keys = <<get_ssh_pubkey()>> # (ref:gen_call)
|
|
|
|
hardware.video.hidpi.enable = true;
|
|
|
|
# networking
|
|
networking.wireless.enable = false;
|
|
networking.networkmanager.enable = true;
|
|
|
|
# hahaha! yes
|
|
nixpkgs.config = { allowUnfree = true; };
|
|
|
|
# power management
|
|
powerManagement.enable = true;
|
|
|
|
environment.systemPackages = (with pkgs.libsForQt5; [
|
|
pkgs.vim
|
|
]);
|
|
}
|
|
#+end_src
|
|
|
|
*** NEXT Would be pretty neat to add a bootstrap script here...
|
|
|
|
open up a konsole and run =bootstrap= or =bootstrap-local= to get a backup restored on to the machine? =bootstrap-push= might be better but a bootstrap script is so alluring!
|
|
|
|
** =config.system.build.justdoit= formats and installs a system
|
|
:PROPERTIES:
|
|
:ID: nixos_justdoit
|
|
:END:
|
|
|
|
#+begin_src nix :tangle ~/arroyo-nix/kexec/justdoit.nix
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
with lib;
|
|
let
|
|
cfg = config.kexec.justdoit;
|
|
x = if cfg.nvme then "p" else "";
|
|
in {
|
|
options = {
|
|
kexec.justdoit = {
|
|
hostName = mkOption {
|
|
type = types.str;
|
|
description = "set the networking.hostName of the installed system";
|
|
};
|
|
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";
|
|
};
|
|
bootType = mkOption {
|
|
type = types.enum [ "ext4" "vfat" "zfs" ];
|
|
default = "ext4";
|
|
};
|
|
swapSize = mkOption {
|
|
type = types.int;
|
|
default = 1024;
|
|
description = "size of swap in mb";
|
|
};
|
|
poolName = mkOption {
|
|
type = types.str;
|
|
default = "tank";
|
|
description = "zfs pool name";
|
|
};
|
|
luksEncrypt = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "encrypt all of zfs and swap";
|
|
};
|
|
uefi = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "create a uefi install";
|
|
};
|
|
nvme = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "rootDevice is nvme";
|
|
};
|
|
zfsPools = mkOption {
|
|
type = types.attrs;
|
|
default = {
|
|
"${cfg.poolName}" = {
|
|
devices = "$ROOT_DEVICE";
|
|
volumes = {
|
|
nix = { mountPoint = "/nix"; };
|
|
root = { mountPoint = "/"; };
|
|
};
|
|
};
|
|
};
|
|
description = "Extra ZFS pools to create and mount";
|
|
example = {
|
|
kiddypool = {
|
|
devices = "$ROOT_DEVICE";
|
|
volumes = {
|
|
nix = {
|
|
snapshot = false;
|
|
compression = false;
|
|
mountPoint = "/nix";
|
|
};
|
|
root ={
|
|
snapshot = false;
|
|
compression = "lz4";
|
|
mountPoint = "/";
|
|
};
|
|
};
|
|
};
|
|
deepend = {
|
|
devices = "mirror /dev/sda /dev/sdb mirror /dev/sdc /dev/sdd";
|
|
volumes = {
|
|
home = {
|
|
snapshot = true;
|
|
compression = "lz4";
|
|
mountPoint = "/home";
|
|
};
|
|
media = {
|
|
snapshot = true;
|
|
compression = false;
|
|
mountPoint = "/media";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
config = let
|
|
mkBootTable = {
|
|
ext4 = "mkfs.ext4 $NIXOS_BOOT -L NIXOS_BOOT";
|
|
vfat = "mkfs.vfat $NIXOS_BOOT -n NIXOS_BOOT";
|
|
zfs = "";
|
|
};
|
|
|
|
mkZfsCreateCmd =
|
|
(poolName: volName: vol:
|
|
"zfs create ${lib.optionalString (lib.isString vol.compression) "-o compression=${vol.compression}"} -o mountpoint=legacy ${poolName}/${volName}");
|
|
zfsPoolSetup = concatStringsSep "\n"
|
|
(lib.mapAttrsToList
|
|
(poolName: pool:
|
|
lib.concatStringsSep "\n"
|
|
(["zpool create -f -o altroot=/mnt/${poolName} ${poolName} ${pool.devices}"] ++
|
|
(lib.mapAttrsToList (mkZfsCreateCmd poolName) pool.volumes)))
|
|
cfg.zfsPools);
|
|
|
|
mkSnapshotCmd = (poolName: volName: vol:
|
|
"zfs set com.sun:auto-snapshot=${boolToString vol.snapshot} ${poolName}/${volName}");
|
|
zfsPoolSnapshotRules = concatStringsSep "\n"
|
|
(lib.mapAttrsToList
|
|
(poolName: pool:
|
|
lib.concatStringsSep "\n"
|
|
(["zfs set com.sun:auto-snapshot=false ${poolName}"] ++
|
|
(lib.mapAttrsToList (mkSnapshotCmd poolName) pool.volumes)))
|
|
cfg.zfsPools);
|
|
|
|
# mounts need to be sorted so that /mnt doesn't occlude /mnt/home etc later on...
|
|
mkMountCmd = (poolName: volName: vol:
|
|
{sortKey = "/mnt${vol.mountPoint}";
|
|
theCommand = "mkdir -p /mnt${vol.mountPoint} && mount -t zfs ${poolName}/${volName} /mnt${vol.mountPoint}";});
|
|
mkZfsPoolMountCommands = cmd:
|
|
(lists.toposort (p1: p2: hasPrefix p1.sortKey p2.sortKey)
|
|
(flatten
|
|
(mapAttrsToList
|
|
(poolName: pool:
|
|
(mapAttrsToList (cmd poolName) pool.volumes))
|
|
cfg.zfsPools)));
|
|
zfsPoolMountCommands =
|
|
concatStringsSep "\n"
|
|
(map (pair: pair.theCommand)
|
|
(mkZfsPoolMountCommands mkMountCmd).result);
|
|
|
|
mkUmountCmd = (poolName: volName: vol:
|
|
{sortKey = "/mnt${vol.mountPoint}";
|
|
theCommand = "umount /mnt${vol.mountPoint}";});
|
|
zfsPoolUmountCommands =
|
|
concatStringsSep "\n"
|
|
(reverseList
|
|
(map (pair: pair.theCommand)
|
|
(mkZfsPoolMountCommands mkUmountCmd).result));
|
|
|
|
in lib.mkIf true {
|
|
system.build.justdoit = pkgs.writeScriptBin "justdoit" ''
|
|
#!${pkgs.stdenv.shell}
|
|
set -e
|
|
vgchange -a n
|
|
wipefs -a ${cfg.rootDevice}
|
|
dd if=/dev/zero of=${cfg.rootDevice} bs=512 count=10000
|
|
sfdisk ${cfg.rootDevice} <<EOF
|
|
label: gpt
|
|
device: ${cfg.rootDevice}
|
|
unit: sectors
|
|
${lib.optionalString (cfg.bootType != "zfs") "1 : size=${toString (2048 * cfg.bootSize)}, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B"}
|
|
${lib.optionalString (! cfg.uefi) "4 : size=4096, type=21686148-6449-6E6F-744E-656564454649"}
|
|
2 : size=${toString (2048 * cfg.swapSize)}, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
|
|
3 : type=0FC63DAF-8483-4772-8E79-3D69D8477DE4
|
|
EOF
|
|
${if cfg.luksEncrypt then ''
|
|
cryptsetup luksFormat ${cfg.rootDevice}${x}2
|
|
cryptsetup open --type luks ${cfg.rootDevice}${x}2 swap
|
|
cryptsetup luksFormat ${cfg.rootDevice}${x}3
|
|
cryptsetup open --type luks ${cfg.rootDevice}${x}3 root
|
|
export ROOT_DEVICE=/dev/mapper/root
|
|
export SWAP_DEVICE=/dev/mapper/swap
|
|
'' else ''
|
|
export ROOT_DEVICE=${cfg.rootDevice}${x}3
|
|
export SWAP_DEVICE=${cfg.rootDevice}${x}2
|
|
''}
|
|
${lib.optionalString (cfg.bootType != "zfs") "export NIXOS_BOOT=${cfg.rootDevice}${x}1"}
|
|
${mkBootTable.${cfg.bootType}}
|
|
mkswap $SWAP_DEVICE -L NIXOS_SWAP
|
|
${lib.optionalString (cfg.zfsPools != {}) zfsPoolSetup}
|
|
${lib.optionalString (cfg.zfsPools != {}) zfsPoolSnapshotRules}
|
|
swapon $SWAP_DEVICE
|
|
${lib.optionalString (cfg.zfsPools != {}) zfsPoolMountCommands}
|
|
mkdir -p /mnt/boot
|
|
${lib.optionalString (cfg.bootType != "zfs") "mount $NIXOS_BOOT /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
|
|
{ ... }:
|
|
{
|
|
${lib.optionalString (cfg.hostName != "") "networking.hostName = \"${cfg.hostName}\";"}
|
|
${if cfg.uefi then ''
|
|
# boot.loader.grub.efiInstallAsRemovable = true;
|
|
# boot.loader.grub.efiSupport = true;
|
|
# boot.loader.grub.device = "nodev";
|
|
boot.loader.efi.canTouchEfiVariables = true;
|
|
boot.loader.systemd-boot.enable = true;
|
|
'' else ''
|
|
boot.loader.grub.enable = true;
|
|
# boot.loader.grub.device = "${cfg.rootDevice}";
|
|
boot.loader.grub.device = "/dev/sdf";
|
|
''}
|
|
networking.hostId = "$hostId"; # required for zfs use
|
|
${if cfg.luksEncrypt ''
|
|
boot.zfs.devNodes = "/dev/mapper"; # (ref:devNodes)
|
|
boot.initrd.luks.devices = {
|
|
"swap" = { name = "swap"; device = "${cfg.rootDevice}${x}2"; preLVM = true; };
|
|
"root" = { name = "root"; device = "${cfg.rootDevice}${x}3"; preLVM = true; };
|
|
};
|
|
'' else ''
|
|
boot.zfs.devNodes = "/dev/disk/by-uuid"; # (ref:devNodes)
|
|
''}
|
|
}
|
|
EOF
|
|
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
|
|
export NIX_PATH="home-manager=/nix/var/nix/profiles/per-user/root/channels/home-manager/:$NIX_PATH"
|
|
nix-channel --update
|
|
nixos-install
|
|
${lib.optionalString (cfg.bootType != "zfs") "umount /mnt/boot"}
|
|
${lib.optionalString (cfg.zfsPools != {}) zfsPoolUmountCommands}
|
|
zpool set cachefile=none ${cfg.poolName}
|
|
zpool export ${cfg.poolName}
|
|
swapoff $SWAP_DEVICE
|
|
'';
|
|
environment.systemPackages = [ config.system.build.justdoit ];
|
|
boot.supportedFilesystems = [ "zfs" ];
|
|
};
|
|
}
|
|
#+end_src
|
|
|
|
** =system.build.kexec_tarball= produces a =kexecutable= file
|
|
:PROPERTIES:
|
|
:ID: nixos_kexec_tarball
|
|
:END:
|
|
|
|
#+begin_src nix :tangle ~/arroyo-nix/kexec/kexec.nix
|
|
{ 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
|
|
set -e
|
|
cd $(mktemp -d)
|
|
pwd
|
|
mkdir initrd
|
|
pushd initrd
|
|
if [ -e /ssh_pubkey ]; then
|
|
cat /ssh_pubkey >> authorized_keys
|
|
fi
|
|
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
|
|
'';
|
|
};
|
|
};
|
|
boot.initrd.postMountCommands = ''
|
|
mkdir -p /mnt-root/root/.ssh/
|
|
cp /authorized_keys /mnt-root/root/.ssh/
|
|
'';
|
|
system.build.kexec_tarball = pkgs.callPackage <nixpkgs/nixos/lib/make-system-tarball.nix> {
|
|
storeContents = [
|
|
{ object = config.system.build.kexec_script; symlink = "/kexec_nixos"; }
|
|
];
|
|
contents = [];
|
|
};
|
|
}
|
|
#+end_src
|
|
|
|
* Testing it :noexport:
|
|
|
|
#+begin_example
|
|
nix-build simple-test.nix -A luks_legacy
|
|
nix-build simple-test.nix -A luks_nvme
|
|
#... etc
|
|
#+end_example
|
|
|
|
#+begin_src nix :tangle ~/arroyo-nix/kexec/simple-test.nix
|
|
let
|
|
pkgs = import <nixpkgs> { config = {}; };
|
|
packages = with pkgs.lib; self: {
|
|
nvme = false;
|
|
uefi = false;
|
|
virtio = true;
|
|
configuration = {};
|
|
configuration1 = {
|
|
imports = [ ./configuration.nix self.configuration ];
|
|
};
|
|
config = (import <nixpkgs/nixos> { configuration = self.configuration1; }).config;
|
|
justdoit = self.config.system.build.justdoit;
|
|
image = self.config.system.build.image;
|
|
interface = if self.nvme then "none" else (if self.virtio then "virtio" else "scsi");
|
|
commonFlags = [
|
|
"-fw_cfg" "opt/com.angeldsis/simple-string,string=foobarbaz"
|
|
"-serial" "mon:stdio"
|
|
"-net" "user,hostfwd=tcp:127.0.0.2:2222-:22" "-net" "nic"
|
|
"-m" "2048"
|
|
"-drive" "index=0,id=drive1,file=dummy_root.qcow2,cache=writeback,werror=report,if=${self.interface}"
|
|
] ++ optional self.nvme "-device nvme,drive=drive1,serial=1234"
|
|
++ optional self.uefi "-drive if=pflash,format=raw,readonly,file=${pkgs.OVMF.fd}/FV/OVMF.fd -drive if=pflash,format=raw,file=my_uefi_vars.bin";
|
|
qemu_test1 = 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
|
|
if ! test -e my_uefi_vars.bin; then
|
|
cp ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd my_uefi_vars.bin
|
|
chmod +w my_uefi_vars.bin
|
|
fi
|
|
qemu-kvm -kernel ${self.image}/kernel -initrd ${self.image}/initrd \
|
|
-append "init=${builtins.unsafeDiscardStringContext self.config.system.build.toplevel}/init ${toString self.config.boot.kernelParams}" \
|
|
${toString self.commonFlags}
|
|
'';
|
|
qemu_test2 = pkgs.writeScriptBin "qemu_test2" ''
|
|
#!${pkgs.stdenv.shell}
|
|
export PATH=${pkgs.qemu_kvm}/bin/:$PATH
|
|
qemu-kvm ${toString self.commonFlags}
|
|
# -chardev stdio,id=qemu-debug-out -device isa-debugcon,chardev=qemu-debug-out
|
|
'';
|
|
# -debugcon file:debug.log -global isa-debugcon.iobase=0x402 \
|
|
qemu_test = pkgs.buildEnv {
|
|
name = "qemu_test";
|
|
paths = with self; [ qemu_test1 qemu_test2 ];
|
|
};
|
|
};
|
|
self = pkgs.lib.makeScope pkgs.newScope packages;
|
|
makeTest = { uefi ? false, nvme ? false, virtio ? false, luks ? false, bootType ? (if uefi then "vfat" else "ext4")}: let
|
|
pkgs2 = with pkgs.lib; self.overrideScope' (self: super: {
|
|
inherit uefi nvme virtio;
|
|
configuration = {
|
|
kexec.justdoit = {
|
|
rootDevice = mkForce (if nvme then "/dev/nvme0n1" else (if virtio then "/dev/vda" else "/dev/sda"));
|
|
nvme = mkForce nvme;
|
|
luksEncrypt = mkForce luks;
|
|
uefi = mkForce uefi;
|
|
inherit bootType;
|
|
};
|
|
};
|
|
});
|
|
in pkgs2.qemu_test // { justdoit = pkgs2.justdoit; };
|
|
in {
|
|
legacy_sata = makeTest {};
|
|
uefi_sata = makeTest { uefi = true; };
|
|
legacy_virtio = makeTest { virtio = true; };
|
|
nvme = makeTest { uefi = true; nvme = true; };
|
|
luks_legacy = makeTest { luks = true; virtio = true; };
|
|
virtio_no_boot = makeTest { virtio = true; bootType = "zfs"; };
|
|
luks_nvme = makeTest { luks = true; uefi = true; nvme = true; };
|
|
}
|
|
#+end_src
|
|
|
|
* Work Stream
|
|
|
|
** DONE get justdoit working
|
|
- State "DONE" from "INPROGRESS" [2021-04-03 Sat 02:20]
|
|
** NEXT include the full installation closure in to the image
|
|
** NEXT [[id:cce/home-manager][home-manager]]-alike for nixos configuration.nix generation (??)
|
|
** DONE basic nixops setup to get the boot configuration stuff parameterized
|
|
|
|
- State "DONE" from "WAITING" [2021-04-05 Mon 02:02]
|
|
- Note taken on [2021-04-02 Fri 21:53] \\
|
|
I'm not sure how dynamic configuration.nix generation will compose with nixops
|
|
- State "WAITING" from "NEXT" [2021-04-02 Fri 21:53]
|
|
** DONE rewrite from kexec to iso installation procedures
|
|
- State "DONE" from "NEXT" [2021-04-05 Mon 02:02]
|
|
** NEXT pull public key out of [[id:cce/ssh_configuration][SSH Configuration]]
|
|
** NEXT document my deviations from the upstream justdoit.nix
|
|
** NEXT bootstrap home-manager on [[id:cce/my_nixos_configuration][My NixOS configuration]]
|
|
** NEXT bootstrap wireguard
|
|
** NEXT bootstrap backup and restore
|
|
|
|
* Footnotes
|
|
|
|
[fn:1] nothing worth complaining about: fedora couldn't kexec the images, fedora couldn't expand the images without doing =TMPDIR=/var/tmp= because tmp is a ramdisk... my mongrel [[id:fedora_linux][Fedora Linux]] plus [[id:cce/home-manager][home-manager]] environment struggled to get virtualization running, and the testing cycle was pretty painful. The [[https://github.com/cleverca22/nix-tests/tree/master/kexec][repository]] I based this around was broken OOTB and even the testing scripts included in it didn't work reliably. The =justdoit= itself took a fair bit of tweaking to get to booting, too. I'll reintegrate kexec some day.
|