Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initrd builder for {scripted,systemd} stage1 nukes references without a warning #309316

Open
Ma27 opened this issue May 5, 2024 · 0 comments
Open

Comments

@Ma27
Copy link
Member

Ma27 commented May 5, 2024

Describe the bug

Since the initrd-builder does a nuke-refs, programs in the initial ramdisk may be missing dependencies needed to function. I'm aware that there are reasons for that (at least closure-size concerns), but nontheless the UX isn't very nice since this happens without a single warning.

Context: on my private laptop I have an erase-your-darlings-like setup where I rename the last tank/system to tank/graveyard/before-YYYY-mm-ddTHH:MM:SS and then create another fresh tank/system. I do this to make sure I can restore files that are actually erased if needed.

This involves a bit of bash-hackery in a systemd unit in stage1:

{
  boot = {
    initrd = {
      systemd = {
        enable = true;
        storePaths = with pkgs; [ "${findutils}/bin/xargs" "${gnugrep}/bin/grep" ];
        services.rollback-rootfs = {
          description = "Rollback of tank/system to a pristine state";
          wantedBy = [ "initrd.target" ];
          after = [ "zfs-import-tank.service" ];
          before = [ "sysroot.mount" ];
          path = with pkgs; [ config.boot.zfs.package coreutils findutils gnugrep ];
          unitConfig.DefaultDependencies = "no";
          serviceConfig.Type = "oneshot";
          script = ''
            set -o pipefail

            echo >&2 "==> Erase your darlings: archiving current / (excluding persistent directories)"
            zfs rename tank/system "tank/graveyard/before-$(date +%Y-%m-%dT%H:%M:%S)"
            echo >&2 "==> Erase your darlings: creating fresh, empty /"
            zfs create tank/system -o mountpoint=legacy
            zfs snapshot tank/system@blank

            num_archived_roots="$(zfs list tank/graveyard -rH | tail -n+2 | wc -l)"
            if [[ "''${num_archived_roots-0}" -gt 5 ]]; then
              echo >&2 "==> Erase your darlings: >5 roots already archived. Cleaning up $((num_archived_roots-5))..."
              zfs list -o name tank/graveyard -rH \
                | grep -E '^tank/graveyard/' \
                | sort -r \
                | tail -n+6 \
                | xargs -I {} zfs destroy -r {}
            fi
          '';
        };
      };
    };
  };
}

On my first try, I forgot to add the storePaths = declaration which created a generation that wasn't bootable.

Steps To Reproduce

see above

Expected behavior

I'm not sure. But a few ideas:

  • check if references are also in storePaths (i.e. if /nix/store/...-coreutilsl/bin/sort is used, it must also be in storePaths).
    • Downsides: more computational effort, false-positives (there should probably be a way to silence that warning), not sure if there are sensible ways to resolve shared libraries (you'd need to check all DT_RUNPATH entries against all SONAMEs, ignoring LD_LIBRARY_PATH & DT_RPATH for now)
  • document this very prominently (I'd argue more or less every option that adds code into the initrd - e.g. the script option of a systemd service should have a warning).

Alternatively, we could also do nothing given that NixOS is very good at doing rollbacks, leaving the UX issue I cited above.

Screenshots

n/a

Additional context

n/a

Notify maintainers

@NixOS/systemd

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
output here

Add a 👍 reaction to issues you find important.

@ElvishJerricco ElvishJerricco added this to To Do in systemd in Stage 1 via automation May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

1 participant