This flag was added in Docker 17.06, API version 1.31 through
moby@8dc8cd4719f165c01c98e7d3ce1d6cea6a8f60b8, but didn't add
API-version annotations.
This patch adds the missing annotations to hide this flag if
the CLI is connected to an older version of the daemon that
doesn't support that API.
Before this patch:
DOCKER_API_VERSION=1.30 docker swarm init --help | grep data-path-addr
--data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
DOCKER_API_VERSION=1.31 docker swarm init --help | grep data-path-addr
--data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
With this patch applied:
DOCKER_API_VERSION=1.30 docker swarm init --help | grep data-path-addr
# (no result)
DOCKER_API_VERSION=1.31 docker swarm init --help | grep data-path-addr
--data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
100 lines
3.3 KiB
Go
100 lines
3.3 KiB
Go
package swarm
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/docker/cli/cli"
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
type initOptions struct {
|
|
swarmOptions
|
|
listenAddr NodeAddrOption
|
|
// Not a NodeAddrOption because it has no default port.
|
|
advertiseAddr string
|
|
dataPathAddr string
|
|
forceNewCluster bool
|
|
availability string
|
|
}
|
|
|
|
func newInitCommand(dockerCli command.Cli) *cobra.Command {
|
|
opts := initOptions{
|
|
listenAddr: NewListenAddrOption(),
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "init [OPTIONS]",
|
|
Short: "Initialize a swarm",
|
|
Args: cli.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return runInit(dockerCli, cmd.Flags(), opts)
|
|
},
|
|
}
|
|
|
|
flags := cmd.Flags()
|
|
flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: <ip|interface>[:port])")
|
|
flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])")
|
|
flags.StringVar(&opts.dataPathAddr, flagDataPathAddr, "", "Address or interface to use for data path traffic (format: <ip|interface>)")
|
|
flags.SetAnnotation(flagDataPathAddr, "version", []string{"1.31"})
|
|
flags.BoolVar(&opts.forceNewCluster, "force-new-cluster", false, "Force create a new cluster from current state")
|
|
flags.BoolVar(&opts.autolock, flagAutolock, false, "Enable manager autolocking (requiring an unlock key to start a stopped manager)")
|
|
flags.StringVar(&opts.availability, flagAvailability, "active", `Availability of the node ("active"|"pause"|"drain")`)
|
|
addSwarmFlags(flags, &opts.swarmOptions)
|
|
return cmd
|
|
}
|
|
|
|
func runInit(dockerCli command.Cli, flags *pflag.FlagSet, opts initOptions) error {
|
|
client := dockerCli.Client()
|
|
ctx := context.Background()
|
|
|
|
req := swarm.InitRequest{
|
|
ListenAddr: opts.listenAddr.String(),
|
|
AdvertiseAddr: opts.advertiseAddr,
|
|
DataPathAddr: opts.dataPathAddr,
|
|
ForceNewCluster: opts.forceNewCluster,
|
|
Spec: opts.swarmOptions.ToSpec(flags),
|
|
AutoLockManagers: opts.swarmOptions.autolock,
|
|
}
|
|
if flags.Changed(flagAvailability) {
|
|
availability := swarm.NodeAvailability(strings.ToLower(opts.availability))
|
|
switch availability {
|
|
case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain:
|
|
req.Availability = availability
|
|
default:
|
|
return errors.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability)
|
|
}
|
|
}
|
|
|
|
nodeID, err := client.SwarmInit(ctx, req)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "could not choose an IP address to advertise") || strings.Contains(err.Error(), "could not find the system's IP address") {
|
|
return errors.New(err.Error() + " - specify one with --advertise-addr")
|
|
}
|
|
return err
|
|
}
|
|
|
|
fmt.Fprintf(dockerCli.Out(), "Swarm initialized: current node (%s) is now a manager.\n\n", nodeID)
|
|
|
|
if err := printJoinCommand(ctx, dockerCli, nodeID, true, false); err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Fprint(dockerCli.Out(), "To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.\n\n")
|
|
|
|
if req.AutoLockManagers {
|
|
unlockKeyResp, err := client.SwarmGetUnlockKey(ctx)
|
|
if err != nil {
|
|
return errors.Wrap(err, "could not fetch unlock key")
|
|
}
|
|
printUnlockCommand(dockerCli.Out(), unlockKeyResp.UnlockKey)
|
|
}
|
|
|
|
return nil
|
|
}
|