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