github.com/devdivbcp/moby@v17.12.0-ce-rc1.0.20200726071732-2d4bfdc789ad+incompatible/internal/test/daemon/swarm.go (about) 1 package daemon 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/docker/docker/api/types/swarm" 8 "github.com/docker/docker/internal/test" 9 "github.com/pkg/errors" 10 "gotest.tools/assert" 11 ) 12 13 const ( 14 // DefaultSwarmPort is the default port use for swarm in the tests 15 DefaultSwarmPort = 2477 16 defaultSwarmListenAddr = "0.0.0.0" 17 ) 18 19 var ( 20 startArgs = []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} 21 ) 22 23 // StartNode (re)starts the daemon 24 func (d *Daemon) StartNode(t testingT) { 25 if ht, ok := t.(test.HelperT); ok { 26 ht.Helper() 27 } 28 d.Start(t, startArgs...) 29 } 30 31 // StartNodeWithBusybox starts daemon to be used as a swarm node, and loads the busybox image 32 func (d *Daemon) StartNodeWithBusybox(t testingT) { 33 if ht, ok := t.(test.HelperT); ok { 34 ht.Helper() 35 } 36 d.StartWithBusybox(t, startArgs...) 37 } 38 39 // RestartNode restarts a daemon to be used as a swarm node 40 func (d *Daemon) RestartNode(t testingT) { 41 if ht, ok := t.(test.HelperT); ok { 42 ht.Helper() 43 } 44 // avoid networking conflicts 45 d.Stop(t) 46 d.Start(t, startArgs...) 47 } 48 49 // StartAndSwarmInit starts the daemon (with busybox) and init the swarm 50 func (d *Daemon) StartAndSwarmInit(t testingT) { 51 d.StartNodeWithBusybox(t) 52 d.SwarmInit(t, swarm.InitRequest{}) 53 } 54 55 // StartAndSwarmJoin starts the daemon (with busybox) and join the specified swarm as worker or manager 56 func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) { 57 if th, ok := t.(test.HelperT); ok { 58 th.Helper() 59 } 60 d.StartNodeWithBusybox(t) 61 62 tokens := leader.JoinTokens(t) 63 token := tokens.Worker 64 if manager { 65 token = tokens.Manager 66 } 67 t.Logf("[%s] joining swarm manager [%s]@%s, swarm listen addr %s", d.id, leader.id, leader.SwarmListenAddr(), d.SwarmListenAddr()) 68 d.SwarmJoin(t, swarm.JoinRequest{ 69 RemoteAddrs: []string{leader.SwarmListenAddr()}, 70 JoinToken: token, 71 }) 72 } 73 74 // SpecConstructor defines a swarm spec constructor 75 type SpecConstructor func(*swarm.Spec) 76 77 // SwarmListenAddr returns the listen-addr used for the daemon 78 func (d *Daemon) SwarmListenAddr() string { 79 return fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) 80 } 81 82 // NodeID returns the swarm mode node ID 83 func (d *Daemon) NodeID() string { 84 return d.CachedInfo.Swarm.NodeID 85 } 86 87 // SwarmInit initializes a new swarm cluster. 88 func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) { 89 if ht, ok := t.(test.HelperT); ok { 90 ht.Helper() 91 } 92 if req.ListenAddr == "" { 93 req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) 94 } 95 if req.DefaultAddrPool == nil { 96 req.DefaultAddrPool = d.DefaultAddrPool 97 req.SubnetSize = d.SubnetSize 98 } 99 if d.DataPathPort > 0 { 100 req.DataPathPort = d.DataPathPort 101 } 102 cli := d.NewClientT(t) 103 defer cli.Close() 104 _, err := cli.SwarmInit(context.Background(), req) 105 assert.NilError(t, err, "initializing swarm") 106 d.CachedInfo = d.Info(t) 107 } 108 109 // SwarmJoin joins a daemon to an existing cluster. 110 func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) { 111 if ht, ok := t.(test.HelperT); ok { 112 ht.Helper() 113 } 114 if req.ListenAddr == "" { 115 req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) 116 } 117 cli := d.NewClientT(t) 118 defer cli.Close() 119 err := cli.SwarmJoin(context.Background(), req) 120 assert.NilError(t, err, "[%s] joining swarm", d.id) 121 d.CachedInfo = d.Info(t) 122 } 123 124 // SwarmLeave forces daemon to leave current cluster. 125 // 126 // The passed in TestingT is only used to validate that the client was successfully created 127 // Some tests rely on error checking the result of the actual unlock, so allow 128 // the error to be returned. 129 func (d *Daemon) SwarmLeave(t assert.TestingT, force bool) error { 130 cli := d.NewClientT(t) 131 defer cli.Close() 132 return cli.SwarmLeave(context.Background(), force) 133 } 134 135 // SwarmInfo returns the swarm information of the daemon 136 func (d *Daemon) SwarmInfo(t assert.TestingT) swarm.Info { 137 if ht, ok := t.(test.HelperT); ok { 138 ht.Helper() 139 } 140 cli := d.NewClientT(t) 141 info, err := cli.Info(context.Background()) 142 assert.NilError(t, err, "get swarm info") 143 return info.Swarm 144 } 145 146 // SwarmUnlock tries to unlock a locked swarm 147 // 148 // The passed in TestingT is only used to validate that the client was successfully created 149 // Some tests rely on error checking the result of the actual unlock, so allow 150 // the error to be returned. 151 func (d *Daemon) SwarmUnlock(t assert.TestingT, req swarm.UnlockRequest) error { 152 cli := d.NewClientT(t) 153 defer cli.Close() 154 155 err := cli.SwarmUnlock(context.Background(), req) 156 if err != nil { 157 err = errors.Wrap(err, "unlocking swarm") 158 } 159 return err 160 } 161 162 // GetSwarm returns the current swarm object 163 func (d *Daemon) GetSwarm(t assert.TestingT) swarm.Swarm { 164 if ht, ok := t.(test.HelperT); ok { 165 ht.Helper() 166 } 167 cli := d.NewClientT(t) 168 defer cli.Close() 169 170 sw, err := cli.SwarmInspect(context.Background()) 171 assert.NilError(t, err) 172 return sw 173 } 174 175 // UpdateSwarm updates the current swarm object with the specified spec constructors 176 func (d *Daemon) UpdateSwarm(t assert.TestingT, f ...SpecConstructor) { 177 if ht, ok := t.(test.HelperT); ok { 178 ht.Helper() 179 } 180 cli := d.NewClientT(t) 181 defer cli.Close() 182 183 sw := d.GetSwarm(t) 184 for _, fn := range f { 185 fn(&sw.Spec) 186 } 187 188 err := cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{}) 189 assert.NilError(t, err) 190 } 191 192 // RotateTokens update the swarm to rotate tokens 193 func (d *Daemon) RotateTokens(t assert.TestingT) { 194 if ht, ok := t.(test.HelperT); ok { 195 ht.Helper() 196 } 197 cli := d.NewClientT(t) 198 defer cli.Close() 199 200 sw, err := cli.SwarmInspect(context.Background()) 201 assert.NilError(t, err) 202 203 flags := swarm.UpdateFlags{ 204 RotateManagerToken: true, 205 RotateWorkerToken: true, 206 } 207 208 err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags) 209 assert.NilError(t, err) 210 } 211 212 // JoinTokens returns the current swarm join tokens 213 func (d *Daemon) JoinTokens(t assert.TestingT) swarm.JoinTokens { 214 if ht, ok := t.(test.HelperT); ok { 215 ht.Helper() 216 } 217 cli := d.NewClientT(t) 218 defer cli.Close() 219 220 sw, err := cli.SwarmInspect(context.Background()) 221 assert.NilError(t, err) 222 return sw.JoinTokens 223 }