feat: self-update of master and agents (#15)

This commit is contained in:
2026-10-13 11:55:46 +02:00
parent ec28d1e027
commit fe4aca2883
34 changed files with 1167 additions and 115 deletions
+20 -4
View File
@@ -11,8 +11,6 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/shcizo/package-updater/internal/protocol"
)
const (
@@ -71,6 +69,7 @@ func dockerEnv() []string {
// ComposeDocker is the subset of the Docker SDK ComposeExecutor needs.
type ComposeDocker interface {
SelfInspector
HelperDocker
ContainerList(ctx context.Context, opts container.ListOptions) ([]container.Summary, error)
}
@@ -95,7 +94,14 @@ func NewComposeExecutor(cli ComposeDocker, resolve *Resolver, selfID string, run
// is), writes it to the stack's override file and recreates the service.
// Working directory and config files come from the service's container
// labels on this machine, never from the job. It returns the pinned ref.
func (e *ComposeExecutor) Execute(ctx context.Context, job protocol.JobStart, out io.Writer) (string, error) {
//
// When the service is the agent's own container, the recreate runs in a
// helper container instead (see selfUpdate), because it stops this process.
func (e *ComposeExecutor) Execute(ctx context.Context, job Job, out io.Writer) (string, error) {
// What the job has printed so far goes into the helper's labels.
soFar := &tailBuffer{max: selfUpdateOutputMax}
out = io.MultiWriter(out, tailWriter{soFar})
project, service := job.ComposeProject, job.ComposeService
cts, err := e.cli.ContainerList(ctx, container.ListOptions{
All: true,
@@ -114,10 +120,11 @@ func (e *ComposeExecutor) Execute(ctx context.Context, job protocol.JobStart, ou
configFiles := cts[0].Labels[labelConfigFiles]
envFileLabel := cts[0].Labels[labelEnvFile]
roots, err := MountRoots(ctx, e.cli, e.selfID)
self, err := inspectSelf(ctx, e.cli, e.selfID)
if err != nil {
return "", err
}
roots := rootsOf(self)
files, dir, err := composeFiles(roots, configFiles)
if err != nil {
return "", err
@@ -163,8 +170,17 @@ func (e *ComposeExecutor) Execute(ctx context.Context, job protocol.JobStart, ou
}
base := composeBase(project, workingDir, files, envs)
isSelf := false
if self.ContainerJSONBase != nil && self.ID != "" {
for _, ct := range cts {
isSelf = isSelf || ct.ID == self.ID
}
}
for _, step := range [][]string{{"pull", service}, {"up", "-d", service}} {
args := append(append([]string(nil), base...), step...)
if isSelf && step[0] == "up" {
return e.selfUpdate(ctx, job, self, workingDir, args, pinned, out, soFar)
}
fmt.Fprintf(out, "$ docker %s\n", strings.Join(args, " "))
tail := &tailBuffer{max: errorOutputTail}
if err := e.run(ctx, workingDir, io.MultiWriter(out, tailWriter{tail}), args...); err != nil {