From 5ba14fd915b1ce00957c9cbf47fd168384130373 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 23 Nov 2023 20:02:21 +0000 Subject: [PATCH] add levitate package sets up a chroot system in tmpfs that will be executed on the next reboot to enable system maintenance without the regular filesystems mounted --- pkgs/default.nix | 2 ++ pkgs/levitate/default.nix | 75 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 pkgs/levitate/default.nix diff --git a/pkgs/default.nix b/pkgs/default.nix index 13cd494..2495a15 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -102,4 +102,6 @@ in { fennel = callPackage ./fennel {}; fennelrepl = callPackage ./fennelrepl {}; anoia = callPackage ./anoia {}; + + levitate = callPackage ./levitate {}; } diff --git a/pkgs/levitate/default.nix b/pkgs/levitate/default.nix new file mode 100644 index 0000000..207f8ea --- /dev/null +++ b/pkgs/levitate/default.nix @@ -0,0 +1,75 @@ +{ + writeScriptBin +, writeScript +, systemconfig +, execline +, lib +, services ? null +, liminix +, pseudofile +, pkgs +} : +let + inherit (pseudofile) dir symlink; + inherit (liminix.services) oneshot; + newRoot = "/run/maintenance"; + sysconfig = + let + doChroot = writeScript "exec" '' + #!${execline}/bin/execlineb -P + cd ${newRoot} + foreground { mount --move ${newRoot} / } + redirfd -r 0 /dev/console + redirfd -w 1 /dev/console + fdmove -c 2 1 + emptyenv chroot . /bin/init + ''; + base = {...} : { + config = { + services = services // { + banner = oneshot { + name = "banner"; + up = "cat /etc/banner > /dev/console"; + down = "true"; + }; + }; + + filesystem = dir { + exec = symlink doChroot; + etc = dir { + banner = symlink (pkgs.writeText "banner" '' + + LADIES AND GENTLEMEN WE ARE FLOATING IN SPACE + + Most services are disabled. The system is operating + with a ram-based root filesystem, making it safe to + overwrite the flash devices in order to perform + upgrades and maintenance. + + Don't forget to reboot when you have finished. + + ''); + }; + }; + }; + }; + eval = lib.evalModules { + modules = [ + { _module.args = { inherit pkgs; inherit (pkgs) lim; }; } + ../../modules/base.nix + ../../modules/users.nix + ../../modules/busybox.nix + base + ../../modules/s6 + ]; + }; + in systemconfig eval.config.filesystem.contents; +in writeScriptBin "levitate" '' + #!/bin/sh + destdir=${newRoot} + mkdir -p $destdir $destdir/nix/store + for path in $(cat ${sysconfig}/etc/nix-store-paths) ; do + (cd $destdir && cp -a $path .$path) + done + ${sysconfig}/bin/activate $destdir +''