66 lines
2.0 KiB
Go
66 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"gitea.dcglab.co.uk/steve/restic-manager/internal/agent/updater"
|
|
"gitea.dcglab.co.uk/steve/restic-manager/internal/agent/wsclient"
|
|
"gitea.dcglab.co.uk/steve/restic-manager/internal/api"
|
|
)
|
|
|
|
// runUpdate handles a server-dispatched command.update. It logs progress
|
|
// via log.stream so the live job page captures pre-restart state, then
|
|
// calls the platform updater. On Linux the updater calls os.Exit; on
|
|
// Windows it spawns a detached helper and returns, with the agent then
|
|
// exiting.
|
|
//
|
|
// The terminal job state is set by the server, not the agent: success
|
|
// is "agent re-hellos with matching version" rather than anything the
|
|
// agent itself can assert. The only `job.finished` we send from here is
|
|
// on the failure path, before any restart attempt.
|
|
func (d *dispatcher) runUpdate(ctx context.Context, p api.CommandUpdatePayload, tx wsclient.Sender) {
|
|
logf := func(format string, args ...any) {
|
|
line := fmt.Sprintf(format, args...)
|
|
slog.Info("ws agent: update: " + line)
|
|
env, err := api.Marshal(api.MsgLogStream, "", api.LogStreamLine{
|
|
JobID: p.JobID,
|
|
TS: time.Now().UTC(),
|
|
Stream: api.LogStdout,
|
|
Payload: line,
|
|
})
|
|
if err == nil {
|
|
_ = tx.Send(env)
|
|
}
|
|
}
|
|
|
|
startedEnv, err := api.Marshal(api.MsgJobStarted, "", api.JobStartedPayload{
|
|
JobID: p.JobID,
|
|
Kind: api.JobUpdate,
|
|
StartedAt: time.Now().UTC(),
|
|
})
|
|
if err == nil {
|
|
_ = tx.Send(startedEnv)
|
|
}
|
|
|
|
logf("fetching new binary from %s", d.serverURL)
|
|
if err := updater.Update(ctx, d.serverURL); err != nil {
|
|
logf("update failed: %v", err)
|
|
finishedEnv, mErr := api.Marshal(api.MsgJobFinished, "", api.JobFinishedPayload{
|
|
JobID: p.JobID,
|
|
Status: api.JobFailed,
|
|
FinishedAt: time.Now().UTC(),
|
|
Error: err.Error(),
|
|
})
|
|
if mErr == nil {
|
|
_ = tx.Send(finishedEnv)
|
|
}
|
|
return
|
|
}
|
|
// Unreachable on Linux (Update calls os.Exit). On Windows control
|
|
// returns here while the detached helper does the swap-and-restart;
|
|
// the agent then exits cleanly so SCM hands off.
|
|
}
|