services.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package stack
  2. import (
  3. "fmt"
  4. "golang.org/x/net/context"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/api/types/filters"
  7. "github.com/docker/docker/cli"
  8. "github.com/docker/docker/cli/command"
  9. "github.com/docker/docker/cli/command/formatter"
  10. "github.com/docker/docker/cli/command/service"
  11. "github.com/docker/docker/opts"
  12. "github.com/spf13/cobra"
  13. )
  14. type servicesOptions struct {
  15. quiet bool
  16. format string
  17. filter opts.FilterOpt
  18. namespace string
  19. }
  20. func newServicesCommand(dockerCli *command.DockerCli) *cobra.Command {
  21. opts := servicesOptions{filter: opts.NewFilterOpt()}
  22. cmd := &cobra.Command{
  23. Use: "services [OPTIONS] STACK",
  24. Short: "List the services in the stack",
  25. Args: cli.ExactArgs(1),
  26. RunE: func(cmd *cobra.Command, args []string) error {
  27. opts.namespace = args[0]
  28. return runServices(dockerCli, opts)
  29. },
  30. }
  31. flags := cmd.Flags()
  32. flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
  33. flags.StringVar(&opts.format, "format", "", "Pretty-print services using a Go template")
  34. flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
  35. return cmd
  36. }
  37. func runServices(dockerCli *command.DockerCli, opts servicesOptions) error {
  38. ctx := context.Background()
  39. client := dockerCli.Client()
  40. filter := getStackFilterFromOpt(opts.namespace, opts.filter)
  41. services, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: filter})
  42. if err != nil {
  43. return err
  44. }
  45. out := dockerCli.Out()
  46. // if no services in this stack, print message and exit 0
  47. if len(services) == 0 {
  48. fmt.Fprintf(out, "Nothing found in stack: %s\n", opts.namespace)
  49. return nil
  50. }
  51. info := map[string]formatter.ServiceListInfo{}
  52. if !opts.quiet {
  53. taskFilter := filters.NewArgs()
  54. for _, service := range services {
  55. taskFilter.Add("service", service.ID)
  56. }
  57. tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: taskFilter})
  58. if err != nil {
  59. return err
  60. }
  61. nodes, err := client.NodeList(ctx, types.NodeListOptions{})
  62. if err != nil {
  63. return err
  64. }
  65. info = service.GetServicesStatus(services, nodes, tasks)
  66. }
  67. format := opts.format
  68. if len(format) == 0 {
  69. if len(dockerCli.ConfigFile().ServicesFormat) > 0 && !opts.quiet {
  70. format = dockerCli.ConfigFile().ServicesFormat
  71. } else {
  72. format = formatter.TableFormatKey
  73. }
  74. }
  75. servicesCtx := formatter.Context{
  76. Output: dockerCli.Out(),
  77. Format: formatter.NewServiceListFormat(format, opts.quiet),
  78. }
  79. return formatter.ServiceListWrite(servicesCtx, services, info)
  80. }