feat(nixos): prune system+HM gens after 14d, keep ≥3 past (#128)
Some checks failed
Check / eval (push) Has been cancelled
Some checks failed
Check / eval (push) Has been cancelled
Weekly nomarchy-gen-prune deletes only generations that are both older than 14 days and beyond the three most recent past gens (current always kept), for system and Home Manager profiles. Stock nix.gc no longer uses --delete-older-than. checks.gen-prune covers selection self-test and unit wiring; doctor points at the new tool when disk is tight.
This commit is contained in:
@@ -78,44 +78,6 @@ cable leaves. Capture steps in HARDWARE-QUEUE.
|
||||
|
||||
## NEXT
|
||||
|
||||
### 128. Auto-prune system + HM generations: >14 days, but keep ≥3 past
|
||||
|
||||
Bernardo 2026-07-15 (refined same day): automatic cleanup of **both**
|
||||
NixOS (system) and Home Manager (per-user) generations so boot menu,
|
||||
desktop rollback, and store do not grow without bound, with a safety floor:
|
||||
|
||||
1. **Age:** candidates older than **14 days** may be removed.
|
||||
2. **Count floor:** always keep the **current** generation and at least
|
||||
**3 past** generations — even if those three are older than 14 days.
|
||||
3. Combined: delete only gens that are **both** older than 14 days **and**
|
||||
older than the third-most-recent past generation. Gens within 14 days
|
||||
stay regardless of how many there are (until they age out).
|
||||
4. **Apply the same rule independently** to the system profile and to each
|
||||
user's Home Manager profile (desktop rollback in Recovery › Desktop).
|
||||
|
||||
**Why this shape:** pure age GC (`--delete-older-than`) can wipe a machine
|
||||
that is rarely rebuilt down to one generation and remove useful rollback
|
||||
targets; pure count limits (`configurationLimit`) drop recent work just
|
||||
because the user iterates a lot. Age + floor keeps travel-laptop machines
|
||||
safe and busy desktops tidy. 14d matches the existing store GC cadence
|
||||
rather than a longer 30d hold.
|
||||
|
||||
**Today:** `nix.gc` is already weekly with `--delete-older-than 14d`
|
||||
(`modules/nixos/default.nix`) — store GC, **no** min-generation floor, and
|
||||
it is not framed as an explicit dual system+HM policy. This item should
|
||||
replace/refine that (or add a dedicated pruner if stock GC cannot express
|
||||
the floor on both profiles). Bootloader list
|
||||
(`boot.loader.systemd-boot.configurationLimit`) may need to stay in sync
|
||||
so removed system profiles do not leave dead boot entries.
|
||||
|
||||
Pass = weekly (or post-rebuild) cleanup enforces 14d + keep ≥3 past on
|
||||
**system and HM** generations; a machine with only old gens never goes
|
||||
below current+3 on either profile; docs/RECOVERY still matches boot-menu
|
||||
and desktop rollback; doctor or a check asserts the timer/unit exists and
|
||||
the prune script's dry-run logic. V3: box with many gens — boot menu +
|
||||
`nix-env -p /nix/var/nix/profiles/system --list-generations` +
|
||||
`home-manager generations` after a prune.
|
||||
|
||||
### 120. A netinstall ISO, next to the fat offline one
|
||||
|
||||
Bernardo 2026-07-14, after seeing the measured size: **keep the current ISO
|
||||
|
||||
@@ -19,6 +19,17 @@ Template:
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-15 — #128 generation prune (14d + keep ≥3 past, system+HM)
|
||||
- **Task:** Implement auto-prune for system and Home Manager generations.
|
||||
- **Did:** `pkgs/nomarchy-gen-prune` + `modules/nixos/gen-prune.nix` weekly
|
||||
timer; pure select (current + 3 past always; else drop if age>14d); store
|
||||
GC without `--delete-older-than`; bootloader refresh after system prune.
|
||||
Doctor fix + RECOVERY note. Closed #128.
|
||||
- **Verified:** V0/V1 — `checks.gen-prune` (self-test + dry-run + timer
|
||||
assert + no age-only gc options). V3: run on a multi-gen box.
|
||||
- **Pending:** V3 on real machine with many gens.
|
||||
- **Next suggestion:** human #115/#120, or hardware queue.
|
||||
|
||||
## 2026-07-15 — File #128 generation auto-prune policy (no code)
|
||||
- **Task:** Bernardo: auto-clean gens older than N days but always keep
|
||||
≥3 past; include HM; prefer 14d over 30d.
|
||||
|
||||
@@ -65,6 +65,11 @@ broken one. Make the fix stick from the working boot: revert the change
|
||||
in `~/.nomarchy` (`git -C ~/.nomarchy revert …` or edit `system.nix`
|
||||
back), then `nomarchy-rebuild`.
|
||||
|
||||
**Automatic prune (#128):** a weekly timer (`nomarchy-gen-prune`) removes
|
||||
system *and* Home Manager generations that are **older than 14 days** and
|
||||
**beyond the three most recent past gens** (current + ≥3 past always kept).
|
||||
Manual: `sudo nomarchy-gen-prune` (or `--dry-run`).
|
||||
|
||||
## 4. Files went missing or wrong — snapshots (BTRFS installs)
|
||||
|
||||
With `nomarchy.system.snapper.enable` (the installer's default on
|
||||
|
||||
@@ -427,6 +427,11 @@ Design/decision records and a running log of shipped work (items marked
|
||||
default `$TERMINAL` / SUPER+Return, doctor + calendar + what-changed use
|
||||
`kitty --class=com.nomarchy.*`. Ghostty module and install-time GL probe
|
||||
removed. V3: Acer SUPER+Return + doctor float.
|
||||
- ✓ **Generation prune (#128):** weekly `nomarchy-gen-prune` (system + HM):
|
||||
delete only gens older than **14 days** that are also beyond the **3 most
|
||||
recent past** gens (current always kept). Stock `nix.gc` no longer uses
|
||||
`--delete-older-than` (floor-free). `checks.gen-prune` self-test + unit
|
||||
wiring. Manual: `sudo nomarchy-gen-prune` / `--dry-run`.
|
||||
- ✓ **Recovery + System IA + Control Center retired (#111 / #105 / #110):**
|
||||
System menu is Connectivity / Devices / Recovery / Preferences (root still
|
||||
six entries). Recovery is scope-first: Desktop generation (HM), System boot
|
||||
|
||||
31
flake.nix
31
flake.nix
@@ -90,6 +90,7 @@
|
||||
nomarchy-what-changed = final.callPackage ./pkgs/nomarchy-what-changed { };
|
||||
nomarchy-detect-hw = final.callPackage ./pkgs/nomarchy-detect-hw { };
|
||||
nomarchy-airplane = final.callPackage ./pkgs/nomarchy-airplane { };
|
||||
nomarchy-gen-prune = final.callPackage ./pkgs/nomarchy-gen-prune { };
|
||||
# pull / rebuild / home (+ legacy aliases) — also on HM so a home
|
||||
# switch can refresh a broken system-package nomarchy-pull.
|
||||
# Includes nomarchy-what-changed (generation readability, #82).
|
||||
@@ -604,6 +605,36 @@
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# Generation prune (#128): pure selection self-test (14d + keep ≥3
|
||||
# past) baked into the script; assert timer+service on the distro.
|
||||
gen-prune =
|
||||
let
|
||||
node = self.nixosConfigurations.nomarchy;
|
||||
timerWanted =
|
||||
builtins.elem "timers.target"
|
||||
(node.config.systemd.timers.nomarchy-gen-prune.wantedBy or [ ]);
|
||||
execStart =
|
||||
node.config.systemd.services.nomarchy-gen-prune.serviceConfig.ExecStart or "";
|
||||
gcOpts = node.config.nix.gc.options or "";
|
||||
noAgeWipe =
|
||||
gcOpts == ""
|
||||
|| !(nixpkgs.lib.hasInfix "delete-older-than" gcOpts);
|
||||
in
|
||||
assert nixpkgs.lib.assertMsg timerWanted
|
||||
"gen-prune: timer not wanted by timers.target";
|
||||
assert nixpkgs.lib.assertMsg (execStart != "")
|
||||
"gen-prune: service ExecStart empty";
|
||||
assert nixpkgs.lib.assertMsg noAgeWipe
|
||||
"gen-prune: nix.gc.options must not use --delete-older-than (got: ${gcOpts})";
|
||||
pkgs.runCommand "nomarchy-gen-prune"
|
||||
{ nativeBuildInputs = [ pkgs.bash ]; }
|
||||
''
|
||||
set -eu
|
||||
${pkgs.nomarchy-gen-prune}/bin/nomarchy-gen-prune --self-test
|
||||
${pkgs.nomarchy-gen-prune}/bin/nomarchy-gen-prune --dry-run >/dev/null
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# Installer keyboard no-variant regression (item 91): gum's `(none)`
|
||||
# row is display-only. Exercise it through the real template
|
||||
# patcher, then build the exact us + empty-variant console keymap
|
||||
|
||||
@@ -35,7 +35,11 @@ let
|
||||
in if builtins.isBool v then v else null;
|
||||
in
|
||||
{
|
||||
imports = [ ./options.nix ./plymouth.nix ./greeter.nix ./file-manager.nix ./power.nix ./services.nix ./hardware.nix ./timezone.nix ./oom.nix ];
|
||||
imports = [
|
||||
./options.nix ./plymouth.nix ./greeter.nix ./file-manager.nix
|
||||
./power.nix ./services.nix ./hardware.nix ./timezone.nix ./oom.nix
|
||||
./gen-prune.nix # #128 system+HM generation prune (14d, keep ≥3 past)
|
||||
];
|
||||
|
||||
config = {
|
||||
# Distro branding. distroName flows into /etc/os-release PRETTY_NAME,
|
||||
@@ -512,11 +516,8 @@ in
|
||||
# dirty" warning fires on every rebuild and is pure noise here.
|
||||
warn-dirty = lib.mkDefault false;
|
||||
};
|
||||
gc = {
|
||||
automatic = lib.mkDefault true;
|
||||
dates = lib.mkDefault "weekly";
|
||||
options = lib.mkDefault "--delete-older-than 14d";
|
||||
};
|
||||
# Generation age+floor policy + store GC: modules/nixos/gen-prune.nix (#128).
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
41
modules/nixos/gen-prune.nix
Normal file
41
modules/nixos/gen-prune.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
# #128 — weekly generation prune: system + Home Manager profiles.
|
||||
# Policy: drop gens older than 14 days only when they are beyond the
|
||||
# three most recent *past* generations (current always kept).
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
environment.systemPackages = [ pkgs.nomarchy-gen-prune ];
|
||||
|
||||
# Stock nix.gc --delete-older-than has no keep-N floor and would fight
|
||||
# this policy. Keep weekly store GC for dead paths only; generation
|
||||
# selection is nomarchy-gen-prune's job.
|
||||
nix.gc = {
|
||||
automatic = lib.mkDefault true;
|
||||
dates = lib.mkDefault "weekly";
|
||||
# Empty options → collect unreferenced store paths only (no age-based
|
||||
# profile generation wipe).
|
||||
options = lib.mkDefault "";
|
||||
};
|
||||
|
||||
systemd.services.nomarchy-gen-prune = {
|
||||
description = "Prune old NixOS and Home Manager generations (14d, keep ≥3 past)";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.nomarchy-gen-prune}/bin/nomarchy-gen-prune";
|
||||
};
|
||||
# After the stock store GC timer if both fire weekly.
|
||||
after = [ "nix-gc.service" ];
|
||||
};
|
||||
|
||||
systemd.timers.nomarchy-gen-prune = {
|
||||
description = "Weekly Nix generation prune (Nomarchy #128)";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "weekly";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "1h";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -60,7 +60,7 @@ for mp in / /boot /nix; do
|
||||
avail=$(numfmt --to=iec $((availkb * 1024)))
|
||||
if [ "$use" -ge 90 ]; then
|
||||
bad "$mp is ${use}% full (${avail} free)" \
|
||||
"sudo nix-collect-garbage --delete-older-than 14d (then sys-rebuild to prune old boot entries)"
|
||||
"sudo nomarchy-gen-prune (14d + keep ≥3 past system/HM gens; then reclaims store)"
|
||||
else
|
||||
ok "$mp has space (${use}% used, ${avail} free)"
|
||||
fi
|
||||
@@ -127,6 +127,21 @@ else
|
||||
skip "system generation age (no system profile)"
|
||||
fi
|
||||
|
||||
# ── generation prune (#128: 14d + keep ≥3 past, system + HM) ─────────
|
||||
if [ -n "$(systemctl list-unit-files nomarchy-gen-prune.timer --no-legend --plain 2>/dev/null)" ]; then
|
||||
if systemctl is-enabled --quiet nomarchy-gen-prune.timer 2>/dev/null; then
|
||||
ok "generation prune timer is enabled (14d, keep ≥3 past)"
|
||||
else
|
||||
bad "nomarchy-gen-prune.timer is installed but not enabled" \
|
||||
"systemctl enable --now nomarchy-gen-prune.timer"
|
||||
fi
|
||||
elif command -v nomarchy-gen-prune >/dev/null 2>&1; then
|
||||
warn "nomarchy-gen-prune is on PATH but no timer unit" \
|
||||
"rebuild the system so gen-prune.nix ships the weekly timer"
|
||||
else
|
||||
skip "generation prune (package not on this machine)"
|
||||
fi
|
||||
|
||||
# ── snapper timeline (when enabled) ──────────────────────────────────
|
||||
if [ -n "$(systemctl list-unit-files snapper-timeline.timer --no-legend --plain 2>/dev/null)" ]; then
|
||||
if systemctl is-active --quiet snapper-timeline.timer; then
|
||||
|
||||
228
pkgs/nomarchy-gen-prune/default.nix
Normal file
228
pkgs/nomarchy-gen-prune/default.nix
Normal file
@@ -0,0 +1,228 @@
|
||||
{ lib
|
||||
, writeShellScriptBin
|
||||
, coreutils
|
||||
, gnugrep
|
||||
, gawk
|
||||
, nix
|
||||
, findutils
|
||||
}:
|
||||
|
||||
# #128 — prune system + Home Manager generations:
|
||||
# drop only if older than 14 days AND beyond the 3 most recent *past*
|
||||
# gens (current + ≥3 past always kept). Store reclaim is a plain
|
||||
# nix-collect-garbage after (no --delete-older-than — that would ignore
|
||||
# the floor).
|
||||
writeShellScriptBin "nomarchy-gen-prune" ''
|
||||
set -euo pipefail
|
||||
PATH=${lib.makeBinPath [ coreutils gnugrep gawk nix findutils ]}:$PATH
|
||||
|
||||
MAX_AGE_DAYS=''${NOMARCHY_GEN_PRUNE_MAX_AGE_DAYS:-14}
|
||||
KEEP_PAST=''${NOMARCHY_GEN_PRUNE_KEEP_PAST:-3}
|
||||
DRY=0
|
||||
SELFTEST=0
|
||||
|
||||
usage() {
|
||||
echo "usage: nomarchy-gen-prune [--dry-run] [--self-test]" >&2
|
||||
echo " Prune NixOS system + Home Manager profile generations:" >&2
|
||||
echo " delete only if older than ''${MAX_AGE_DAYS}d and beyond the" >&2
|
||||
echo " ''${KEEP_PAST} most recent past gens (current always kept)." >&2
|
||||
exit 64
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY=1 ;;
|
||||
--self-test) SELFTEST=1 ;;
|
||||
-h|--help) usage ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() { echo "nomarchy-gen-prune: $*" >&2; }
|
||||
|
||||
# Pure selection: stdin lines "NUM EPOCH [current]"
|
||||
# stdout: generation numbers to delete (one per line).
|
||||
# Always protect current + up to KEEP_PAST gens with number < current
|
||||
# (highest first). Others delete only if EPOCH < now - MAX_AGE_DAYS.
|
||||
select_deletions() {
|
||||
local now keep_past max_age
|
||||
now=$(date +%s)
|
||||
keep_past=$KEEP_PAST
|
||||
max_age=$MAX_AGE_DAYS
|
||||
awk -v now="$now" -v keep_past="$keep_past" -v max_age="$max_age" '
|
||||
NF < 2 { next }
|
||||
{
|
||||
num = $1 + 0
|
||||
ts = $2 + 0
|
||||
cur = (NF >= 3 && $3 == "current")
|
||||
nums[n] = num; tss[num] = ts; if (cur) current = num; n++
|
||||
}
|
||||
END {
|
||||
if (n == 0) exit 0
|
||||
if (current == 0) {
|
||||
# No marker: treat highest generation number as current.
|
||||
current = nums[0]
|
||||
for (i = 1; i < n; i++) if (nums[i] > current) current = nums[i]
|
||||
}
|
||||
# Past gens: number < current, sort desc.
|
||||
pn = 0
|
||||
for (i = 0; i < n; i++) {
|
||||
if (nums[i] < current) { past[pn++] = nums[i] }
|
||||
}
|
||||
# bubble-sort past desc (small n)
|
||||
for (i = 0; i < pn; i++)
|
||||
for (j = i + 1; j < pn; j++)
|
||||
if (past[j] > past[i]) { t = past[i]; past[i] = past[j]; past[j] = t }
|
||||
protect[current] = 1
|
||||
for (i = 0; i < pn && i < keep_past; i++) protect[past[i]] = 1
|
||||
cutoff = now - (max_age * 86400)
|
||||
for (i = 0; i < n; i++) {
|
||||
g = nums[i]
|
||||
if (protect[g]) continue
|
||||
if (tss[g] < cutoff) print g
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
if [ "$SELFTEST" = 1 ]; then
|
||||
# Fixture: now-fixed via epoch math in the data itself.
|
||||
# current=10; past 9,8,7 protected; 6 is >14d old → delete; 5 is young → keep.
|
||||
export KEEP_PAST=3 MAX_AGE_DAYS=14
|
||||
now=$(date +%s)
|
||||
old=$((now - 20 * 86400))
|
||||
young=$((now - 2 * 86400))
|
||||
got=$(printf '%s\n' \
|
||||
"10 $young current" \
|
||||
"9 $old" \
|
||||
"8 $old" \
|
||||
"7 $old" \
|
||||
"6 $old" \
|
||||
"5 $young" \
|
||||
| select_deletions)
|
||||
echo "$got" | grep -qx 6 || { echo "self-test: expected only 6, got: [$got]" >&2; exit 1; }
|
||||
# Rarely rebuilt: only old gens → delete none below floor (keep 10+9+8+7)
|
||||
got=$(printf '%s\n' \
|
||||
"10 $old current" \
|
||||
"9 $old" \
|
||||
"8 $old" \
|
||||
"7 $old" \
|
||||
"6 $old" \
|
||||
| select_deletions)
|
||||
echo "$got" | grep -qx 6 || { echo "self-test: floor failed, got: [$got]" >&2; exit 1; }
|
||||
# Only 3 gens total, all old → delete nothing
|
||||
got=$(printf '%s\n' \
|
||||
"3 $old current" \
|
||||
"2 $old" \
|
||||
"1 $old" \
|
||||
| select_deletions)
|
||||
[ -z "$got" ] || { echo "self-test: expected empty, got: [$got]" >&2; exit 1; }
|
||||
log "self-test ok"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Enumerate "NUM EPOCH [current]" for a profile symlink base.
|
||||
# profile is the live link, e.g. /nix/var/nix/profiles/system
|
||||
list_gens() {
|
||||
local profile=$1
|
||||
local dir base cur_base cur_num name num ts
|
||||
[ -e "$profile" ] || [ -L "$profile" ] || return 0
|
||||
dir=$(dirname -- "$profile")
|
||||
base=$(basename -- "$profile")
|
||||
cur_base=$(basename -- "$(readlink "$profile" 2>/dev/null || true)")
|
||||
cur_num=
|
||||
case "$cur_base" in
|
||||
"$base"-*-link)
|
||||
cur_num=''${cur_base#"$base"-}
|
||||
cur_num=''${cur_num%-link}
|
||||
;;
|
||||
esac
|
||||
# shellcheck disable=SC2035
|
||||
for link in "$dir"/"$base"-*-link; do
|
||||
[ -e "$link" ] || [ -L "$link" ] || continue
|
||||
name=$(basename -- "$link")
|
||||
case "$name" in
|
||||
"$base"-*-link) ;;
|
||||
*) continue ;;
|
||||
esac
|
||||
num=''${name#"$base"-}
|
||||
num=''${num%-link}
|
||||
case "$num" in *[!0-9]*|"") continue ;; esac
|
||||
ts=$(stat -c %Y -- "$link" 2>/dev/null || echo 0)
|
||||
if [ -n "$cur_num" ] && [ "$num" = "$cur_num" ]; then
|
||||
printf '%s %s current\n' "$num" "$ts"
|
||||
else
|
||||
printf '%s %s\n' "$num" "$ts"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
prune_profile() {
|
||||
local profile=$1 label=$2
|
||||
local list dels
|
||||
if [ ! -e "$profile" ] && [ ! -L "$profile" ]; then
|
||||
log "skip $label (no profile at $profile)"
|
||||
return 0
|
||||
fi
|
||||
list=$(list_gens "$profile" || true)
|
||||
if [ -z "$list" ]; then
|
||||
log "skip $label (no generation links)"
|
||||
return 0
|
||||
fi
|
||||
dels=$(printf '%s\n' "$list" | select_deletions)
|
||||
if [ -z "$dels" ]; then
|
||||
log "$label: nothing to prune"
|
||||
return 0
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
set -- $dels
|
||||
log "$label: delete generations $* (keep current + $KEEP_PAST past; age>$MAX_AGE_DAYS d)"
|
||||
if [ "$DRY" = 1 ]; then
|
||||
log "$label: dry-run — not deleting"
|
||||
return 0
|
||||
fi
|
||||
# nix-env needs a writeable profile; system requires root.
|
||||
nix-env -p "$profile" --delete-generations "$@" \
|
||||
|| log "$label: nix-env --delete-generations failed (need root for system?)"
|
||||
}
|
||||
|
||||
prune_profile /nix/var/nix/profiles/system "system"
|
||||
|
||||
# Home Manager: per-user under /nix/var/nix/profiles and XDG state.
|
||||
if [ -d /nix/var/nix/profiles/per-user ]; then
|
||||
for u in /nix/var/nix/profiles/per-user/*; do
|
||||
[ -d "$u" ] || continue
|
||||
prune_profile "$u/home-manager" "home-manager($(basename "$u"))"
|
||||
done
|
||||
fi
|
||||
# Standalone / modern HM state dir for real users' homes.
|
||||
if [ -d /home ]; then
|
||||
for h in /home/*; do
|
||||
[ -d "$h" ] || continue
|
||||
prune_profile "$h/.local/state/nix/profiles/home-manager" \
|
||||
"home-manager-xdg($(basename "$h"))"
|
||||
done
|
||||
fi
|
||||
# root's XDG state if present
|
||||
prune_profile /root/.local/state/nix/profiles/home-manager "home-manager-xdg(root)"
|
||||
|
||||
if [ "$DRY" = 1 ]; then
|
||||
log "dry-run done (no store GC)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Reclaim store paths freed by gen deletion — no --delete-older-than
|
||||
# (would re-introduce floor-free age GC on any remaining profiles).
|
||||
log "nix-collect-garbage (dead store paths only)"
|
||||
nix-collect-garbage || true
|
||||
|
||||
# Refresh systemd-boot entries so removed system gens disappear from
|
||||
# the menu without waiting for the next rebuild.
|
||||
if [ -x /run/current-system/bin/switch-to-configuration ]; then
|
||||
log "refreshing bootloader entries"
|
||||
/run/current-system/bin/switch-to-configuration boot >/dev/null 2>&1 \
|
||||
|| log "bootloader refresh skipped (non-fatal)"
|
||||
fi
|
||||
|
||||
log "done"
|
||||
''
|
||||
Reference in New Issue
Block a user