github.com/cspotcode/docker-cli@v20.10.0-rc1.0.20201201121459-3faad7acc5b8+incompatible/cli/command/stack/services.go (about) 1 package stack 2 3 import ( 4 "fmt" 5 "sort" 6 7 "github.com/docker/cli/cli" 8 "github.com/docker/cli/cli/command" 9 "github.com/docker/cli/cli/command/service" 10 "github.com/docker/cli/cli/command/stack/formatter" 11 "github.com/docker/cli/cli/command/stack/kubernetes" 12 "github.com/docker/cli/cli/command/stack/options" 13 "github.com/docker/cli/cli/command/stack/swarm" 14 cliopts "github.com/docker/cli/opts" 15 swarmtypes "github.com/docker/docker/api/types/swarm" 16 "github.com/fvbommel/sortorder" 17 "github.com/spf13/cobra" 18 "github.com/spf13/pflag" 19 ) 20 21 func newServicesCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command { 22 opts := options.Services{Filter: cliopts.NewFilterOpt()} 23 24 cmd := &cobra.Command{ 25 Use: "services [OPTIONS] STACK", 26 Short: "List the services in the stack", 27 Args: cli.ExactArgs(1), 28 RunE: func(cmd *cobra.Command, args []string) error { 29 opts.Namespace = args[0] 30 if err := validateStackName(opts.Namespace); err != nil { 31 return err 32 } 33 return RunServices(dockerCli, cmd.Flags(), common.Orchestrator(), opts) 34 }, 35 } 36 flags := cmd.Flags() 37 flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs") 38 flags.StringVar(&opts.Format, "format", "", "Pretty-print services using a Go template") 39 flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided") 40 kubernetes.AddNamespaceFlag(flags) 41 return cmd 42 } 43 44 // RunServices performs a stack services against the specified orchestrator 45 func RunServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Services) error { 46 services, err := GetServices(dockerCli, flags, commonOrchestrator, opts) 47 if err != nil { 48 return err 49 } 50 return formatWrite(dockerCli, services, opts) 51 } 52 53 // GetServices returns the services for the specified orchestrator 54 func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Services) ([]swarmtypes.Service, error) { 55 switch { 56 case commonOrchestrator.HasAll(): 57 return nil, errUnsupportedAllOrchestrator 58 case commonOrchestrator.HasKubernetes(): 59 kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(flags, commonOrchestrator)) 60 if err != nil { 61 return nil, err 62 } 63 return kubernetes.GetServices(kli, opts) 64 default: 65 return swarm.GetServices(dockerCli, opts) 66 } 67 } 68 69 func formatWrite(dockerCli command.Cli, services []swarmtypes.Service, opts options.Services) error { 70 // if no services in the stack, print message and exit 0 71 if len(services) == 0 { 72 _, _ = fmt.Fprintf(dockerCli.Err(), "Nothing found in stack: %s\n", opts.Namespace) 73 return nil 74 } 75 sort.Slice(services, func(i, j int) bool { 76 return sortorder.NaturalLess(services[i].Spec.Name, services[j].Spec.Name) 77 }) 78 79 format := opts.Format 80 if len(format) == 0 { 81 if len(dockerCli.ConfigFile().ServicesFormat) > 0 && !opts.Quiet { 82 format = dockerCli.ConfigFile().ServicesFormat 83 } else { 84 format = formatter.TableFormatKey 85 } 86 } 87 88 servicesCtx := formatter.Context{ 89 Output: dockerCli.Out(), 90 Format: service.NewListFormat(format, opts.Quiet), 91 } 92 return service.ListFormatWrite(servicesCtx, services) 93 }