github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/cli/command/stack/deploy.go (about)

     1  package stack
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/docker/docker/cli"
     7  	"github.com/docker/docker/cli/command"
     8  	"github.com/pkg/errors"
     9  	"github.com/spf13/cobra"
    10  	"golang.org/x/net/context"
    11  )
    12  
    13  const (
    14  	defaultNetworkDriver = "overlay"
    15  )
    16  
    17  type deployOptions struct {
    18  	bundlefile       string
    19  	composefile      string
    20  	namespace        string
    21  	sendRegistryAuth bool
    22  }
    23  
    24  func newDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
    25  	var opts deployOptions
    26  
    27  	cmd := &cobra.Command{
    28  		Use:     "deploy [OPTIONS] STACK",
    29  		Aliases: []string{"up"},
    30  		Short:   "Deploy a new stack or update an existing stack",
    31  		Args:    cli.ExactArgs(1),
    32  		RunE: func(cmd *cobra.Command, args []string) error {
    33  			opts.namespace = args[0]
    34  			return runDeploy(dockerCli, opts)
    35  		},
    36  	}
    37  
    38  	flags := cmd.Flags()
    39  	addBundlefileFlag(&opts.bundlefile, flags)
    40  	addComposefileFlag(&opts.composefile, flags)
    41  	addRegistryAuthFlag(&opts.sendRegistryAuth, flags)
    42  	return cmd
    43  }
    44  
    45  func runDeploy(dockerCli *command.DockerCli, opts deployOptions) error {
    46  	ctx := context.Background()
    47  
    48  	switch {
    49  	case opts.bundlefile == "" && opts.composefile == "":
    50  		return fmt.Errorf("Please specify either a bundle file (with --bundle-file) or a Compose file (with --compose-file).")
    51  	case opts.bundlefile != "" && opts.composefile != "":
    52  		return fmt.Errorf("You cannot specify both a bundle file and a Compose file.")
    53  	case opts.bundlefile != "":
    54  		return deployBundle(ctx, dockerCli, opts)
    55  	default:
    56  		return deployCompose(ctx, dockerCli, opts)
    57  	}
    58  }
    59  
    60  // checkDaemonIsSwarmManager does an Info API call to verify that the daemon is
    61  // a swarm manager. This is necessary because we must create networks before we
    62  // create services, but the API call for creating a network does not return a
    63  // proper status code when it can't create a network in the "global" scope.
    64  func checkDaemonIsSwarmManager(ctx context.Context, dockerCli *command.DockerCli) error {
    65  	info, err := dockerCli.Client().Info(ctx)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	if !info.Swarm.ControlAvailable {
    70  		return errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
    71  	}
    72  	return nil
    73  }