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  }