github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/cli/command/swarm/init.go (about)

     1  package swarm
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"golang.org/x/net/context"
     8  
     9  	"github.com/docker/docker/api/types/swarm"
    10  	"github.com/docker/docker/cli"
    11  	"github.com/docker/docker/cli/command"
    12  	"github.com/pkg/errors"
    13  	"github.com/spf13/cobra"
    14  	"github.com/spf13/pflag"
    15  )
    16  
    17  type initOptions struct {
    18  	swarmOptions
    19  	listenAddr NodeAddrOption
    20  	// Not a NodeAddrOption because it has no default port.
    21  	advertiseAddr   string
    22  	forceNewCluster bool
    23  	availability    string
    24  }
    25  
    26  func newInitCommand(dockerCli command.Cli) *cobra.Command {
    27  	opts := initOptions{
    28  		listenAddr: NewListenAddrOption(),
    29  	}
    30  
    31  	cmd := &cobra.Command{
    32  		Use:   "init [OPTIONS]",
    33  		Short: "Initialize a swarm",
    34  		Args:  cli.NoArgs,
    35  		RunE: func(cmd *cobra.Command, args []string) error {
    36  			return runInit(dockerCli, cmd.Flags(), opts)
    37  		},
    38  	}
    39  
    40  	flags := cmd.Flags()
    41  	flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: <ip|interface>[:port])")
    42  	flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])")
    43  	flags.BoolVar(&opts.forceNewCluster, "force-new-cluster", false, "Force create a new cluster from current state")
    44  	flags.BoolVar(&opts.autolock, flagAutolock, false, "Enable manager autolocking (requiring an unlock key to start a stopped manager)")
    45  	flags.StringVar(&opts.availability, flagAvailability, "active", "Availability of the node (active/pause/drain)")
    46  	addSwarmFlags(flags, &opts.swarmOptions)
    47  	return cmd
    48  }
    49  
    50  func runInit(dockerCli command.Cli, flags *pflag.FlagSet, opts initOptions) error {
    51  	client := dockerCli.Client()
    52  	ctx := context.Background()
    53  
    54  	req := swarm.InitRequest{
    55  		ListenAddr:       opts.listenAddr.String(),
    56  		AdvertiseAddr:    opts.advertiseAddr,
    57  		ForceNewCluster:  opts.forceNewCluster,
    58  		Spec:             opts.swarmOptions.ToSpec(flags),
    59  		AutoLockManagers: opts.swarmOptions.autolock,
    60  	}
    61  	if flags.Changed(flagAvailability) {
    62  		availability := swarm.NodeAvailability(strings.ToLower(opts.availability))
    63  		switch availability {
    64  		case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain:
    65  			req.Availability = availability
    66  		default:
    67  			return fmt.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability)
    68  		}
    69  	}
    70  
    71  	nodeID, err := client.SwarmInit(ctx, req)
    72  	if err != nil {
    73  		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") {
    74  			return errors.New(err.Error() + " - specify one with --advertise-addr")
    75  		}
    76  		return err
    77  	}
    78  
    79  	fmt.Fprintf(dockerCli.Out(), "Swarm initialized: current node (%s) is now a manager.\n\n", nodeID)
    80  
    81  	if err := printJoinCommand(ctx, dockerCli, nodeID, false, true); err != nil {
    82  		return err
    83  	}
    84  
    85  	fmt.Fprint(dockerCli.Out(), "To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.\n\n")
    86  
    87  	if req.AutoLockManagers {
    88  		unlockKeyResp, err := client.SwarmGetUnlockKey(ctx)
    89  		if err != nil {
    90  			return errors.Wrap(err, "could not fetch unlock key")
    91  		}
    92  		printUnlockCommand(ctx, dockerCli, unlockKeyResp.UnlockKey)
    93  	}
    94  
    95  	return nil
    96  }