Show a progress bar and live log while Hammerhead, edges and sites update
The updater reports each step (checking, downloading with percent, verifying, installing, restarting). Edges and sites send that progress and their log with their reports; Hammerhead serves it to a dialog that opens when an update starts, and keeps its own last update log on disk across the restart. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9bd48917c7
commit
2b7cb5dd35
11 files changed
+306
-13
No files matched your search
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -45,13 +46,32 @@ func (s *Server) applyUpdate(w http.ResponseWriter, r *http.Request, p *principa
|
||||
fail(w, 400, errors.New("auto-update is off: set HAMMERHEAD_AUTO_UPDATE=1 and restart Hammerhead, or update it by hand"))
|
||||
return
|
||||
}
|
||||
u := &s.selfUpd
|
||||
u.mu.Lock()
|
||||
if u.running {
|
||||
u.mu.Unlock()
|
||||
fail(w, 409, errors.New("an update is already running"))
|
||||
return
|
||||
}
|
||||
u.running, u.stage, u.pct, u.lines = true, "starting", 0, nil
|
||||
u.mu.Unlock()
|
||||
os.WriteFile(s.updateLogPath(), nil, 0o600) // a new run starts a new log
|
||||
cfg := s.updateConfig("hammerhead", s.opts.Version)
|
||||
cfg.Restart = func(exe string) error { s.Close(); return selfupdate.Restart(exe) }
|
||||
cfg.Progress = func(e selfupdate.Event) { s.selfNote(e.Stage, e.Pct, e.Line) }
|
||||
cfg.Restart = func(exe string) error {
|
||||
s.selfNote("restarting", 100, "Closing the database and restarting")
|
||||
s.Close()
|
||||
return selfupdate.Restart(exe)
|
||||
}
|
||||
s.selfNote("starting", 0, "Update requested by "+p.User.Email)
|
||||
s.audit("", p.User.Email, "server.update", "")
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
defer cancel()
|
||||
selfupdate.CheckOnce(ctx, cfg) // on success the process is replaced and this never returns
|
||||
u.mu.Lock()
|
||||
u.running = false
|
||||
u.mu.Unlock()
|
||||
}()
|
||||
writeJSON(w, 200, map[string]any{"started": true})
|
||||
}
|
||||
@@ -121,6 +141,7 @@ func (s *Server) updateEdge(w http.ResponseWriter, r *http.Request, p *principal
|
||||
fail(w, 400, err)
|
||||
return
|
||||
}
|
||||
delete(s.updRuns, e.ID) // a new request starts a new log
|
||||
s.bump()
|
||||
s.audit("", p.User.Email, "edge.update", e.Name)
|
||||
ok(w)
|
||||
@@ -142,6 +163,7 @@ func (s *Server) updateSite(w http.ResponseWriter, r *http.Request, c *orgCtx) {
|
||||
fail(w, 400, err)
|
||||
return
|
||||
}
|
||||
delete(s.updRuns, st.ID)
|
||||
s.bump()
|
||||
s.audit(c.Org.ID, c.Actor, "site.update", st.Name)
|
||||
ok(w)
|
||||
|
||||
Reference in new issue
Block a user