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  }