feat: self-update of master and agents (#15)
This commit is contained in:
@@ -40,21 +40,16 @@ type Publisher interface{ Publish(t events.Topic) }
|
||||
|
||||
// Service starts update jobs.
|
||||
type Service struct {
|
||||
store Store
|
||||
hub Hub
|
||||
pub Publisher
|
||||
selfRepo string
|
||||
log *slog.Logger
|
||||
now func() time.Time
|
||||
store Store
|
||||
hub Hub
|
||||
pub Publisher
|
||||
log *slog.Logger
|
||||
now func() time.Time
|
||||
}
|
||||
|
||||
// New returns a Service. agentImage is the master's AGENT_IMAGE; services
|
||||
// whose image repo equals its repo are the updater itself and are refused.
|
||||
func New(store Store, hub Hub, pub Publisher, agentImage string, log *slog.Logger) *Service {
|
||||
return &Service{
|
||||
store: store, hub: hub, pub: pub, log: log, now: time.Now,
|
||||
selfRepo: imageref.Parse(agentImage).Repo,
|
||||
}
|
||||
// New returns a Service.
|
||||
func New(store Store, hub Hub, pub Publisher, log *slog.Logger) *Service {
|
||||
return &Service{store: store, hub: hub, pub: pub, log: log, now: time.Now}
|
||||
}
|
||||
|
||||
// target splits a service's actual ref into the repo and tag to deploy. A bare
|
||||
@@ -102,8 +97,8 @@ func (s *Service) updatable(svc model.Service, explicitRef bool) error {
|
||||
switch {
|
||||
case svc.RemovedAt != nil:
|
||||
return &model.NotUpdatableError{Reason: model.ReasonRemoved}
|
||||
case svc.Self || imageref.Parse(svc.ActualRef).Repo == s.selfRepo:
|
||||
return &model.NotUpdatableError{Reason: model.ReasonSelf}
|
||||
case svc.Self && svc.Kind == protocol.KindSwarm:
|
||||
return &model.NotUpdatableError{Reason: model.ReasonSelfSwarm}
|
||||
case svc.Built:
|
||||
return &model.NotUpdatableError{Reason: model.ReasonBuilt}
|
||||
case svc.Kind == protocol.KindContainer:
|
||||
@@ -126,13 +121,7 @@ func (s *Service) Restorable(svc model.Service) error {
|
||||
if !svc.Drifted() {
|
||||
return &model.NotUpdatableError{Reason: model.ReasonNotDrifted}
|
||||
}
|
||||
if err := s.updatable(svc, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if imageref.Parse(svc.DesiredRef).Repo == s.selfRepo {
|
||||
return &model.NotUpdatableError{Reason: model.ReasonSelf}
|
||||
}
|
||||
return nil
|
||||
return s.updatable(svc, true)
|
||||
}
|
||||
|
||||
// RestoreDesired starts a manual job that deploys the drifted service's
|
||||
@@ -232,9 +221,10 @@ func (s *Service) TriggerVersion(ctx context.Context, serviceID, versionID int64
|
||||
}
|
||||
|
||||
// Start starts an update of svc. It returns the job, which may already be
|
||||
// failed ("agent offline", "agent too old for updates", or "agent too old to
|
||||
// failed ("agent offline", "agent too old for updates", "agent too old to
|
||||
// deploy a pinned version" when the ref has a digest or no tag and the agent
|
||||
// speaks protocol version 2); a
|
||||
// speaks protocol version 2, or "agent too old to update itself" for an
|
||||
// agent's own service before protocol version 4); a
|
||||
// *model.NotUpdatableError when the service cannot be updated (no job
|
||||
// created); the active job and model.ErrJobActive when one is queued or
|
||||
// running. Poll and webhook jobs are refused for a drifted service; only a
|
||||
@@ -255,6 +245,9 @@ func (s *Service) Start(ctx context.Context, svc model.Service, req StartRequest
|
||||
if p := imageref.Parse(ref); p.Digest != "" || p.Tag == "" {
|
||||
minProtocol = protocol.MinPinnedRefVersion
|
||||
}
|
||||
if svc.Self {
|
||||
minProtocol = protocol.MinSelfUpdateVersion
|
||||
}
|
||||
r, routeErr := s.hub.Route(svc, minProtocol)
|
||||
nj := model.NewJob{
|
||||
ServiceID: svc.ID, FromRef: svc.ActualRef, ToRef: ref,
|
||||
@@ -276,7 +269,7 @@ func (s *Service) Start(ctx context.Context, svc model.Service, req StartRequest
|
||||
|
||||
failure := routeErr
|
||||
if failure == nil {
|
||||
start := protocol.JobStart{Kind: svc.Kind, Ref: ref}
|
||||
start := protocol.JobStart{Kind: svc.Kind, Ref: ref, Self: svc.Self}
|
||||
if svc.Kind == protocol.KindSwarm {
|
||||
start.SwarmClusterID, start.SwarmService = svc.SwarmClusterID, svc.SwarmService
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user