UP | HOME

BootstrapNixOS

After running through the steps to get nixos-rebuild build-vm working, I realized there's some work that needs to be done to bootstrap NixOS.

  1. Copy over SSH keys.
  2. Run bootstrap.sh
  3. Run the bootstrap.lisp program below.
  4. emacs will complain if Brass Mono isn't installed.
  5. Really, a lot of this will go away if you restore your home directory.

bootstrap.sh

[[ ! -d $HOME/.emacs.d ]] && \
    git clone git@git.wntrmute.dev:kyle/emacsd .emacs.d
[[ ! -d $HOME/org ]] && \
    git clone git@git.wntrmute.dev:kyle/org-files org
[[ ! -d $HOME/quicklisp ]] && \
    curl -LO https://beta.quicklisp.org/quicklisp.lisp
[[ ! -d $HOME/.stumpwm.d/modules ]] && \
    cd .stumpwm.d && \
    git clone https://github.com/stumpwm/stumpwm-contrib modules

bootstrap.lisp

(quicklisp-quickstart:install)
(ql:add-to-init-file)
(ql:quickload :quicklisp-slime-helper)
(ql:quickload :clx)
(ql:quickload :xembed)
(ql:quickload :cl-ppcre)
(ql:quickload :alexandria)

Questions

Backup system

Can I unpack a tarball / rsync onto a qcow2 image? Might be a useful way to build a backup image.

It maybe isn't, because it relies on kernel versions stored in the nix tree. Anyways, it was a fun experiment, and at least lets you test new changes on a "live" system.

#!/bin/sh

set -eu

build_dir="${build_dir:-/tmp/nixos-vm}"
mount_point="${mount_point:-/tmp/fs}"
qcow2="${qcow2:-${build_dir}/$(hostname -s).qcow2}"

echo "[+] configuration:"
echo "    build dir:    ${build_dir}"
echo "  mount point:    ${mount_point}"
echo "        image:    ${qcow2}"

build_nixos_vm () {
    echo "[+] updating NixOS config"
    cd /etc/nixos
    doas git pull --rebase local master

    if [[ -d "${build_dir}" ]]
    then
        echo "[+] removing ${build_dir}"
        sleep 2
        rm -r "${build_dir}"
    fi

    mkdir "${build_dir}"
    cd "${build_dir}"
    nixos-rebuild build-vm

    echo "[+] Spinning up VM; kill it when you see the line"
    echo "      'Virtualisation disk image created.'"
    "${build_dir}/result/bin/run-$(hostname -s)-vm"
    doas qemu-img resize "${qcow2}" 256G

    doas modprobe nbd max_part=8

    echo "[+] connecting to network block driver"
    echo "    note: on failure, you may need to manually run"
    echo "    doas qemu-nbd --disconnect /dev/nbd0"
    doas qemu-nbd --connect=/dev/nbd0 ${qcow2}

    if [[ -d "${mount_point}" ]]
    then
        echo "[+] removing ${mount_point}"
        sleep 2
        rm -r "${mount_point}"
    fi

    mkdir -p "${mount_point}"
    doas mount /dev/nbd0 "${mount_point}"

    rsync --progress -auvz "${HOME}/" "${mount_point}/home/kyle/"

    echo "[+] finished, cleaning up"
    doas umount "${mount_point}"
    doas qemu-nbd --disconnect /dev/nbd0
    doas rmdir "${mount_point}"
    doas rm -r "${build_dir}"
}

cleanup () {
    if [[ -d "${build_dir}" ]]
    then
        echo "[+] removing ${build_dir}"
        sleep 2
        rm -r "${build_dir}"
    fi

    if [[ ! -z "$(mount | grep /dev/nbd0)" ]]
    then
        echo "[+] unmounting network block device"
        doas umount /dev/nbd0
    fi

    echo "[+] disconnecting network block device"
    echo "    it's okay if this fails"
    doas qemu-nbd --disconnect /dev/nbd0

    if [[ -d "${mount_point}" ]]
    then
        echo "[+] removing ${mount_point}"
        sleep 2
        rm -r "${mount_point}"
    fi
}

case "${1:-build}" in
    build)
        build_nixos_vm
        ;;
    cleanup)
        cleanup
        ;;
    *)
        echo "[!] Valid commands are build, cleanup"
        exit 1
        ;;
esac