mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Make internal/test/daemon.Daemon swarm aware
This remove the daemon.Swarm construction by make the new test Daemon struct aware of swarm. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
f0d277fe84
commit
83d18cf4e3
18 changed files with 721 additions and 697 deletions
|
@ -311,7 +311,7 @@ func init() {
|
|||
type DockerSwarmSuite struct {
|
||||
server *httptest.Server
|
||||
ds *DockerSuite
|
||||
daemons []*daemon.Swarm
|
||||
daemons []*daemon.Daemon
|
||||
daemonsLock sync.Mutex // protect access to daemons
|
||||
portIndex int
|
||||
}
|
||||
|
@ -328,14 +328,10 @@ func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
|
|||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm {
|
||||
d := &daemon.Swarm{
|
||||
Daemon: daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
}),
|
||||
Port: defaultSwarmPort + s.portIndex,
|
||||
}
|
||||
d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
|
||||
func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Daemon {
|
||||
d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
}, testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex))
|
||||
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} // avoid networking conflicts
|
||||
d.StartWithBusybox(c, args...)
|
||||
|
||||
|
@ -346,12 +342,12 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemo
|
|||
if manager {
|
||||
token = tokens.Manager
|
||||
}
|
||||
c.Assert(d.Join(swarm.JoinRequest{
|
||||
RemoteAddrs: []string{s.daemons[0].ListenAddr},
|
||||
d.SwarmJoin(c, swarm.JoinRequest{
|
||||
RemoteAddrs: []string{s.daemons[0].SwarmListenAddr()},
|
||||
JoinToken: token,
|
||||
}), check.IsNil)
|
||||
})
|
||||
} else {
|
||||
c.Assert(d.Init(swarm.InitRequest{}), check.IsNil)
|
||||
d.SwarmInit(c, swarm.InitRequest{})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,8 @@ type Config struct {
|
|||
// New returns a Daemon instance to be used for testing.
|
||||
// This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST.
|
||||
// The daemon will not automatically start.
|
||||
func New(t testingT, dockerBinary string, dockerdBinary string, config Config) *Daemon {
|
||||
ops := []func(*daemon.Daemon){
|
||||
daemon.WithDockerdBinary(dockerdBinary),
|
||||
}
|
||||
func New(t testingT, dockerBinary string, dockerdBinary string, config Config, ops ...func(*daemon.Daemon)) *Daemon {
|
||||
ops = append(ops, daemon.WithDockerdBinary(dockerdBinary))
|
||||
if config.Experimental {
|
||||
ops = append(ops, daemon.WithExperimental)
|
||||
}
|
||||
|
@ -150,6 +148,21 @@ func (d *Daemon) WaitRun(contID string) error {
|
|||
return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...)
|
||||
}
|
||||
|
||||
// CmdRetryOutOfSequence tries the specified command against the current daemon for 10 times
|
||||
func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) {
|
||||
for i := 0; ; i++ {
|
||||
out, err := d.Cmd(args...)
|
||||
if err != nil {
|
||||
if strings.Contains(out, "update out of sequence") {
|
||||
if i < 10 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
}
|
||||
|
||||
// WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.
|
||||
// Deprecated: use cli.WaitCmd instead
|
||||
func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error {
|
||||
|
|
|
@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/integration-cli/daemon"
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
|
@ -12,178 +11,12 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/go-check/check"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Swarm is a test daemon with helpers for participating in a swarm.
|
||||
type Swarm struct {
|
||||
*Daemon
|
||||
swarm.Info
|
||||
Port int
|
||||
ListenAddr string
|
||||
}
|
||||
|
||||
// Init initializes a new swarm cluster.
|
||||
func (d *Swarm) Init(req swarm.InitRequest) error {
|
||||
if req.ListenAddr == "" {
|
||||
req.ListenAddr = d.ListenAddr
|
||||
}
|
||||
cli, err := d.NewClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("initializing swarm: failed to create client %v", err)
|
||||
}
|
||||
defer cli.Close()
|
||||
_, err = cli.SwarmInit(context.Background(), req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("initializing swarm: %v", err)
|
||||
}
|
||||
info, err := d.SwarmInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Info = info
|
||||
return nil
|
||||
}
|
||||
|
||||
// Join joins a daemon to an existing cluster.
|
||||
func (d *Swarm) Join(req swarm.JoinRequest) error {
|
||||
if req.ListenAddr == "" {
|
||||
req.ListenAddr = d.ListenAddr
|
||||
}
|
||||
cli, err := d.NewClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("joining swarm: failed to create client %v", err)
|
||||
}
|
||||
defer cli.Close()
|
||||
err = cli.SwarmJoin(context.Background(), req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("joining swarm: %v", err)
|
||||
}
|
||||
info, err := d.SwarmInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Info = info
|
||||
return nil
|
||||
}
|
||||
|
||||
// Leave forces daemon to leave current cluster.
|
||||
func (d *Swarm) Leave(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 *Swarm) SwarmInfo() (swarm.Info, error) {
|
||||
cli, err := d.NewClient()
|
||||
if err != nil {
|
||||
return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
|
||||
}
|
||||
|
||||
info, err := cli.Info(context.Background())
|
||||
if err != nil {
|
||||
return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
|
||||
}
|
||||
|
||||
return info.Swarm, nil
|
||||
}
|
||||
|
||||
// Unlock tries to unlock a locked swarm
|
||||
func (d *Swarm) Unlock(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
|
||||
}
|
||||
|
||||
// ServiceConstructor defines a swarm service constructor function
|
||||
type ServiceConstructor func(*swarm.Service)
|
||||
|
||||
// NodeConstructor defines a swarm node constructor
|
||||
type NodeConstructor func(*swarm.Node)
|
||||
|
||||
// SecretConstructor defines a swarm secret constructor
|
||||
type SecretConstructor func(*swarm.Secret)
|
||||
|
||||
// ConfigConstructor defines a swarm config constructor
|
||||
type ConfigConstructor func(*swarm.Config)
|
||||
|
||||
// SpecConstructor defines a swarm spec constructor
|
||||
type SpecConstructor func(*swarm.Spec)
|
||||
|
||||
// CreateServiceWithOptions creates a swarm service given the specified service constructors
|
||||
// and auth config
|
||||
func (d *Swarm) CreateServiceWithOptions(c *check.C, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
|
||||
var service swarm.Service
|
||||
for _, fn := range f {
|
||||
fn(&service)
|
||||
}
|
||||
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
res, err := cli.ServiceCreate(ctx, service.Spec, opts)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return res.ID
|
||||
}
|
||||
|
||||
// CreateService creates a swarm service given the specified service constructor
|
||||
func (d *Swarm) CreateService(c *check.C, f ...ServiceConstructor) string {
|
||||
return d.CreateServiceWithOptions(c, types.ServiceCreateOptions{}, f...)
|
||||
}
|
||||
|
||||
// GetService returns the swarm service corresponding to the specified id
|
||||
func (d *Swarm) GetService(c *check.C, id string) *swarm.Service {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
return &service
|
||||
}
|
||||
|
||||
// GetServiceTasks returns the swarm tasks for the specified service
|
||||
func (d *Swarm) GetServiceTasks(c *check.C, service string) []swarm.Task {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("desired-state", "running")
|
||||
filterArgs.Add("service", service)
|
||||
|
||||
options := types.TaskListOptions{
|
||||
Filters: filterArgs,
|
||||
}
|
||||
|
||||
tasks, err := cli.TaskList(context.Background(), options)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return tasks
|
||||
}
|
||||
|
||||
// CheckServiceTasksInState returns the number of tasks with a matching state,
|
||||
// and optional message substring.
|
||||
func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
tasks := d.GetServiceTasks(c, service)
|
||||
var count int
|
||||
|
@ -200,7 +33,7 @@ func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState,
|
|||
|
||||
// CheckServiceTasksInStateWithError returns the number of tasks with a matching state,
|
||||
// and optional message substring.
|
||||
func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
tasks := d.GetServiceTasks(c, service)
|
||||
var count int
|
||||
|
@ -216,12 +49,12 @@ func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.Ta
|
|||
}
|
||||
|
||||
// CheckServiceRunningTasks returns the number of running tasks for the specified service
|
||||
func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")
|
||||
}
|
||||
|
||||
// CheckServiceUpdateState returns the current update state for the specified service
|
||||
func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
service := d.GetService(c, service)
|
||||
if service.UpdateStatus == nil {
|
||||
|
@ -232,7 +65,7 @@ func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interfac
|
|||
}
|
||||
|
||||
// CheckPluginRunning returns the runtime state of the plugin
|
||||
func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
apiclient, err := d.NewClient()
|
||||
assert.NilError(c, err)
|
||||
|
@ -246,7 +79,7 @@ func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{},
|
|||
}
|
||||
|
||||
// CheckPluginImage returns the runtime state of the plugin
|
||||
func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
apiclient, err := d.NewClient()
|
||||
assert.NilError(c, err)
|
||||
|
@ -260,7 +93,7 @@ func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, c
|
|||
}
|
||||
|
||||
// CheckServiceTasks returns the number of tasks for the specified service
|
||||
func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckServiceTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
tasks := d.GetServiceTasks(c, service)
|
||||
return len(tasks), nil
|
||||
|
@ -268,7 +101,7 @@ func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, c
|
|||
}
|
||||
|
||||
// CheckRunningTaskNetworks returns the number of times each network is referenced from a task.
|
||||
func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
@ -293,7 +126,7 @@ func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.Comment
|
|||
}
|
||||
|
||||
// CheckRunningTaskImages returns the times each image is running as a task.
|
||||
func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
@ -318,7 +151,7 @@ func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentIn
|
|||
}
|
||||
|
||||
// CheckNodeReadyCount returns the number of ready node on the swarm
|
||||
func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) {
|
||||
nodes := d.ListNodes(c)
|
||||
var readyCount int
|
||||
for _, node := range nodes {
|
||||
|
@ -329,303 +162,21 @@ func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInter
|
|||
return readyCount, nil
|
||||
}
|
||||
|
||||
// GetTask returns the swarm task identified by the specified id
|
||||
func (d *Swarm) GetTask(c *check.C, id string) swarm.Task {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
task, _, err := cli.TaskInspectWithRaw(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return task
|
||||
}
|
||||
|
||||
// UpdateService updates a swarm service with the specified service constructor
|
||||
func (d *Swarm) UpdateService(c *check.C, service *swarm.Service, f ...ServiceConstructor) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
for _, fn := range f {
|
||||
fn(service)
|
||||
}
|
||||
|
||||
_, err = cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// RemoveService removes the specified service
|
||||
func (d *Swarm) RemoveService(c *check.C, id string) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
err = cli.ServiceRemove(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// GetNode returns a swarm node identified by the specified id
|
||||
func (d *Swarm) GetNode(c *check.C, id string) *swarm.Node {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
node, _, err := cli.NodeInspectWithRaw(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(node.ID, checker.Equals, id)
|
||||
return &node
|
||||
}
|
||||
|
||||
// RemoveNode removes the specified node
|
||||
func (d *Swarm) RemoveNode(c *check.C, id string, force bool) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
options := types.NodeRemoveOptions{
|
||||
Force: force,
|
||||
}
|
||||
err = cli.NodeRemove(context.Background(), id, options)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// UpdateNode updates a swarm node with the specified node constructor
|
||||
func (d *Swarm) UpdateNode(c *check.C, id string, f ...NodeConstructor) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
for i := 0; ; i++ {
|
||||
node := d.GetNode(c, id)
|
||||
for _, fn := range f {
|
||||
fn(node)
|
||||
}
|
||||
|
||||
err = cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec)
|
||||
if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ListNodes returns the list of the current swarm nodes
|
||||
func (d *Swarm) ListNodes(c *check.C) []swarm.Node {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
return nodes
|
||||
}
|
||||
|
||||
// ListServices returns the list of the current swarm services
|
||||
func (d *Swarm) ListServices(c *check.C) []swarm.Service {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
return services
|
||||
}
|
||||
|
||||
// CreateSecret creates a secret given the specified spec
|
||||
func (d *Swarm) CreateSecret(c *check.C, secretSpec swarm.SecretSpec) string {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
scr, err := cli.SecretCreate(context.Background(), secretSpec)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
return scr.ID
|
||||
}
|
||||
|
||||
// ListSecrets returns the list of the current swarm secrets
|
||||
func (d *Swarm) ListSecrets(c *check.C) []swarm.Secret {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
return secrets
|
||||
}
|
||||
|
||||
// GetSecret returns a swarm secret identified by the specified id
|
||||
func (d *Swarm) GetSecret(c *check.C, id string) *swarm.Secret {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
secret, _, err := cli.SecretInspectWithRaw(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return &secret
|
||||
}
|
||||
|
||||
// DeleteSecret removes the swarm secret identified by the specified id
|
||||
func (d *Swarm) DeleteSecret(c *check.C, id string) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
err = cli.SecretRemove(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// UpdateSecret updates the swarm secret identified by the specified id
|
||||
// Currently, only label update is supported.
|
||||
func (d *Swarm) UpdateSecret(c *check.C, id string, f ...SecretConstructor) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
secret := d.GetSecret(c, id)
|
||||
for _, fn := range f {
|
||||
fn(secret)
|
||||
}
|
||||
|
||||
err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
|
||||
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// CreateConfig creates a config given the specified spec
|
||||
func (d *Swarm) CreateConfig(c *check.C, configSpec swarm.ConfigSpec) string {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
scr, err := cli.ConfigCreate(context.Background(), configSpec)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return scr.ID
|
||||
}
|
||||
|
||||
// ListConfigs returns the list of the current swarm configs
|
||||
func (d *Swarm) ListConfigs(c *check.C) []swarm.Config {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
return configs
|
||||
}
|
||||
|
||||
// GetConfig returns a swarm config identified by the specified id
|
||||
func (d *Swarm) GetConfig(c *check.C, id string) *swarm.Config {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
config, _, err := cli.ConfigInspectWithRaw(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
return &config
|
||||
}
|
||||
|
||||
// DeleteConfig removes the swarm config identified by the specified id
|
||||
func (d *Swarm) DeleteConfig(c *check.C, id string) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
err = cli.ConfigRemove(context.Background(), id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// UpdateConfig updates the swarm config identified by the specified id
|
||||
// Currently, only label update is supported.
|
||||
func (d *Swarm) UpdateConfig(c *check.C, id string, f ...ConfigConstructor) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
config := d.GetConfig(c, id)
|
||||
for _, fn := range f {
|
||||
fn(config)
|
||||
}
|
||||
|
||||
err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// GetSwarm returns the current swarm object
|
||||
func (d *Swarm) GetSwarm(c *check.C) swarm.Swarm {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
sw, err := cli.SwarmInspect(context.Background())
|
||||
c.Assert(err, checker.IsNil)
|
||||
return sw
|
||||
}
|
||||
|
||||
// UpdateSwarm updates the current swarm object with the specified spec constructors
|
||||
func (d *Swarm) UpdateSwarm(c *check.C, f ...SpecConstructor) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
sw := d.GetSwarm(c)
|
||||
for _, fn := range f {
|
||||
fn(&sw.Spec)
|
||||
}
|
||||
|
||||
err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{})
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// RotateTokens update the swarm to rotate tokens
|
||||
func (d *Swarm) RotateTokens(c *check.C) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
sw, err := cli.SwarmInspect(context.Background())
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
flags := swarm.UpdateFlags{
|
||||
RotateManagerToken: true,
|
||||
RotateWorkerToken: true,
|
||||
}
|
||||
|
||||
err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// JoinTokens returns the current swarm join tokens
|
||||
func (d *Swarm) JoinTokens(c *check.C) swarm.JoinTokens {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
||||
sw, err := cli.SwarmInspect(context.Background())
|
||||
c.Assert(err, checker.IsNil)
|
||||
return sw.JoinTokens
|
||||
}
|
||||
|
||||
// CheckLocalNodeState returns the current swarm node state
|
||||
func (d *Swarm) CheckLocalNodeState(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
func (d *Daemon) CheckLocalNodeState(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info := d.SwarmInfo(c)
|
||||
return info.LocalNodeState, nil
|
||||
}
|
||||
|
||||
// CheckControlAvailable returns the current swarm control available
|
||||
func (d *Swarm) CheckControlAvailable(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
func (d *Daemon) CheckControlAvailable(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info := d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
return info.ControlAvailable, nil
|
||||
}
|
||||
|
||||
// CheckLeader returns whether there is a leader on the swarm or not
|
||||
func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
|
||||
func (d *Daemon) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
|
||||
cli, err := d.NewClient()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cli.Close()
|
||||
|
@ -644,18 +195,3 @@ func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
|
|||
}
|
||||
return fmt.Errorf("no leader"), check.Commentf("could not find leader")
|
||||
}
|
||||
|
||||
// CmdRetryOutOfSequence tries the specified command against the current daemon for 10 times
|
||||
func (d *Swarm) CmdRetryOutOfSequence(args ...string) (string, error) {
|
||||
for i := 0; ; i++ {
|
||||
out, err := d.Cmd(args...)
|
||||
if err != nil {
|
||||
if strings.Contains(out, "update out of sequence") {
|
||||
if i < 10 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func (s *DockerSwarmSuite) getDaemon(c *check.C, nodeID string) *daemon.Swarm {
|
||||
func (s *DockerSwarmSuite) getDaemon(c *check.C, nodeID string) *daemon.Daemon {
|
||||
s.daemonsLock.Lock()
|
||||
defer s.daemonsLock.Unlock()
|
||||
for _, d := range s.daemons {
|
||||
if d.NodeID == nodeID {
|
||||
if d.NodeID() == nodeID {
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ func (s *DockerSwarmSuite) TestAPISwarmListNodes(c *check.C) {
|
|||
|
||||
loop0:
|
||||
for _, n := range nodes {
|
||||
for _, d := range []*daemon.Swarm{d1, d2, d3} {
|
||||
if n.ID == d.NodeID {
|
||||
for _, d := range []*daemon.Daemon{d1, d2, d3} {
|
||||
if n.ID == d.NodeID() {
|
||||
continue loop0
|
||||
}
|
||||
}
|
||||
|
@ -53,8 +53,7 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeRemove(c *check.C) {
|
|||
c.Assert(len(nodes), checker.Equals, 3, check.Commentf("nodes: %#v", nodes))
|
||||
|
||||
// Getting the info so we can take the NodeID
|
||||
d2Info, err := d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
d2Info := d2.SwarmInfo(c)
|
||||
|
||||
// forceful removal of d2 should work
|
||||
d1.RemoveNode(c, d2Info.NodeID, true)
|
||||
|
@ -88,14 +87,14 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *check.C) {
|
|||
waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
|
||||
|
||||
// drain d2, all containers should move to d1
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Availability = swarm.NodeAvailabilityDrain
|
||||
})
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 0)
|
||||
|
||||
// set d2 back to active
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Availability = swarm.NodeAvailabilityActive
|
||||
})
|
||||
|
||||
|
@ -115,7 +114,7 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *check.C) {
|
|||
d2ContainerCount := len(d2.ActiveContainers())
|
||||
|
||||
// set d2 to paused, scale service up, only d1 gets new tasks
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Availability = swarm.NodeAvailabilityPause
|
||||
})
|
||||
|
||||
|
|
|
@ -15,12 +15,13 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
testdaemon "github.com/docker/docker/internal/test/daemon"
|
||||
"github.com/go-check/check"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func setPortConfig(portConfig []swarm.PortConfig) daemon.ServiceConstructor {
|
||||
func setPortConfig(portConfig []swarm.PortConfig) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.EndpointSpec == nil {
|
||||
s.Spec.EndpointSpec = &swarm.EndpointSpec{}
|
||||
|
@ -140,7 +141,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesCreateGlobal(c *check.C) {
|
|||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmServicesUpdate(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*daemon.Swarm
|
||||
var daemons [nodeCount]*daemon.Daemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
|
@ -309,7 +310,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateStartFirst(c *check.C) {
|
|||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*daemon.Swarm
|
||||
var daemons [nodeCount]*daemon.Daemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
|
@ -349,7 +350,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) {
|
|||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintRole(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*daemon.Swarm
|
||||
var daemons [nodeCount]*daemon.Daemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
|
@ -401,7 +402,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintRole(c *check.C) {
|
|||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintLabel(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*daemon.Swarm
|
||||
var daemons [nodeCount]*daemon.Daemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
|
@ -496,7 +497,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintLabel(c *check.C) {
|
|||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmServicePlacementPrefs(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*daemon.Swarm
|
||||
var daemons [nodeCount]*daemon.Daemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
|
@ -551,9 +552,9 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesStateReporting(c *check.C) {
|
|||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
|
||||
|
||||
getContainers := func() map[string]*daemon.Swarm {
|
||||
m := make(map[string]*daemon.Swarm)
|
||||
for _, d := range []*daemon.Swarm{d1, d2, d3} {
|
||||
getContainers := func() map[string]*daemon.Daemon {
|
||||
m := make(map[string]*daemon.Daemon)
|
||||
for _, d := range []*daemon.Daemon{d1, d2, d3} {
|
||||
for _, id := range d.ActiveContainers() {
|
||||
m[id] = d
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
testdaemon "github.com/docker/docker/internal/test/daemon"
|
||||
"github.com/docker/swarmkit/ca"
|
||||
"github.com/go-check/check"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
|
@ -35,30 +36,30 @@ var defaultReconciliationTimeout = 30 * time.Second
|
|||
func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) {
|
||||
// todo: should find a better way to verify that components are running than /info
|
||||
d1 := s.AddDaemon(c, true, true)
|
||||
info, err := d1.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d1.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.True)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(info.Cluster.RootRotationInProgress, checker.False)
|
||||
|
||||
d2 := s.AddDaemon(c, true, false)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
// Leaving cluster
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
c.Assert(d2.SwarmLeave(false), checker.IsNil)
|
||||
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: d1.JoinTokens(c).Worker, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
|
||||
d2.SwarmJoin(c, swarm.JoinRequest{
|
||||
ListenAddr: d1.SwarmListenAddr(),
|
||||
JoinToken: d1.JoinTokens(c).Worker,
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
|
@ -69,93 +70,100 @@ func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) {
|
|||
d1.Start(c)
|
||||
d2.Start(c)
|
||||
|
||||
info, err = d1.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d1.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.True)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmJoinToken(c *check.C) {
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
|
||||
d1.SwarmInit(c, swarm.InitRequest{})
|
||||
|
||||
// todo: error message differs depending if some components of token are valid
|
||||
|
||||
d2 := s.AddDaemon(c, false, false)
|
||||
err := d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}})
|
||||
c2 := d2.NewClientT(c)
|
||||
err := c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err := d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{JoinToken: "foobaz", RemoteAddrs: []string{d1.ListenAddr}})
|
||||
err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
JoinToken: "foobaz",
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "invalid join token")
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
workerToken := d1.JoinTokens(c).Worker
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
d2.SwarmJoin(c, swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
JoinToken: workerToken,
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(d2.SwarmLeave(false), checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
// change tokens
|
||||
d1.RotateTokens(c)
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}})
|
||||
err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
JoinToken: workerToken,
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
workerToken = d1.JoinTokens(c).Worker
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
d2.SwarmJoin(c, swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.SwarmListenAddr()}})
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(d2.SwarmLeave(false), checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
// change spec, don't change tokens
|
||||
d1.UpdateSwarm(c, func(s *swarm.Spec) {})
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}})
|
||||
err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "join token is necessary")
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
d2.SwarmJoin(c, swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.SwarmListenAddr()}})
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(d2.Leave(false), checker.IsNil)
|
||||
info, err = d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(d2.SwarmLeave(false), checker.IsNil)
|
||||
info = d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestUpdateSwarmAddExternalCA(c *check.C) {
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
|
||||
d1.SwarmInit(c, swarm.InitRequest{})
|
||||
d1.UpdateSwarm(c, func(s *swarm.Spec) {
|
||||
s.CAConfig.ExternalCAs = []*swarm.ExternalCA{
|
||||
{
|
||||
|
@ -169,8 +177,7 @@ func (s *DockerSwarmSuite) TestUpdateSwarmAddExternalCA(c *check.C) {
|
|||
},
|
||||
}
|
||||
})
|
||||
info, err := d1.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d1.SwarmInfo(c)
|
||||
c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs, checker.HasLen, 2)
|
||||
c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "")
|
||||
c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, "cacert")
|
||||
|
@ -182,28 +189,32 @@ func (s *DockerSwarmSuite) TestAPISwarmCAHash(c *check.C) {
|
|||
splitToken := strings.Split(d1.JoinTokens(c).Worker, "-")
|
||||
splitToken[2] = "1kxftv4ofnc6mt30lmgipg6ngf9luhwqopfk1tz6bdmnkubg0e"
|
||||
replacementToken := strings.Join(splitToken, "-")
|
||||
err := d2.Join(swarm.JoinRequest{JoinToken: replacementToken, RemoteAddrs: []string{d1.ListenAddr}})
|
||||
c2 := d2.NewClientT(c)
|
||||
err := c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
JoinToken: replacementToken,
|
||||
RemoteAddrs: []string{d1.SwarmListenAddr()},
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "remote CA does not match fingerprint")
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
|
||||
d1.SwarmInit(c, swarm.InitRequest{})
|
||||
d2 := s.AddDaemon(c, true, false)
|
||||
|
||||
info, err := d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d2.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Role = swarm.NodeRoleManager
|
||||
})
|
||||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.True)
|
||||
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Role = swarm.NodeRoleWorker
|
||||
})
|
||||
|
||||
|
@ -228,7 +239,7 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
|
|||
}, checker.Equals, "swarm-worker")
|
||||
|
||||
// Demoting last node should fail
|
||||
node := d1.GetNode(c, d1.NodeID)
|
||||
node := d1.GetNode(c, d1.NodeID())
|
||||
node.Spec.Role = swarm.NodeRoleWorker
|
||||
url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
|
||||
res, body, err := request.DoOnHost(d1.Sock(), url, request.Method("POST"), request.JSONBody(node.Spec))
|
||||
|
@ -246,13 +257,12 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
|
|||
if !strings.Contains(string(b), "last manager of the swarm") {
|
||||
c.Assert(string(b), checker.Contains, "this would result in a loss of quorum")
|
||||
}
|
||||
info, err = d1.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d1.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
c.Assert(info.ControlAvailable, checker.True)
|
||||
|
||||
// Promote already demoted node
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Role = swarm.NodeRoleManager
|
||||
})
|
||||
|
||||
|
@ -278,7 +288,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderProxy(c *check.C) {
|
|||
|
||||
// 3 services should be started now, because the requests were proxied to leader
|
||||
// query each node and make sure it returns 3 services
|
||||
for _, d := range []*daemon.Swarm{d1, d2, d3} {
|
||||
for _, d := range []*daemon.Daemon{d1, d2, d3} {
|
||||
services := d.ListServices(c)
|
||||
c.Assert(services, checker.HasLen, 3)
|
||||
}
|
||||
|
@ -291,23 +301,23 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) {
|
|||
d3 := s.AddDaemon(c, true, true)
|
||||
|
||||
// assert that the first node we made is the leader, and the other two are followers
|
||||
c.Assert(d1.GetNode(c, d1.NodeID).ManagerStatus.Leader, checker.True)
|
||||
c.Assert(d1.GetNode(c, d2.NodeID).ManagerStatus.Leader, checker.False)
|
||||
c.Assert(d1.GetNode(c, d3.NodeID).ManagerStatus.Leader, checker.False)
|
||||
c.Assert(d1.GetNode(c, d1.NodeID()).ManagerStatus.Leader, checker.True)
|
||||
c.Assert(d1.GetNode(c, d2.NodeID()).ManagerStatus.Leader, checker.False)
|
||||
c.Assert(d1.GetNode(c, d3.NodeID()).ManagerStatus.Leader, checker.False)
|
||||
|
||||
d1.Stop(c)
|
||||
|
||||
var (
|
||||
leader *daemon.Swarm // keep track of leader
|
||||
followers []*daemon.Swarm // keep track of followers
|
||||
leader *daemon.Daemon // keep track of leader
|
||||
followers []*daemon.Daemon // keep track of followers
|
||||
)
|
||||
checkLeader := func(nodes ...*daemon.Swarm) checkF {
|
||||
checkLeader := func(nodes ...*daemon.Daemon) checkF {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
// clear these out before each run
|
||||
leader = nil
|
||||
followers = nil
|
||||
for _, d := range nodes {
|
||||
if d.GetNode(c, d.NodeID).ManagerStatus.Leader {
|
||||
if d.GetNode(c, d.NodeID()).ManagerStatus.Leader {
|
||||
leader = d
|
||||
} else {
|
||||
followers = append(followers, d)
|
||||
|
@ -344,7 +354,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) {
|
|||
c.Assert(leader, checker.NotNil)
|
||||
c.Assert(followers, checker.HasLen, 2)
|
||||
// and that after we added d1 back, the leader hasn't changed
|
||||
c.Assert(leader.NodeID, checker.Equals, stableleader.NodeID)
|
||||
c.Assert(leader.NodeID(), checker.Equals, stableleader.NodeID())
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestAPISwarmRaftQuorum(c *check.C) {
|
||||
|
@ -400,8 +410,8 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveRemovesContainer(c *check.C) {
|
|||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances+1)
|
||||
|
||||
c.Assert(d.Leave(false), checker.NotNil)
|
||||
c.Assert(d.Leave(true), checker.IsNil)
|
||||
c.Assert(d.SwarmLeave(false), checker.NotNil)
|
||||
c.Assert(d.SwarmLeave(true), checker.IsNil)
|
||||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
|
||||
|
||||
|
@ -420,17 +430,18 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveOnPendingJoin(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
id = strings.TrimSpace(id)
|
||||
|
||||
err = d2.Join(swarm.JoinRequest{
|
||||
c2 := d2.NewClientT(c)
|
||||
err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d2.SwarmListenAddr(),
|
||||
RemoteAddrs: []string{"123.123.123.123:1234"},
|
||||
})
|
||||
c.Assert(err, check.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "Timeout was reached")
|
||||
|
||||
info, err := d2.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d2.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
|
||||
|
||||
c.Assert(d2.Leave(true), checker.IsNil)
|
||||
c.Assert(d2.SwarmLeave(true), checker.IsNil)
|
||||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 1)
|
||||
|
||||
|
@ -443,7 +454,9 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveOnPendingJoin(c *check.C) {
|
|||
func (s *DockerSwarmSuite) TestAPISwarmRestoreOnPendingJoin(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
d := s.AddDaemon(c, false, false)
|
||||
err := d.Join(swarm.JoinRequest{
|
||||
client := d.NewClientT(c)
|
||||
err := client.SwarmJoin(context.Background(), swarm.JoinRequest{
|
||||
ListenAddr: d.SwarmListenAddr(),
|
||||
RemoteAddrs: []string{"123.123.123.123:1234"},
|
||||
})
|
||||
c.Assert(err, check.NotNil)
|
||||
|
@ -454,8 +467,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestoreOnPendingJoin(c *check.C) {
|
|||
d.Stop(c)
|
||||
d.Start(c)
|
||||
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
}
|
||||
|
||||
|
@ -539,7 +551,7 @@ func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) {
|
|||
waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
|
||||
|
||||
// drain d2, all containers should move to d1
|
||||
d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
|
||||
d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) {
|
||||
n.Spec.Availability = swarm.NodeAvailabilityDrain
|
||||
})
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
|
||||
|
@ -547,16 +559,15 @@ func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) {
|
|||
|
||||
d2.Stop(c)
|
||||
|
||||
c.Assert(d1.Init(swarm.InitRequest{
|
||||
d1.SwarmInit(c, swarm.InitRequest{
|
||||
ForceNewCluster: true,
|
||||
Spec: swarm.Spec{},
|
||||
}), checker.IsNil)
|
||||
})
|
||||
|
||||
waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
|
||||
|
||||
d3 := s.AddDaemon(c, true, true)
|
||||
info, err := d3.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d3.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.True)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
|
@ -622,7 +633,7 @@ func serviceForUpdate(s *swarm.Service) {
|
|||
s.Spec.Name = "updatetest"
|
||||
}
|
||||
|
||||
func setInstances(replicas int) daemon.ServiceConstructor {
|
||||
func setInstances(replicas int) testdaemon.ServiceConstructor {
|
||||
ureplicas := uint64(replicas)
|
||||
return func(s *swarm.Service) {
|
||||
s.Spec.Mode = swarm.ServiceMode{
|
||||
|
@ -633,7 +644,7 @@ func setInstances(replicas int) daemon.ServiceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setUpdateOrder(order string) daemon.ServiceConstructor {
|
||||
func setUpdateOrder(order string) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.UpdateConfig == nil {
|
||||
s.Spec.UpdateConfig = &swarm.UpdateConfig{}
|
||||
|
@ -642,7 +653,7 @@ func setUpdateOrder(order string) daemon.ServiceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setRollbackOrder(order string) daemon.ServiceConstructor {
|
||||
func setRollbackOrder(order string) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.RollbackConfig == nil {
|
||||
s.Spec.RollbackConfig = &swarm.UpdateConfig{}
|
||||
|
@ -651,7 +662,7 @@ func setRollbackOrder(order string) daemon.ServiceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setImage(image string) daemon.ServiceConstructor {
|
||||
func setImage(image string) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.TaskTemplate.ContainerSpec == nil {
|
||||
s.Spec.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{}
|
||||
|
@ -660,25 +671,25 @@ func setImage(image string) daemon.ServiceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setFailureAction(failureAction string) daemon.ServiceConstructor {
|
||||
func setFailureAction(failureAction string) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
s.Spec.UpdateConfig.FailureAction = failureAction
|
||||
}
|
||||
}
|
||||
|
||||
func setMaxFailureRatio(maxFailureRatio float32) daemon.ServiceConstructor {
|
||||
func setMaxFailureRatio(maxFailureRatio float32) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
s.Spec.UpdateConfig.MaxFailureRatio = maxFailureRatio
|
||||
}
|
||||
}
|
||||
|
||||
func setParallelism(parallelism uint64) daemon.ServiceConstructor {
|
||||
func setParallelism(parallelism uint64) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
s.Spec.UpdateConfig.Parallelism = parallelism
|
||||
}
|
||||
}
|
||||
|
||||
func setConstraints(constraints []string) daemon.ServiceConstructor {
|
||||
func setConstraints(constraints []string) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.TaskTemplate.Placement == nil {
|
||||
s.Spec.TaskTemplate.Placement = &swarm.Placement{}
|
||||
|
@ -687,7 +698,7 @@ func setConstraints(constraints []string) daemon.ServiceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setPlacementPrefs(prefs []swarm.PlacementPreference) daemon.ServiceConstructor {
|
||||
func setPlacementPrefs(prefs []swarm.PlacementPreference) testdaemon.ServiceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
if s.Spec.TaskTemplate.Placement == nil {
|
||||
s.Spec.TaskTemplate.Placement = &swarm.Placement{}
|
||||
|
@ -702,18 +713,19 @@ func setGlobalMode(s *swarm.Service) {
|
|||
}
|
||||
}
|
||||
|
||||
func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCount int) {
|
||||
func checkClusterHealth(c *check.C, cl []*daemon.Daemon, managerCount, workerCount int) {
|
||||
var totalMCount, totalWCount int
|
||||
|
||||
for _, d := range cl {
|
||||
var (
|
||||
info swarm.Info
|
||||
err error
|
||||
)
|
||||
|
||||
// check info in a waitAndAssert, because if the cluster doesn't have a leader, `info` will return an error
|
||||
checkInfo := func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
info, err = d.SwarmInfo()
|
||||
client := d.NewClientT(c)
|
||||
daemonInfo, err := client.Info(context.Background())
|
||||
info = daemonInfo.Swarm
|
||||
return err, check.Commentf("cluster not ready in time")
|
||||
}
|
||||
waitAndAssert(c, defaultReconciliationTimeout, checkInfo, checker.IsNil)
|
||||
|
@ -733,7 +745,7 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun
|
|||
}
|
||||
nn := d.GetNode(c, n.ID)
|
||||
n = *nn
|
||||
return n.Status.State == swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.Info.NodeID)
|
||||
return n.Status.State == swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.NodeID())
|
||||
}
|
||||
waitAndAssert(c, defaultReconciliationTimeout, waitReady, checker.True)
|
||||
|
||||
|
@ -743,18 +755,18 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun
|
|||
}
|
||||
nn := d.GetNode(c, n.ID)
|
||||
n = *nn
|
||||
return n.Spec.Availability == swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.Info.NodeID)
|
||||
return n.Spec.Availability == swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.NodeID())
|
||||
}
|
||||
waitAndAssert(c, defaultReconciliationTimeout, waitActive, checker.True)
|
||||
|
||||
if n.Spec.Role == swarm.NodeRoleManager {
|
||||
c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.Info.NodeID))
|
||||
c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.NodeID()))
|
||||
if n.ManagerStatus.Leader {
|
||||
leaderFound = true
|
||||
}
|
||||
mCount++
|
||||
} else {
|
||||
c.Assert(n.ManagerStatus, checker.IsNil, check.Commentf("manager status of node %s (worker), reported by %s", n.ID, d.Info.NodeID))
|
||||
c.Assert(n.ManagerStatus, checker.IsNil, check.Commentf("manager status of node %s (worker), reported by %s", n.ID, d.NodeID()))
|
||||
wCount++
|
||||
}
|
||||
}
|
||||
|
@ -769,11 +781,10 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun
|
|||
func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) {
|
||||
mCount, wCount := 5, 1
|
||||
|
||||
var nodes []*daemon.Swarm
|
||||
var nodes []*daemon.Daemon
|
||||
for i := 0; i < mCount; i++ {
|
||||
manager := s.AddDaemon(c, true, true)
|
||||
info, err := manager.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := manager.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.True)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
nodes = append(nodes, manager)
|
||||
|
@ -781,8 +792,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) {
|
|||
|
||||
for i := 0; i < wCount; i++ {
|
||||
worker := s.AddDaemon(c, true, false)
|
||||
info, err := worker.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := worker.SwarmInfo(c)
|
||||
c.Assert(info.ControlAvailable, checker.False)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
nodes = append(nodes, worker)
|
||||
|
@ -795,7 +805,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) {
|
|||
errs := make(chan error, len(nodes))
|
||||
|
||||
for _, d := range nodes {
|
||||
go func(daemon *daemon.Swarm) {
|
||||
go func(daemon *daemon.Daemon) {
|
||||
defer wg.Done()
|
||||
if err := daemon.StopWithError(); err != nil {
|
||||
errs <- err
|
||||
|
@ -820,7 +830,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) {
|
|||
errs := make(chan error, len(nodes))
|
||||
|
||||
for _, d := range nodes {
|
||||
go func(daemon *daemon.Swarm) {
|
||||
go func(daemon *daemon.Daemon) {
|
||||
defer wg.Done()
|
||||
if err := daemon.StartWithError("--iptables=false"); err != nil {
|
||||
errs <- err
|
||||
|
@ -859,7 +869,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateWithName(c *check.C) {
|
|||
// Unlocking an unlocked swarm results in an error
|
||||
func (s *DockerSwarmSuite) TestAPISwarmUnlockNotLocked(c *check.C) {
|
||||
d := s.AddDaemon(c, true, true)
|
||||
err := d.Unlock(swarm.UnlockRequest{UnlockKey: "wrong-key"})
|
||||
err := d.SwarmUnlock(swarm.UnlockRequest{UnlockKey: "wrong-key"})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "swarm is not locked")
|
||||
}
|
||||
|
@ -870,7 +880,10 @@ func (s *DockerSwarmSuite) TestAPISwarmErrorHandling(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
defer ln.Close()
|
||||
d := s.AddDaemon(c, false, false)
|
||||
err = d.Init(swarm.InitRequest{})
|
||||
client := d.NewClientT(c)
|
||||
_, err = client.SwarmInit(context.Background(), swarm.InitRequest{
|
||||
ListenAddr: d.SwarmListenAddr(),
|
||||
})
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(err.Error(), checker.Contains, "address already in use")
|
||||
}
|
||||
|
@ -940,13 +953,13 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
|
|||
m := s.AddDaemon(c, true, true)
|
||||
w := s.AddDaemon(c, true, false)
|
||||
|
||||
info, err := m.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := m.SwarmInfo(c)
|
||||
|
||||
currentTrustRoot := info.Cluster.TLSInfo.TrustRoot
|
||||
|
||||
// rotate multiple times
|
||||
for i := 0; i < 4; i++ {
|
||||
var err error
|
||||
var cert, key []byte
|
||||
if i%2 != 0 {
|
||||
cert, _, key, err = initca.New(&csr.CertificateRequest{
|
||||
|
@ -966,8 +979,7 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
|
|||
// poll to make sure update succeeds
|
||||
var clusterTLSInfo swarm.TLSInfo
|
||||
for j := 0; j < 18; j++ {
|
||||
info, err := m.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := m.SwarmInfo(c)
|
||||
|
||||
// the desired CA cert and key is always redacted
|
||||
c.Assert(info.Cluster.Spec.CAConfig.SigningCAKey, checker.Equals, "")
|
||||
|
@ -989,8 +1001,8 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
|
|||
// could take another second or two for the nodes to trust the new roots after they've all gotten
|
||||
// new TLS certificates
|
||||
for j := 0; j < 18; j++ {
|
||||
mInfo := m.GetNode(c, m.NodeID).Description.TLSInfo
|
||||
wInfo := m.GetNode(c, w.NodeID).Description.TLSInfo
|
||||
mInfo := m.GetNode(c, m.NodeID()).Description.TLSInfo
|
||||
wInfo := m.GetNode(c, w.NodeID()).Description.TLSInfo
|
||||
|
||||
if mInfo.TrustRoot == clusterTLSInfo.TrustRoot && wInfo.TrustRoot == clusterTLSInfo.TrustRoot {
|
||||
break
|
||||
|
@ -1000,8 +1012,8 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
|
|||
time.Sleep(250 * time.Millisecond)
|
||||
}
|
||||
|
||||
c.Assert(m.GetNode(c, m.NodeID).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo)
|
||||
c.Assert(m.GetNode(c, w.NodeID).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo)
|
||||
c.Assert(m.GetNode(c, m.NodeID()).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo)
|
||||
c.Assert(m.GetNode(c, w.NodeID()).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo)
|
||||
currentTrustRoot = clusterTLSInfo.TrustRoot
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func pruneNetworkAndVerify(c *check.C, d *daemon.Swarm, kept, pruned []string) {
|
||||
func pruneNetworkAndVerify(c *check.C, d *daemon.Daemon, kept, pruned []string) {
|
||||
_, err := d.Cmd("network", "prune", "--force")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ func (s *DockerSwarmSuite) TestServiceLogs(c *check.C) {
|
|||
// countLogLines returns a closure that can be used with waitAndAssert to
|
||||
// verify that a minimum number of expected container log messages have been
|
||||
// output.
|
||||
func countLogLines(d *daemon.Swarm, name string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func countLogLines(d *daemon.Daemon, name string) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
result := icmd.RunCmd(d.Command("service", "logs", "-t", "--raw", name))
|
||||
result.Assert(c, icmd.Expected{})
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) {
|
|||
// passing an external CA (this is without starting a root rotation) does not fail
|
||||
cli.Docker(cli.Args("swarm", "update", "--external-ca", "protocol=cfssl,url=https://something.org",
|
||||
"--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"),
|
||||
cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
|
||||
cli.Daemon(d)).Assert(c, icmd.Success)
|
||||
|
||||
expected, err := ioutil.ReadFile("fixtures/https/ca.pem")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -73,7 +73,7 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) {
|
|||
|
||||
result := cli.Docker(cli.Args("swarm", "update",
|
||||
"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://something.org,cacert=%s", tempFile.Path())),
|
||||
cli.Daemon(d.Daemon))
|
||||
cli.Daemon(d))
|
||||
result.Assert(c, icmd.Expected{
|
||||
ExitCode: 125,
|
||||
Err: "must be in PEM format",
|
||||
|
@ -94,7 +94,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
|
|||
|
||||
result := cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s",
|
||||
"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://somethingelse.org,cacert=%s", tempFile.Path())),
|
||||
cli.Daemon(d.Daemon))
|
||||
cli.Daemon(d))
|
||||
result.Assert(c, icmd.Expected{
|
||||
ExitCode: 125,
|
||||
Err: "must be in PEM format",
|
||||
|
@ -103,7 +103,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
|
|||
cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s",
|
||||
"--external-ca", "protocol=cfssl,url=https://something.org",
|
||||
"--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"),
|
||||
cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
|
||||
cli.Daemon(d)).Assert(c, icmd.Success)
|
||||
|
||||
expected, err := ioutil.ReadFile("fixtures/https/ca.pem")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -115,8 +115,8 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
|
|||
c.Assert(spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "")
|
||||
c.Assert(spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, string(expected))
|
||||
|
||||
c.Assert(d.Leave(true), checker.IsNil)
|
||||
cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
|
||||
c.Assert(d.SwarmLeave(true), checker.IsNil)
|
||||
cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d)).Assert(c, icmd.Success)
|
||||
|
||||
spec = getSpec()
|
||||
c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour)
|
||||
|
@ -126,12 +126,12 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) {
|
|||
func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) {
|
||||
testRequires(c, IPv6)
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1.Daemon)).Assert(c, icmd.Success)
|
||||
cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1)).Assert(c, icmd.Success)
|
||||
|
||||
d2 := s.AddDaemon(c, false, false)
|
||||
cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success)
|
||||
cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2)).Assert(c, icmd.Success)
|
||||
|
||||
out := cli.Docker(cli.Args("info"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success).Combined()
|
||||
out := cli.Docker(cli.Args("info"), cli.Daemon(d2)).Assert(c, icmd.Success).Combined()
|
||||
c.Assert(out, checker.Contains, "Swarm: active")
|
||||
}
|
||||
|
||||
|
@ -145,13 +145,12 @@ func (s *DockerSwarmSuite) TestSwarmInitUnspecifiedAdvertiseAddr(c *check.C) {
|
|||
func (s *DockerSwarmSuite) TestSwarmIncompatibleDaemon(c *check.C) {
|
||||
// init swarm mode and stop a daemon
|
||||
d := s.AddDaemon(c, true, true)
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
d.Stop(c)
|
||||
|
||||
// start a daemon with --cluster-store and --cluster-advertise
|
||||
err = d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=1.1.1.1:2375")
|
||||
err := d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=1.1.1.1:2375")
|
||||
c.Assert(err, checker.NotNil)
|
||||
content, err := d.ReadLogFile()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -426,7 +425,7 @@ func (s *DockerSwarmSuite) TestOverlayAttachableOnSwarmLeave(c *check.C) {
|
|||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
// Leave the swarm
|
||||
err = d.Leave(true)
|
||||
err = d.SwarmLeave(true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Check the container is disconnected
|
||||
|
@ -989,13 +988,12 @@ func (s *DockerSwarmSuite) TestDNSConfigUpdate(c *check.C) {
|
|||
c.Assert(strings.TrimSpace(out), checker.Equals, "{[1.2.3.4] [example.com] [timeout:3]}")
|
||||
}
|
||||
|
||||
func getNodeStatus(c *check.C, d *daemon.Swarm) swarm.LocalNodeState {
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
func getNodeStatus(c *check.C, d *daemon.Daemon) swarm.LocalNodeState {
|
||||
info := d.SwarmInfo(c)
|
||||
return info.LocalNodeState
|
||||
}
|
||||
|
||||
func checkKeyIsEncrypted(d *daemon.Swarm) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
func checkKeyIsEncrypted(d *daemon.Daemon) func(*check.C) (interface{}, check.CommentInterface) {
|
||||
return func(c *check.C) (interface{}, check.CommentInterface) {
|
||||
keyBytes, err := ioutil.ReadFile(filepath.Join(d.Folder, "root", "swarm", "certificates", "swarm-node.key"))
|
||||
if err != nil {
|
||||
|
@ -1011,7 +1009,7 @@ func checkKeyIsEncrypted(d *daemon.Swarm) func(*check.C) (interface{}, check.Com
|
|||
}
|
||||
}
|
||||
|
||||
func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Swarm, unlockKey string) {
|
||||
func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Daemon, unlockKey string) {
|
||||
// Wait for the PEM file to become unencrypted
|
||||
waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, false)
|
||||
|
||||
|
@ -1019,7 +1017,7 @@ func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Swarm, unlockKey string) {
|
|||
c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive)
|
||||
}
|
||||
|
||||
func checkSwarmUnlockedToLocked(c *check.C, d *daemon.Swarm) {
|
||||
func checkSwarmUnlockedToLocked(c *check.C, d *daemon.Daemon) {
|
||||
// Wait for the PEM file to become encrypted
|
||||
waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, true)
|
||||
|
||||
|
@ -1117,8 +1115,7 @@ func (s *DockerSwarmSuite) TestSwarmLeaveLocked(c *check.C) {
|
|||
// It starts off locked
|
||||
d.Restart(c, "--swarm-default-advertise-addr=lo")
|
||||
|
||||
info, err := d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info := d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateLocked)
|
||||
|
||||
outs, _ = d.Cmd("node", "ls")
|
||||
|
@ -1132,15 +1129,13 @@ func (s *DockerSwarmSuite) TestSwarmLeaveLocked(c *check.C) {
|
|||
outs, err = d.Cmd("swarm", "leave", "--force")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs))
|
||||
|
||||
info, err = d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
|
||||
|
||||
outs, err = d.Cmd("swarm", "init")
|
||||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs))
|
||||
|
||||
info, err = d.SwarmInfo()
|
||||
c.Assert(err, checker.IsNil)
|
||||
info = d.SwarmInfo(c)
|
||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1171,7 @@ func (s *DockerSwarmSuite) TestSwarmLockUnlockCluster(c *check.C) {
|
|||
c.Assert(outs, checker.Equals, unlockKey+"\n")
|
||||
|
||||
// The ones that got the cluster update should be set to locked
|
||||
for _, d := range []*daemon.Swarm{d1, d3} {
|
||||
for _, d := range []*daemon.Daemon{d1, d3} {
|
||||
checkSwarmUnlockedToLocked(c, d)
|
||||
|
||||
cmd := d.Command("swarm", "unlock")
|
||||
|
@ -1197,7 +1192,7 @@ func (s *DockerSwarmSuite) TestSwarmLockUnlockCluster(c *check.C) {
|
|||
c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs))
|
||||
|
||||
// the ones that got the update are now set to unlocked
|
||||
for _, d := range []*daemon.Swarm{d1, d3} {
|
||||
for _, d := range []*daemon.Daemon{d1, d3} {
|
||||
checkSwarmLockedToUnlocked(c, d, unlockKey)
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1242,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) {
|
|||
c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive)
|
||||
|
||||
// promote worker
|
||||
outs, err = d1.Cmd("node", "promote", d2.Info.NodeID)
|
||||
outs, err = d1.Cmd("node", "promote", d2.NodeID())
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(outs, checker.Contains, "promoted to a manager in the swarm")
|
||||
|
||||
|
@ -1255,7 +1250,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) {
|
|||
d3 := s.AddDaemon(c, true, true)
|
||||
|
||||
// both new nodes are locked
|
||||
for _, d := range []*daemon.Swarm{d2, d3} {
|
||||
for _, d := range []*daemon.Daemon{d2, d3} {
|
||||
checkSwarmUnlockedToLocked(c, d)
|
||||
|
||||
cmd := d.Command("swarm", "unlock")
|
||||
|
@ -1265,7 +1260,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) {
|
|||
}
|
||||
|
||||
// demote manager back to worker - workers are not locked
|
||||
outs, err = d1.Cmd("node", "demote", d3.Info.NodeID)
|
||||
outs, err = d1.Cmd("node", "demote", d3.NodeID())
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(outs, checker.Contains, "demoted in the swarm")
|
||||
|
||||
|
@ -1409,7 +1404,7 @@ func (s *DockerSwarmSuite) TestSwarmClusterRotateUnlockKey(c *check.C) {
|
|||
d2.Restart(c)
|
||||
d3.Restart(c)
|
||||
|
||||
for _, d := range []*daemon.Swarm{d2, d3} {
|
||||
for _, d := range []*daemon.Daemon{d2, d3} {
|
||||
c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked)
|
||||
|
||||
outs, _ := d.Cmd("node", "ls")
|
||||
|
@ -1521,7 +1516,7 @@ func (s *DockerSwarmSuite) TestSwarmManagerAddress(c *check.C) {
|
|||
d3 := s.AddDaemon(c, true, false)
|
||||
|
||||
// Manager Addresses will always show Node 1's address
|
||||
expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.Port)
|
||||
expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.SwarmPort)
|
||||
|
||||
out, err := d1.Cmd("info")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -1641,7 +1636,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinWithDrain(c *check.C) {
|
|||
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
|
||||
out, err = d1.Cmd("swarm", "join", "--availability=drain", "--token", token, d.ListenAddr)
|
||||
out, err = d1.Cmd("swarm", "join", "--availability=drain", "--token", token, d.SwarmListenAddr())
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||
|
||||
|
@ -1835,7 +1830,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinLeave(c *check.C) {
|
|||
// Verify that back to back join/leave does not cause panics
|
||||
d1 := s.AddDaemon(c, false, false)
|
||||
for i := 0; i < 10; i++ {
|
||||
out, err = d1.Cmd("swarm", "join", "--token", token, d.ListenAddr)
|
||||
out, err = d1.Cmd("swarm", "join", "--token", token, d.SwarmListenAddr())
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||
|
||||
|
@ -1846,7 +1841,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinLeave(c *check.C) {
|
|||
|
||||
const defaultRetryCount = 10
|
||||
|
||||
func waitForEvent(c *check.C, d *daemon.Swarm, since string, filter string, event string, retry int) string {
|
||||
func waitForEvent(c *check.C, d *daemon.Daemon, since string, filter string, event string, retry int) string {
|
||||
if retry < 1 {
|
||||
c.Fatalf("retry count %d is invalid. It should be no less than 1", retry)
|
||||
return ""
|
||||
|
@ -1982,7 +1977,7 @@ func (s *DockerSwarmSuite) TestSwarmClusterEventsNode(c *check.C) {
|
|||
s.AddDaemon(c, true, true)
|
||||
d3 := s.AddDaemon(c, true, true)
|
||||
|
||||
d3ID := d3.NodeID
|
||||
d3ID := d3.NodeID()
|
||||
waitForEvent(c, d1, "0", "-f scope=swarm", "node create "+d3ID, defaultRetryCount)
|
||||
|
||||
t1 := daemonUnixTime(c)
|
||||
|
|
|
@ -2,7 +2,6 @@ package swarm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -11,18 +10,13 @@ import (
|
|||
"github.com/docker/docker/api/types/filters"
|
||||
swarmtypes "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/internal/test/daemon"
|
||||
"github.com/docker/docker/internal/test/environment"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/gotestyourself/gotestyourself/poll"
|
||||
"github.com/gotestyourself/gotestyourself/skip"
|
||||
)
|
||||
|
||||
const (
|
||||
dockerdBinary = "dockerd"
|
||||
defaultSwarmPort = 2477
|
||||
)
|
||||
|
||||
// ServicePoll tweaks the pollSettings for `service`
|
||||
func ServicePoll(config *poll.Settings) {
|
||||
// Override the default pollSettings for `service` resource here ...
|
||||
|
@ -55,23 +49,17 @@ func ContainerPoll(config *poll.Settings) {
|
|||
}
|
||||
|
||||
// NewSwarm creates a swarm daemon for testing
|
||||
func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm {
|
||||
func NewSwarm(t *testing.T, testEnv *environment.Execution, ops ...func(*daemon.Daemon)) *daemon.Daemon {
|
||||
skip.IfCondition(t, testEnv.IsRemoteDaemon())
|
||||
d := &daemon.Swarm{
|
||||
Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
}),
|
||||
// TODO: better method of finding an unused port
|
||||
Port: defaultSwarmPort,
|
||||
if testEnv.DaemonInfo.ExperimentalBuild {
|
||||
ops = append(ops, daemon.WithExperimental)
|
||||
}
|
||||
// TODO: move to a NewSwarm constructor
|
||||
d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
|
||||
|
||||
d := daemon.New(t, ops...)
|
||||
// avoid networking conflicts
|
||||
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
|
||||
d.StartWithBusybox(t, args...)
|
||||
|
||||
assert.NilError(t, d.Init(swarmtypes.InitRequest{}))
|
||||
d.SwarmInit(t, swarmtypes.InitRequest{})
|
||||
return d
|
||||
}
|
||||
|
||||
|
@ -79,7 +67,7 @@ func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm {
|
|||
type ServiceSpecOpt func(*swarmtypes.ServiceSpec)
|
||||
|
||||
// CreateService creates a service on the passed in swarm daemon.
|
||||
func CreateService(t *testing.T, d *daemon.Swarm, opts ...ServiceSpecOpt) string {
|
||||
func CreateService(t *testing.T, d *daemon.Daemon, opts ...ServiceSpecOpt) string {
|
||||
spec := defaultServiceSpec()
|
||||
for _, o := range opts {
|
||||
o(&spec)
|
||||
|
@ -151,7 +139,7 @@ func ServiceWithName(name string) ServiceSpecOpt {
|
|||
}
|
||||
|
||||
// GetRunningTasks gets the list of running tasks for a service
|
||||
func GetRunningTasks(t *testing.T, d *daemon.Swarm, serviceID string) []swarmtypes.Task {
|
||||
func GetRunningTasks(t *testing.T, d *daemon.Daemon, serviceID string) []swarmtypes.Task {
|
||||
client := GetClient(t, d)
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
|
@ -167,7 +155,7 @@ func GetRunningTasks(t *testing.T, d *daemon.Swarm, serviceID string) []swarmtyp
|
|||
}
|
||||
|
||||
// ExecTask runs the passed in exec config on the given task
|
||||
func ExecTask(t *testing.T, d *daemon.Swarm, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse {
|
||||
func ExecTask(t *testing.T, d *daemon.Daemon, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse {
|
||||
client := GetClient(t, d)
|
||||
|
||||
ctx := context.Background()
|
||||
|
@ -187,7 +175,7 @@ func ensureContainerSpec(spec *swarmtypes.ServiceSpec) {
|
|||
}
|
||||
|
||||
// GetClient creates a new client for the passed in swarm daemon.
|
||||
func GetClient(t *testing.T, d *daemon.Swarm) client.APIClient {
|
||||
func GetClient(t *testing.T, d *daemon.Daemon) client.APIClient {
|
||||
client, err := client.NewClientWithOpts(client.WithHost((d.Sock())))
|
||||
assert.NilError(t, err)
|
||||
return client
|
||||
|
|
66
internal/test/daemon/config.go
Normal file
66
internal/test/daemon/config.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
// ConfigConstructor defines a swarm config constructor
|
||||
type ConfigConstructor func(*swarm.Config)
|
||||
|
||||
// CreateConfig creates a config given the specified spec
|
||||
func (d *Daemon) CreateConfig(t assert.TestingT, configSpec swarm.ConfigSpec) string {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
scr, err := cli.ConfigCreate(context.Background(), configSpec)
|
||||
assert.NilError(t, err)
|
||||
return scr.ID
|
||||
}
|
||||
|
||||
// ListConfigs returns the list of the current swarm configs
|
||||
func (d *Daemon) ListConfigs(t assert.TestingT) []swarm.Config {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{})
|
||||
assert.NilError(t, err)
|
||||
return configs
|
||||
}
|
||||
|
||||
// GetConfig returns a swarm config identified by the specified id
|
||||
func (d *Daemon) GetConfig(t assert.TestingT, id string) *swarm.Config {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
config, _, err := cli.ConfigInspectWithRaw(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
return &config
|
||||
}
|
||||
|
||||
// DeleteConfig removes the swarm config identified by the specified id
|
||||
func (d *Daemon) DeleteConfig(t assert.TestingT, id string) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
err := cli.ConfigRemove(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// UpdateConfig updates the swarm config identified by the specified id
|
||||
// Currently, only label update is supported.
|
||||
func (d *Daemon) UpdateConfig(t assert.TestingT, id string, f ...ConfigConstructor) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
config := d.GetConfig(t, id)
|
||||
for _, fn := range f {
|
||||
fn(config)
|
||||
}
|
||||
|
||||
err := cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
|
||||
assert.NilError(t, err)
|
||||
}
|
|
@ -67,6 +67,13 @@ type Daemon struct {
|
|||
experimental bool
|
||||
dockerdBinary string
|
||||
log logT
|
||||
|
||||
// swarm related field
|
||||
swarmListenAddr string
|
||||
SwarmPort int // FIXME(vdemeester) should probably not be exported
|
||||
|
||||
// cached information
|
||||
CachedInfo types.Info
|
||||
}
|
||||
|
||||
// New returns a Daemon instance to be used for testing.
|
||||
|
@ -98,14 +105,16 @@ func New(t testingT, ops ...func(*Daemon)) *Daemon {
|
|||
}
|
||||
}
|
||||
d := &Daemon{
|
||||
id: id,
|
||||
Folder: daemonFolder,
|
||||
Root: daemonRoot,
|
||||
storageDriver: storageDriver,
|
||||
userlandProxy: userlandProxy,
|
||||
execRoot: filepath.Join(os.TempDir(), "docker-execroot", id),
|
||||
dockerdBinary: defaultDockerdBinary,
|
||||
log: t,
|
||||
id: id,
|
||||
Folder: daemonFolder,
|
||||
Root: daemonRoot,
|
||||
storageDriver: storageDriver,
|
||||
userlandProxy: userlandProxy,
|
||||
execRoot: filepath.Join(os.TempDir(), "docker-execroot", id),
|
||||
dockerdBinary: defaultDockerdBinary,
|
||||
swarmListenAddr: defaultSwarmListenAddr,
|
||||
SwarmPort: defaultSwarmPort,
|
||||
log: t,
|
||||
}
|
||||
|
||||
for _, op := range ops {
|
||||
|
@ -150,12 +159,23 @@ func (d *Daemon) ReadLogFile() ([]byte, error) {
|
|||
}
|
||||
|
||||
// NewClient creates new client based on daemon's socket path
|
||||
// FIXME(vdemeester): replace NewClient with NewClientT
|
||||
func (d *Daemon) NewClient() (*client.Client, error) {
|
||||
return client.NewClientWithOpts(
|
||||
client.FromEnv,
|
||||
client.WithHost(d.Sock()))
|
||||
}
|
||||
|
||||
// NewClientT creates new client based on daemon's socket path
|
||||
// FIXME(vdemeester): replace NewClient with NewClientT
|
||||
func (d *Daemon) NewClientT(t assert.TestingT) *client.Client {
|
||||
c, err := client.NewClientWithOpts(
|
||||
client.FromEnv,
|
||||
client.WithHost(d.Sock()))
|
||||
assert.NilError(t, err, "cannot create daemon client")
|
||||
return c
|
||||
}
|
||||
|
||||
// CleanupExecRoot cleans the daemon exec root (network namespaces, ...)
|
||||
func (d *Daemon) CleanupExecRoot(t testingT) {
|
||||
cleanupExecRoot(t, d.execRoot)
|
||||
|
@ -610,7 +630,7 @@ func (d *Daemon) queryRootDir() (string, error) {
|
|||
|
||||
// Info returns the info struct for this daemon
|
||||
func (d *Daemon) Info(t assert.TestingT) types.Info {
|
||||
apiclient, err := client.NewClientWithOpts(client.WithHost((d.Sock())))
|
||||
apiclient, err := d.NewClient()
|
||||
assert.NilError(t, err)
|
||||
info, err := apiclient.Info(context.Background())
|
||||
assert.NilError(t, err)
|
||||
|
|
69
internal/test/daemon/node.go
Normal file
69
internal/test/daemon/node.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
// NodeConstructor defines a swarm node constructor
|
||||
type NodeConstructor func(*swarm.Node)
|
||||
|
||||
// GetNode returns a swarm node identified by the specified id
|
||||
func (d *Daemon) GetNode(t assert.TestingT, id string) *swarm.Node {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
node, _, err := cli.NodeInspectWithRaw(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, node.ID == id)
|
||||
return &node
|
||||
}
|
||||
|
||||
// RemoveNode removes the specified node
|
||||
func (d *Daemon) RemoveNode(t assert.TestingT, id string, force bool) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
options := types.NodeRemoveOptions{
|
||||
Force: force,
|
||||
}
|
||||
err := cli.NodeRemove(context.Background(), id, options)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// UpdateNode updates a swarm node with the specified node constructor
|
||||
func (d *Daemon) UpdateNode(t assert.TestingT, id string, f ...NodeConstructor) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
for i := 0; ; i++ {
|
||||
node := d.GetNode(t, id)
|
||||
for _, fn := range f {
|
||||
fn(node)
|
||||
}
|
||||
|
||||
err := cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec)
|
||||
if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
assert.NilError(t, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ListNodes returns the list of the current swarm nodes
|
||||
func (d *Daemon) ListNodes(t assert.TestingT) []swarm.Node {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
return nodes
|
||||
}
|
|
@ -11,3 +11,17 @@ func WithDockerdBinary(dockerdBinary string) func(*Daemon) {
|
|||
d.dockerdBinary = dockerdBinary
|
||||
}
|
||||
}
|
||||
|
||||
// WithSwarmPort sets the swarm port to use for swarm mode
|
||||
func WithSwarmPort(port int) func(*Daemon) {
|
||||
return func(d *Daemon) {
|
||||
d.SwarmPort = port
|
||||
}
|
||||
}
|
||||
|
||||
// WithSwarmListenAddr sets the swarm listen addr to use for swarm mode
|
||||
func WithSwarmListenAddr(listenAddr string) func(*Daemon) {
|
||||
return func(d *Daemon) {
|
||||
d.swarmListenAddr = listenAddr
|
||||
}
|
||||
}
|
||||
|
|
68
internal/test/daemon/secret.go
Normal file
68
internal/test/daemon/secret.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
// SecretConstructor defines a swarm secret constructor
|
||||
type SecretConstructor func(*swarm.Secret)
|
||||
|
||||
// CreateSecret creates a secret given the specified spec
|
||||
func (d *Daemon) CreateSecret(t assert.TestingT, secretSpec swarm.SecretSpec) string {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
scr, err := cli.SecretCreate(context.Background(), secretSpec)
|
||||
assert.NilError(t, err)
|
||||
|
||||
return scr.ID
|
||||
}
|
||||
|
||||
// ListSecrets returns the list of the current swarm secrets
|
||||
func (d *Daemon) ListSecrets(t assert.TestingT) []swarm.Secret {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{})
|
||||
assert.NilError(t, err)
|
||||
return secrets
|
||||
}
|
||||
|
||||
// GetSecret returns a swarm secret identified by the specified id
|
||||
func (d *Daemon) GetSecret(t assert.TestingT, id string) *swarm.Secret {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
secret, _, err := cli.SecretInspectWithRaw(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
return &secret
|
||||
}
|
||||
|
||||
// DeleteSecret removes the swarm secret identified by the specified id
|
||||
func (d *Daemon) DeleteSecret(t assert.TestingT, id string) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
err := cli.SecretRemove(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// UpdateSecret updates the swarm secret identified by the specified id
|
||||
// Currently, only label update is supported.
|
||||
func (d *Daemon) UpdateSecret(t assert.TestingT, id string, f ...SecretConstructor) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
secret := d.GetSecret(t, id)
|
||||
for _, fn := range f {
|
||||
fn(secret)
|
||||
}
|
||||
|
||||
err := cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
|
||||
|
||||
assert.NilError(t, err)
|
||||
}
|
108
internal/test/daemon/service.go
Normal file
108
internal/test/daemon/service.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
)
|
||||
|
||||
// ServiceConstructor defines a swarm service constructor function
|
||||
type ServiceConstructor func(*swarm.Service)
|
||||
|
||||
// CreateServiceWithOptions creates a swarm service given the specified service constructors
|
||||
// and auth config
|
||||
func (d *Daemon) CreateServiceWithOptions(t assert.TestingT, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
|
||||
var service swarm.Service
|
||||
for _, fn := range f {
|
||||
fn(&service)
|
||||
}
|
||||
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
res, err := cli.ServiceCreate(ctx, service.Spec, opts)
|
||||
assert.NilError(t, err)
|
||||
return res.ID
|
||||
}
|
||||
|
||||
// CreateService creates a swarm service given the specified service constructor
|
||||
func (d *Daemon) CreateService(t assert.TestingT, f ...ServiceConstructor) string {
|
||||
return d.CreateServiceWithOptions(t, types.ServiceCreateOptions{}, f...)
|
||||
}
|
||||
|
||||
// GetService returns the swarm service corresponding to the specified id
|
||||
func (d *Daemon) GetService(t assert.TestingT, id string) *swarm.Service {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{})
|
||||
assert.NilError(t, err)
|
||||
return &service
|
||||
}
|
||||
|
||||
// GetServiceTasks returns the swarm tasks for the specified service
|
||||
func (d *Daemon) GetServiceTasks(t assert.TestingT, service string) []swarm.Task {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("desired-state", "running")
|
||||
filterArgs.Add("service", service)
|
||||
|
||||
options := types.TaskListOptions{
|
||||
Filters: filterArgs,
|
||||
}
|
||||
|
||||
tasks, err := cli.TaskList(context.Background(), options)
|
||||
assert.NilError(t, err)
|
||||
return tasks
|
||||
}
|
||||
|
||||
// UpdateService updates a swarm service with the specified service constructor
|
||||
func (d *Daemon) UpdateService(t assert.TestingT, service *swarm.Service, f ...ServiceConstructor) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
for _, fn := range f {
|
||||
fn(service)
|
||||
}
|
||||
|
||||
_, err := cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// RemoveService removes the specified service
|
||||
func (d *Daemon) RemoveService(t assert.TestingT, id string) {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
err := cli.ServiceRemove(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// ListServices returns the list of the current swarm services
|
||||
func (d *Daemon) ListServices(t assert.TestingT) []swarm.Service {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{})
|
||||
assert.NilError(t, err)
|
||||
return services
|
||||
}
|
||||
|
||||
// GetTask returns the swarm task identified by the specified id
|
||||
func (d *Daemon) GetTask(t assert.TestingT, id string) swarm.Task {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
task, _, err := cli.TaskInspectWithRaw(context.Background(), id)
|
||||
assert.NilError(t, err)
|
||||
return task
|
||||
}
|
139
internal/test/daemon/swarm.go
Normal file
139
internal/test/daemon/swarm.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultSwarmPort = 2477
|
||||
defaultSwarmListenAddr = "0.0.0.0"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
if req.ListenAddr == "" {
|
||||
req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
|
||||
}
|
||||
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) {
|
||||
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 {
|
||||
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 {
|
||||
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) {
|
||||
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) {
|
||||
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 {
|
||||
cli := d.NewClientT(t)
|
||||
defer cli.Close()
|
||||
|
||||
sw, err := cli.SwarmInspect(context.Background())
|
||||
assert.NilError(t, err)
|
||||
return sw.JoinTokens
|
||||
}
|
Loading…
Add table
Reference in a new issue