2018-04-11 06:10:17 -04:00
|
|
|
package daemon
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/docker/docker/api/types/swarm"
|
2018-04-18 11:16:55 -04:00
|
|
|
"github.com/docker/docker/internal/test"
|
2018-04-11 06:10:17 -04:00
|
|
|
"github.com/pkg/errors"
|
2018-06-11 09:32:11 -04:00
|
|
|
"gotest.tools/assert"
|
2018-04-11 06:10:17 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2018-04-18 10:18:53 -04:00
|
|
|
// DefaultSwarmPort is the default port use for swarm in the tests
|
|
|
|
DefaultSwarmPort = 2477
|
2018-04-11 06:10:17 -04:00
|
|
|
defaultSwarmListenAddr = "0.0.0.0"
|
|
|
|
)
|
|
|
|
|
2018-04-13 11:02:56 -04:00
|
|
|
// StartAndSwarmInit starts the daemon (with busybox) and init the swarm
|
|
|
|
func (d *Daemon) StartAndSwarmInit(t testingT) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-13 11:02:56 -04:00
|
|
|
// avoid networking conflicts
|
|
|
|
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
|
|
|
|
d.StartWithBusybox(t, args...)
|
|
|
|
|
|
|
|
d.SwarmInit(t, swarm.InitRequest{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// StartAndSwarmJoin starts the daemon (with busybox) and join the specified swarm as worker or manager
|
|
|
|
func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-13 11:02:56 -04:00
|
|
|
// avoid networking conflicts
|
|
|
|
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
|
|
|
|
d.StartWithBusybox(t, args...)
|
|
|
|
|
|
|
|
tokens := leader.JoinTokens(t)
|
|
|
|
token := tokens.Worker
|
|
|
|
if manager {
|
|
|
|
token = tokens.Manager
|
|
|
|
}
|
|
|
|
d.SwarmJoin(t, swarm.JoinRequest{
|
|
|
|
RemoteAddrs: []string{leader.SwarmListenAddr()},
|
|
|
|
JoinToken: token,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-04-11 06:10:17 -04:00
|
|
|
// SpecConstructor defines a swarm spec constructor
|
|
|
|
type SpecConstructor func(*swarm.Spec)
|
|
|
|
|
|
|
|
// SwarmListenAddr returns the listen-addr used for the daemon
|
|
|
|
func (d *Daemon) SwarmListenAddr() string {
|
|
|
|
return fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NodeID returns the swarm mode node ID
|
|
|
|
func (d *Daemon) NodeID() string {
|
|
|
|
return d.CachedInfo.Swarm.NodeID
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwarmInit initializes a new swarm cluster.
|
|
|
|
func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
if req.ListenAddr == "" {
|
|
|
|
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
|
|
|
}
|
2018-07-30 11:25:02 -04:00
|
|
|
if req.DefaultAddrPool == nil {
|
|
|
|
req.DefaultAddrPool = d.DefaultAddrPool
|
|
|
|
req.SubnetSize = d.SubnetSize
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
_, err := cli.SwarmInit(context.Background(), req)
|
|
|
|
assert.NilError(t, err, "initializing swarm")
|
|
|
|
d.CachedInfo = d.Info(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwarmJoin joins a daemon to an existing cluster.
|
|
|
|
func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
if req.ListenAddr == "" {
|
|
|
|
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
|
|
|
}
|
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
err := cli.SwarmJoin(context.Background(), req)
|
|
|
|
assert.NilError(t, err, "initializing swarm")
|
|
|
|
d.CachedInfo = d.Info(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwarmLeave forces daemon to leave current cluster.
|
|
|
|
func (d *Daemon) SwarmLeave(force bool) error {
|
|
|
|
cli, err := d.NewClient()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("leaving swarm: failed to create client %v", err)
|
|
|
|
}
|
|
|
|
defer cli.Close()
|
|
|
|
err = cli.SwarmLeave(context.Background(), force)
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("leaving swarm: %v", err)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwarmInfo returns the swarm information of the daemon
|
|
|
|
func (d *Daemon) SwarmInfo(t assert.TestingT) swarm.Info {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
info, err := cli.Info(context.Background())
|
|
|
|
assert.NilError(t, err, "get swarm info")
|
|
|
|
return info.Swarm
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwarmUnlock tries to unlock a locked swarm
|
|
|
|
func (d *Daemon) SwarmUnlock(req swarm.UnlockRequest) error {
|
|
|
|
cli, err := d.NewClient()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unlocking swarm: failed to create client %v", err)
|
|
|
|
}
|
|
|
|
defer cli.Close()
|
|
|
|
err = cli.SwarmUnlock(context.Background(), req)
|
|
|
|
if err != nil {
|
|
|
|
err = errors.Wrap(err, "unlocking swarm")
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSwarm returns the current swarm object
|
|
|
|
func (d *Daemon) GetSwarm(t assert.TestingT) swarm.Swarm {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
|
|
|
|
sw, err := cli.SwarmInspect(context.Background())
|
|
|
|
assert.NilError(t, err)
|
|
|
|
return sw
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateSwarm updates the current swarm object with the specified spec constructors
|
|
|
|
func (d *Daemon) UpdateSwarm(t assert.TestingT, f ...SpecConstructor) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
|
|
|
|
sw := d.GetSwarm(t)
|
|
|
|
for _, fn := range f {
|
|
|
|
fn(&sw.Spec)
|
|
|
|
}
|
|
|
|
|
|
|
|
err := cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RotateTokens update the swarm to rotate tokens
|
|
|
|
func (d *Daemon) RotateTokens(t assert.TestingT) {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
|
|
|
|
sw, err := cli.SwarmInspect(context.Background())
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
flags := swarm.UpdateFlags{
|
|
|
|
RotateManagerToken: true,
|
|
|
|
RotateWorkerToken: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// JoinTokens returns the current swarm join tokens
|
|
|
|
func (d *Daemon) JoinTokens(t assert.TestingT) swarm.JoinTokens {
|
2018-04-18 11:16:55 -04:00
|
|
|
if ht, ok := t.(test.HelperT); ok {
|
|
|
|
ht.Helper()
|
|
|
|
}
|
2018-04-11 06:10:17 -04:00
|
|
|
cli := d.NewClientT(t)
|
|
|
|
defer cli.Close()
|
|
|
|
|
|
|
|
sw, err := cli.SwarmInspect(context.Background())
|
|
|
|
assert.NilError(t, err)
|
|
|
|
return sw.JoinTokens
|
|
|
|
}
|