~amjoseph/ownerboot

03dcdd5ea3597899f896f3c68a244b2f2e3d3799 — Adam Joseph 2 months ago 07664e9
src/main: log bootflash updates to /nix/var/nix/profiles/bootflash-*

This commit causes all bootflash update attempts performed by the
`flash-write-*.sh` scripts to be logged as generations in one or
both of these profiles:

  /nix/var/nix/profiles/bootflash-{normal,fallback}

Specifically, the profile acquires a new generation which is set to
the outpath (`$out`) of the derivation containing the script; this
outpath contains a symlink (and therefore a reference) to the
outpath of the bootflash image for which a write was attempted.
This is similar to how each NixOS configuration is logged as a
generation in `/nix/var/nix/profiles/system` when you "switch" to
it.

The generations in these profiles should be interpreted as logs of
*attempts* to write to the bootflash, rather than successful write
completions.  The purpose of these generations is not to indicate
the current state of the bootflash, but rather to prevent the
bootflash image from being garbage collected out of /nix/store
without an explicit `nix profile wipe-history` invocation to clear
these profiles.

If you want to determine precisely how the currently-booted
bootflash was built, you should:

1. Readback the flash image (`flashrom -r`).

2. Use `strings | grep /nix/store` to find the image outpath.  All
   builds after commit ef4f1846871a2d81964fc6ec63e03005786d7815 will
   contain their own outpath in uncompressed, unencrypted form.

   If the image was written using a `flash-write-*.script` built at
   or after this commit, the outpath containing that script will
   have been logged to one or both bootflash-* profiles.  Unless
   `nix profile wipe-history` or equivalent has been used, the
   logged outpath will not be garbage collected.  That outpath
   refers to the image outpath, so it too will also not be garbage
   collected.

3. Use `nix-store -qd` on the image outpath to find its deriver.

   Builds after 07664e909cc663da18e6d405c56ebec6e2aa94c8 cause the
   derivation containing `flash-write-*.script` to include a symlink
   to the deriver of the image outpath (unless explicitly disabled
   with `add-image-deriver-as-dependency = false`).  Therefore the
   outpath logging performed as a result of this commit will ensure
   that not only the bootflash image, *but also its deriver's entire
   derivation tree* will be preserved until explicitly deleted with
   `nix profile wipe-history` or equivalent.
1 files changed, 52 insertions(+), 3 deletions(-)

M src/main/default.nix
M src/main/default.nix => src/main/default.nix +52 -3
@@ 27,6 27,56 @@ let
        preferLocalBuild = true;
      });

  linkScripts = lib.pipe scripts [
    (lib.mapAttrsToList
      (scriptName: scriptText:
        let
          # Before attempting to write to the bootflash, we first
          # log this derivation's outpath (`$out`) to one or both of
          # these two profiles:
          #
          #   /nix/var/nix/profiles/bootflash-{normal,fallback}
          #
          # The generations in these profiles should be interpreted
          # as logs of *attempts* to write to the bootflash, rather
          # than successful write completions.  The purpose of these
          # generations is not to indicate the current state of the
          # bootflash, but rather to prevent the bootflash image
          # from being garbage collected out of /nix/store without
          # an explicit `nix profile wipe-history` invocation to
          # clear these profiles.
          #
          # If you want to determine precisely how the
          # currently-booted bootflash was built, you should:
          #
          # 1. Readback the flash image (`flashrom -r`)
          #
          # 2. Use `strings | grep /nix/store` to find the outpath
          #    of the derivation that built the image.
          #
          # 3. Use `nix-store -qd` on that outpath to find the
          #    derivation that built it.
          #
          prependToScript = {
            flash-write-fallback = ''
              nix-env -p /nix/var/nix/profiles/bootflash-fallback --set "${builtins.placeholder "out"}" || exit -1
            '';
            flash-write-normal = ''
              nix-env -p /nix/var/nix/profiles/bootflash-normal --set "${builtins.placeholder "out"}" || exit -1
            '';
            flash-write-all = ''
              nix-env -p /nix/var/nix/profiles/bootflash-fallback --set "${builtins.placeholder "out"}" || exit -1
              nix-env -p /nix/var/nix/profiles/bootflash-normal --set "${builtins.placeholder "out"}" || exit -1
            '';
          }.${scriptName} or "";
          shellScriptPath = writeShellScript scriptName (prependToScript + scriptText);
        in ''
          ln -s ${shellScriptPath} $out/bin/${scriptName}.sh
        ''
      ))
    lib.concatStrings
  ];

in nixpkgsOnBuildForHost.stdenv.mkDerivation (finalAttrs: {
  name = "ownerboot";
  dontUnpack = true;


@@ 42,10 92,9 @@ in nixpkgsOnBuildForHost.stdenv.mkDerivation (finalAttrs: {
  '' + lib.optionalString add-image-deriver-as-dependency ''
    ln -s ${builtins.storePath (builtins.unsafeDiscardStringContext image.drvPath)} $out/etc/image.drv

  '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (scriptName: scriptText: ''
    ln -s ${writeShellScript scriptName scriptText} $out/bin/${scriptName}.sh
  '' + ''
    ${linkScripts}

  '') scripts)) + ''
    runHook postInstall
  '';
})