github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/stack/cmd.go (about) 1 package stack 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/docker/cli/cli" 9 "github.com/docker/cli/cli/command" 10 "github.com/spf13/cobra" 11 "github.com/spf13/pflag" 12 ) 13 14 var errUnsupportedAllOrchestrator = fmt.Errorf(`no orchestrator specified: use either "kubernetes" or "swarm"`) 15 16 type commonOptions struct { 17 orchestrator command.Orchestrator 18 } 19 20 func (o *commonOptions) Orchestrator() command.Orchestrator { 21 if o == nil { 22 return command.OrchestratorSwarm 23 } 24 return o.orchestrator 25 } 26 27 // NewStackCommand returns a cobra command for `stack` subcommands 28 func NewStackCommand(dockerCli command.Cli) *cobra.Command { 29 var opts commonOptions 30 cmd := &cobra.Command{ 31 Use: "stack [OPTIONS]", 32 Short: "Manage Docker stacks", 33 Args: cli.NoArgs, 34 PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 35 orchestrator, err := getOrchestrator(dockerCli, cmd) 36 if err != nil { 37 return err 38 } 39 opts.orchestrator = orchestrator 40 hideOrchestrationFlags(cmd, orchestrator) 41 return checkSupportedFlag(cmd, orchestrator) 42 }, 43 44 RunE: command.ShowHelp(dockerCli.Err()), 45 Annotations: map[string]string{ 46 "version": "1.25", 47 }, 48 } 49 defaultHelpFunc := cmd.HelpFunc() 50 cmd.SetHelpFunc(func(c *cobra.Command, args []string) { 51 if err := cmd.Root().PersistentPreRunE(c, args); err != nil { 52 fmt.Fprintln(dockerCli.Err(), err) 53 return 54 } 55 if err := cmd.PersistentPreRunE(c, args); err != nil { 56 fmt.Fprintln(dockerCli.Err(), err) 57 return 58 } 59 hideOrchestrationFlags(c, opts.orchestrator) 60 defaultHelpFunc(c, args) 61 }) 62 cmd.AddCommand( 63 newDeployCommand(dockerCli, &opts), 64 newListCommand(dockerCli, &opts), 65 newPsCommand(dockerCli, &opts), 66 newRemoveCommand(dockerCli, &opts), 67 newServicesCommand(dockerCli, &opts), 68 ) 69 flags := cmd.PersistentFlags() 70 flags.String("kubeconfig", "", "Kubernetes config file") 71 flags.SetAnnotation("kubeconfig", "kubernetes", nil) 72 flags.SetAnnotation("kubeconfig", "deprecated", nil) 73 flags.String("orchestrator", "", "Orchestrator to use (swarm|kubernetes|all)") 74 flags.SetAnnotation("orchestrator", "deprecated", nil) 75 return cmd 76 } 77 78 func getOrchestrator(dockerCli command.Cli, cmd *cobra.Command) (command.Orchestrator, error) { 79 var orchestratorFlag string 80 if o, err := cmd.Flags().GetString("orchestrator"); err == nil { 81 orchestratorFlag = o 82 } 83 return dockerCli.StackOrchestrator(orchestratorFlag) 84 } 85 86 func hideOrchestrationFlags(cmd *cobra.Command, orchestrator command.Orchestrator) { 87 cmd.Flags().VisitAll(func(f *pflag.Flag) { 88 if _, ok := f.Annotations["kubernetes"]; ok && !orchestrator.HasKubernetes() { 89 f.Hidden = true 90 } 91 if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() { 92 f.Hidden = true 93 } 94 }) 95 for _, subcmd := range cmd.Commands() { 96 hideOrchestrationFlags(subcmd, orchestrator) 97 } 98 } 99 100 func checkSupportedFlag(cmd *cobra.Command, orchestrator command.Orchestrator) error { 101 errs := []string{} 102 cmd.Flags().VisitAll(func(f *pflag.Flag) { 103 if !f.Changed { 104 return 105 } 106 if _, ok := f.Annotations["kubernetes"]; ok && !orchestrator.HasKubernetes() { 107 errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with kubernetes features enabled`, f.Name)) 108 } 109 if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() { 110 errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with swarm features enabled`, f.Name)) 111 } 112 }) 113 for _, subcmd := range cmd.Commands() { 114 if err := checkSupportedFlag(subcmd, orchestrator); err != nil { 115 errs = append(errs, err.Error()) 116 } 117 } 118 if len(errs) > 0 { 119 return errors.New(strings.Join(errs, "\n")) 120 } 121 return nil 122 }