feat: self-update of master and agents (#15)
This commit is contained in:
@@ -16,8 +16,9 @@ type candidate struct {
|
||||
|
||||
// Route picks the connection a job for svc goes to, among agents that speak
|
||||
// at least protocol version minProtocol. It returns model.ErrAgentOffline or
|
||||
// model.ErrAgentTooOld (model.ErrAgentTooOldForPinned when minProtocol asks
|
||||
// for a pinned ref) when there is none.
|
||||
// model.ErrAgentTooOld (model.ErrAgentTooOldForSelfUpdate when minProtocol
|
||||
// asks for self-update, model.ErrAgentTooOldForPinned when it asks for a
|
||||
// pinned ref) when there is none.
|
||||
func (h *Hub) Route(svc model.Service, minProtocol int) (model.Route, error) {
|
||||
h.mu.Lock()
|
||||
conns := make([]candidate, 0, len(h.conns))
|
||||
@@ -65,6 +66,9 @@ func route(svc model.Service, conns []candidate, minProtocol int) (model.Route,
|
||||
}
|
||||
}
|
||||
if tooOld {
|
||||
if minProtocol >= protocol.MinSelfUpdateVersion {
|
||||
return model.Route{}, model.ErrAgentTooOldForSelfUpdate
|
||||
}
|
||||
if minProtocol >= protocol.MinPinnedRefVersion {
|
||||
return model.Route{}, model.ErrAgentTooOldForPinned
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ func TestRoute(t *testing.T) {
|
||||
swarmSvc := model.Service{Kind: protocol.KindSwarm, AgentID: ptr(int64(1)), SwarmClusterID: "c1"}
|
||||
v2 := protocol.Hello{ProtocolVersion: 2}
|
||||
v3 := protocol.Hello{ProtocolVersion: 3}
|
||||
v4 := protocol.Hello{ProtocolVersion: 4}
|
||||
mgrV2 := protocol.Hello{ProtocolVersion: 2, SwarmManager: true, SwarmClusterID: "c1"}
|
||||
mgrV3 := protocol.Hello{ProtocolVersion: 3, SwarmManager: true, SwarmClusterID: "c1"}
|
||||
jobs, pinned := protocol.MinJobVersion, protocol.MinPinnedRefVersion
|
||||
jobs, pinned, selfUpdate := protocol.MinJobVersion, protocol.MinPinnedRefVersion, protocol.MinSelfUpdateVersion
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -47,6 +48,8 @@ func TestRoute(t *testing.T) {
|
||||
[]candidate{{1, 10, protocol.Hello{ProtocolVersion: 2, SwarmManager: true}}}, jobs, model.Route{}, model.ErrAgentOffline},
|
||||
{"swarm, pinned ref falls back to a v3 manager when the reporting one is v2", swarmSvc,
|
||||
[]candidate{{1, 10, mgrV2}, {3, 30, mgrV3}}, pinned, model.Route{AgentID: 3, ConnID: 30}, nil},
|
||||
{"compose, own agent is v3 and the job updates the agent itself", composeSvc, []candidate{{2, 20, v3}}, selfUpdate, model.Route{}, model.ErrAgentTooOldForSelfUpdate},
|
||||
{"compose, v4 agent and a self-update", composeSvc, []candidate{{2, 20, v4}}, selfUpdate, model.Route{AgentID: 2, ConnID: 20}, nil},
|
||||
{"swarm, pinned ref and only v2 managers", swarmSvc, []candidate{{1, 10, mgrV2}}, pinned, model.Route{}, model.ErrAgentTooOldForPinned},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -57,3 +60,11 @@ func TestRoute(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoute_TooOldForSelfUpdateIsAlsoTooOld(t *testing.T) {
|
||||
svc := model.Service{Kind: protocol.KindCompose, AgentID: ptr(int64(2))}
|
||||
_, err := route(svc, []candidate{{2, 20, protocol.Hello{ProtocolVersion: 3}}}, protocol.MinSelfUpdateVersion)
|
||||
assert.ErrorIs(t, err, model.ErrAgentTooOldForSelfUpdate)
|
||||
assert.ErrorIs(t, err, model.ErrAgentTooOld)
|
||||
assert.EqualError(t, err, "agent too old to update itself")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user