Browse code

Allow swarm init with `--availability=drain` This fix adds a new flag `--availability` to `swarm join`.

Related documentation has been updated.

An integration test has been added.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/12/22 11:13:31
Showing 5 changed files
... ...
@@ -135,6 +135,7 @@ type InitRequest struct {
135 135
 	ForceNewCluster  bool
136 136
 	Spec             Spec
137 137
 	AutoLockManagers bool
138
+	Availability     NodeAvailability
138 139
 }
139 140
 
140 141
 // JoinRequest is the request used to join a swarm.
... ...
@@ -20,6 +20,7 @@ type initOptions struct {
20 20
 	// Not a NodeAddrOption because it has no default port.
21 21
 	advertiseAddr   string
22 22
 	forceNewCluster bool
23
+	availability    string
23 24
 }
24 25
 
25 26
 func newInitCommand(dockerCli command.Cli) *cobra.Command {
... ...
@@ -41,6 +42,7 @@ func newInitCommand(dockerCli command.Cli) *cobra.Command {
41 41
 	flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])")
42 42
 	flags.BoolVar(&opts.forceNewCluster, "force-new-cluster", false, "Force create a new cluster from current state")
43 43
 	flags.BoolVar(&opts.autolock, flagAutolock, false, "Enable manager autolocking (requiring an unlock key to start a stopped manager)")
44
+	flags.StringVar(&opts.availability, flagAvailability, "active", "Availability of the node (active/pause/drain)")
44 45
 	addSwarmFlags(flags, &opts.swarmOptions)
45 46
 	return cmd
46 47
 }
... ...
@@ -56,6 +58,15 @@ func runInit(dockerCli command.Cli, flags *pflag.FlagSet, opts initOptions) erro
56 56
 		Spec:             opts.swarmOptions.ToSpec(flags),
57 57
 		AutoLockManagers: opts.swarmOptions.autolock,
58 58
 	}
59
+	if flags.Changed(flagAvailability) {
60
+		availability := swarm.NodeAvailability(strings.ToLower(opts.availability))
61
+		switch availability {
62
+		case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain:
63
+			req.Availability = availability
64
+		default:
65
+			return fmt.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability)
66
+		}
67
+	}
59 68
 
60 69
 	nodeID, err := client.SwarmInit(ctx, req)
61 70
 	if err != nil {
... ...
@@ -320,6 +320,7 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) {
320 320
 		LocalAddr:       localAddr,
321 321
 		ListenAddr:      net.JoinHostPort(listenHost, listenPort),
322 322
 		AdvertiseAddr:   net.JoinHostPort(advertiseHost, advertisePort),
323
+		availability:    req.Availability,
323 324
 	})
324 325
 	if err != nil {
325 326
 		return "", err
... ...
@@ -23,6 +23,7 @@ Initialize a swarm
23 23
 Options:
24 24
       --advertise-addr string           Advertised address (format: <ip|interface>[:port])
25 25
       --autolock                        Enable manager autolocking (requiring an unlock key to start a stopped manager)
26
+      --availability string             Availability of the node (active/pause/drain) (default "active")
26 27
       --cert-expiry duration            Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
27 28
       --dispatcher-heartbeat duration   Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
28 29
       --external-ca external-ca         Specifications of one or more certificate signing endpoints
... ...
@@ -133,6 +134,16 @@ Snapshots compact the Raft log and allow for more efficient transfer of the
133 133
 state to new managers. However, there is a performance cost to taking snapshots
134 134
 frequently.
135 135
 
136
+### `--availability`
137
+
138
+This flag specifies the availability of the node at the time the node joins a master.
139
+Possible availability values are `active`, `pause`, or `drain`.
140
+
141
+This flag is useful in certain situations. For example, a cluster may want to have
142
+dedicated manager nodes that are not served as worker nodes. This could be achieved
143
+by passing `--availability=drain` to `docker swarm init`.
144
+
145
+
136 146
 ## Related information
137 147
 
138 148
 * [swarm join](swarm_join.md)
... ...
@@ -1619,3 +1619,14 @@ func (s *DockerSwarmSuite) TestSwarmJoinWithDrain(c *check.C) {
1619 1619
 	c.Assert(err, checker.IsNil)
1620 1620
 	c.Assert(out, checker.Contains, "Drain")
1621 1621
 }
1622
+
1623
+func (s *DockerSwarmSuite) TestSwarmInitWithDrain(c *check.C) {
1624
+	d := s.AddDaemon(c, false, false)
1625
+
1626
+	out, err := d.Cmd("swarm", "init", "--availability", "drain")
1627
+	c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
1628
+
1629
+	out, err = d.Cmd("node", "ls")
1630
+	c.Assert(err, checker.IsNil)
1631
+	c.Assert(out, checker.Contains, "Drain")
1632
+}