diff --git a/cmd/server/server.go b/cmd/server/server.go index 735c31e..3698d0d 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -232,6 +232,7 @@ func runServer() { meta.Register(api, mods) meta.RegisterHealth(api, sessions) meta.RegisterWhoami(api, sessions, roles, mods) + meta.ConfigPath = configPath meta.RegisterUpdate(api) auth.RegisterLogin(api, sessions, auditStore, cfg.SecureCookie()) diff --git a/internal/meta/update.go b/internal/meta/update.go index a039bd5..6a4910e 100644 --- a/internal/meta/update.go +++ b/internal/meta/update.go @@ -6,11 +6,16 @@ import ( "os/exec" "syscall" + "nadir/internal/config" "nadir/internal/oscmd" "github.com/danielgtaylor/huma/v2" ) +// ConfigPath is set at startup so the update handler can re-load config and +// surface release_repo / parse errors to the caller instead of only stderr. +var ConfigPath string + // RegisterUpdate wires POST /api/meta/update. It runs the equivalent of // `sudo nadir update` in a detached session and returns 202 immediately; the // systemctl restart that ends the updater drops in-flight connections, so the @@ -28,9 +33,18 @@ func RegisterUpdate(api huma.API) { Description: "Equivalent to running `sudo nadir update` on the host: queries server.release_repo for the latest release, downloads the binary matching the host's architecture, atomically replaces the running binary, and restarts the systemd unit. Returns 202 immediately; the service restart drops in-flight connections, so poll /api/health to confirm the new version is up. Requires the wildcard admin role.", Tags: []string{"Meta"}, Metadata: map[string]any{"module": "meta", "permission": "root"}, - Errors: []int{401, 403, 500}, + Errors: []int{400, 401, 403, 500}, DefaultStatus: 202, }, func(ctx context.Context, _ *struct{}) (*oscmd.StatusOutput, error) { + if ConfigPath != "" { + cfg, err := config.Load(ConfigPath) + if err != nil { + return nil, huma.Error500InternalServerError("config load failed", err) + } + if cfg.Server.ReleaseRepo == "" { + return nil, huma.Error400BadRequest("server.release_repo not set in " + ConfigPath) + } + } exe, err := os.Executable() if err != nil { return nil, huma.Error500InternalServerError("could not resolve own binary path", err)