Add the Packages page for nixpkgs upgrades

A page under System for router-upgrade: the channel to follow, Check,
Preview (the package versions that change, the download size, what would be
built here, a reboot note for a new kernel), Download now and Upgrade. The
steps run in router-upgrade.service, which the page asks through a request
file; the last run's output is kept in upgrade/last.log because a finished
one-shot unit has no journal to look up.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
2026-11-08 22:27:39 +01:00
co-authored by Claude Sonnet 5.5
parent 4ac8c6ea6f
commit dd03127a24
10 changed files with 653 additions and 11 deletions
+9 -6
View File
@@ -220,25 +220,28 @@ var startUnit = func(unit string) error {
return err
}
// UpdateStatus is the state of the router-update unit.
// UpdateStatus is the state of a one-shot unit (router-update, router-upgrade)
// and what its last run logged.
type UpdateStatus struct {
Running bool
Result string // of the last run; "" if none
Log string
}
func (s System) UpdateStatus() UpdateStatus {
func unitRun(unit string) UpdateStatus {
st := UpdateStatus{}
st.Running = unitProperty("router-update.service", "ActiveState") == "activating"
if inv := unitProperty("router-update.service", "InvocationID"); inv != "" {
st.Running = unitProperty(unit, "ActiveState") == "activating"
if inv := unitProperty(unit, "InvocationID"); inv != "" {
if !st.Running {
st.Result = unitProperty("router-update.service", "Result")
st.Result = unitProperty(unit, "Result")
}
st.Log, _ = command("journalctl", "--no-pager", "-o", "cat", "-n", "200", "_SYSTEMD_INVOCATION_ID="+inv)
}
return st
}
func (s System) UpdateStatus() UpdateStatus { return unitRun("router-update.service") }
type updateData struct {
Installed Release
Status UpdateStatus
@@ -273,7 +276,7 @@ func (a *app) updateBack(w http.ResponseWriter, r *http.Request, msg string) {
func (a *app) busy() bool {
st := a.sys.Status()
return st.Applying || st.ConfirmRunning || st.RollbackIn > 0 || a.sys.UpdateStatus().Running
return st.Applying || st.ConfirmRunning || st.RollbackIn > 0 || a.sys.UpdateStatus().Running || a.sys.UpgradeStatus().Running
}
func (a *app) updateSaveURL(w http.ResponseWriter, r *http.Request, _ session) {