1
0
forked from dan/liminix

add a new updater output

this is so that we don't have to obfuscate store paths in
systemConfiguration to avoid dragging in build system
deps.

breaking-ish change to workflows, docs updated
This commit is contained in:
Daniel Barlow 2024-12-20 00:05:07 +00:00
parent 812e35b7b9
commit f60b74f415
7 changed files with 86 additions and 51 deletions

10
NEWS
View File

@ -142,3 +142,13 @@ hardware.dts.includePaths.
The "new" hardware.dts.includes option is now for dtsi files which
should be merged into the device tree.
2024-12-19
Incremental updates changed again (but not massively). From hereon in,
the preferred way to do an incremental update on an installed device
with a writable filesystem is to build the updater output
nix-build -I liminix-config=hosts/myhost.nix --argstr deviceName turris-omnia -A outputs.updater
and then run the generated `update.sh` script. See
https://www.liminix.org/doc/admin.html#updating-an-installed-system

View File

@ -172,8 +172,6 @@
../../modules/arch/arm.nix
../../modules/outputs/tftpboot.nix
../../modules/outputs/mbrimage.nix
../../modules/outputs/extlinux.nix
../../modules/outputs/system-configuration.nix
];
config = {
@ -337,7 +335,7 @@
targets = ["ath9k" "ath10k_pci"];
};
in {
defaultOutput = "systemConfiguration";
defaultOutput = "updater";
loadAddress = lim.parseInt "0x00800000"; # "0x00008000";
entryPoint = lim.parseInt "0x00800000"; # "0x00008000";
rootDevice = "/dev/mmcblk0p1";

View File

@ -159,48 +159,26 @@ you need to mooun the pstore filesystem.
Updating an installed system (JFFS2)
************************************
Updating an installed system
****************************
If your system has a writable root filesystem (JFFS2, btrfs etc -
anything but squashfs), we have mechanisms for in-places updates
analogous to :command:`nixos-rebuild`, but the operation is a bit
different because it expects to run on a build machine and then copy
to the host device using :command:`ssh`.
Adding packages
===============
If your device is running a JFFS2 root filesystem, you can build
extra packages for it on your build system and copy them to the
device: any package in Nixpkgs or in the Liminix overlay is available
with the ``pkgs`` prefix:
.. code-block:: console
nix-build -I liminix-config=./my-configuration.nix \
--arg device "import ./devices/mydevice" -A pkgs.tcpdump
nix-shell -p min-copy-closure root@the-device result/
Note that this only copies the package to the device: it doesn't update
any profile to add it to ``$PATH``
.. _rebuilding the system:
Rebuilding the system
=====================
Liminix has a mechanism for in-place updates of a running system which
is analogous to :command:`nixos-rebuild`, but its operation is a
bit different because it expects to run on a build machine and then
copy to the host device. To use this, build the `outputs.systemConfiguration`
target and then run the :command:`result/install.sh` script it generates.
To use this, build the ``outputs.updater``
target and then run the :command:`update.sh` script it generates.
.. code-block:: console
nix-build -I liminix-config=./my-configuration.nix \
--arg device "import ./devices/mydevice" \
-A outputs.systemConfiguration
./result/install.sh root@the-device
-A outputs.updater
./result/bin/update.sh root@the-device
The install script uses min-copy-closure to copy new or changed
The update script uses min-copy-closure to copy new or changed
packages to the device, then (perhaps) reboots it. The reboot
behaviour can be affected by flags:
@ -213,7 +191,6 @@ behaviour can be affected by flags:
the services that have updated store paths (and anything that
depends on them), but will not affect services that haven't changed.
It doesn't delete old packages automatically: to do that run
:command:`min-collect-garbage`, which will delete any packages not in
the current system closure. Note that Liminix does not have the NixOS
@ -233,6 +210,26 @@ Caveats
.. _levitate:
Adding packages
===============
If you simply wish to add a package without any change to services,
you can call :command:`min-copy-closure` directly to install
any package in Nixpkgs or in the Liminix overlay
.. code-block:: console
nix-build -I liminix-config=./my-configuration.nix \
--arg device "import ./devices/mydevice" -A pkgs.tcpdump
nix-shell -p min-copy-closure root@the-device result/
Note that this only copies the package and its dependencies to the
device: it doesn't update any profile to add it to ``$PATH``
.. _rebuilding the system:
Reinstalling on a running system
********************************

View File

@ -14,6 +14,7 @@ in
./outputs/squashfs.nix
./outputs/vmroot.nix
./outputs/extlinux.nix
./outputs/updater
];
options = {
system.outputs = {

View File

@ -0,0 +1,36 @@
{
config
, pkgs
, lib
, ...
}:
let
inherit (lib) mkIf;
o = config.system.outputs;
inherit (pkgs) runCommand;
inherit (lib) mkOption types;
inherit (pkgs.buildPackages) min-copy-closure;
in
{
imports = [ ../system-configuration.nix ];
options.system.outputs.updater = mkOption {
type = types.package;
description = ''
updater
******
For configurations with a writable filesystem, create a shell
script that runs on the build system and updates the device
over the network to the new configuration
'';
};
config.system.outputs.updater =
runCommand "buildUpdater" { } ''
mkdir -p $out/bin
substitute ${./update.sh} $out/bin/update.sh \
--subst-var-by toplevel ${o.systemConfiguration} \
--subst-var-by min_copy_closure ${min-copy-closure}
chmod +x $out/bin/update.sh
'';
}

View File

@ -1,22 +1,19 @@
#!/usr/bin/env bash
# this shell script can be run on the build system to
# min-copy-closure the system configuration onto the device
# and reboot/restart services as requested
# this shell script is run on the build system to min-copy-closure the
# system configuration onto the device and reboot/restart services as
# requested
die() {
echo "$@"
exit 1
}
# add min-copy-closure to the path. removing junk characters
# inserted by default.nix (q.v.)
min_copy_closure=@min-copy-closure@; PATH=${min_copy_closure//_/}/bin:$PATH
PATH=@min_copy_closure@/bin:$PATH
ssh_command=${SSH_COMMAND-ssh}
reboot="reboot"
case "$1" in
"--no-reboot")
unset reboot
@ -34,10 +31,11 @@ shift
test -n "$target_host" || \
die "Usage: $0 [--no-reboot] [--fast] target-host"
toplevel=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && readlink `pwd` )
toplevel=$(realpath @toplevel@)
test -e $toplevel/etc/nix-store-paths || die "missing etc/nix-store-paths, is this really a system configuration?"
echo installing from systemConfiguration $toplevel to host $target_host
$ssh_command $target_host uname -a || die "Can't ssh to $target_host"
min-copy-closure $target_host $toplevel
set -x
$ssh_command $target_host $toplevel/bin/install

View File

@ -83,11 +83,6 @@ in attrset:
$STRIP --remove-section=.note --remove-section=.comment --strip-all activate -o $out/bin/activate
ln -s ${s6-init-bin}/bin/init $out/bin/init
cp -p ${writeFennel "restart-services" {} ./restart-services.fnl} $out/bin/restart-services
# obfuscate the store path of min-copy-closure so that the output
# closure doesn't include a bunch of build system stuff
f=${buildPackages.min-copy-closure}; f=$(echo $f | sed 's/\(.....\)/\1_/g')
substitute ${./build-system-install.sh} $out/install.sh --subst-var-by min-copy-closure $f
chmod +x $out/install.sh
cat > $out/bin/install <<EOF
#!/bin/sh -e
prefix=\''${1-/}