ps.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package service
  2. import (
  3. "strings"
  4. "golang.org/x/net/context"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/api/types/filters"
  7. swarmtypes "github.com/docker/docker/api/types/swarm"
  8. "github.com/docker/docker/cli"
  9. "github.com/docker/docker/cli/command"
  10. "github.com/docker/docker/cli/command/formatter"
  11. "github.com/docker/docker/cli/command/idresolver"
  12. "github.com/docker/docker/cli/command/node"
  13. "github.com/docker/docker/cli/command/task"
  14. "github.com/docker/docker/opts"
  15. "github.com/pkg/errors"
  16. "github.com/spf13/cobra"
  17. )
  18. type psOptions struct {
  19. services []string
  20. quiet bool
  21. noResolve bool
  22. noTrunc bool
  23. format string
  24. filter opts.FilterOpt
  25. }
  26. func newPsCommand(dockerCli *command.DockerCli) *cobra.Command {
  27. opts := psOptions{filter: opts.NewFilterOpt()}
  28. cmd := &cobra.Command{
  29. Use: "ps [OPTIONS] SERVICE [SERVICE...]",
  30. Short: "List the tasks of one or more services",
  31. Args: cli.RequiresMinArgs(1),
  32. RunE: func(cmd *cobra.Command, args []string) error {
  33. opts.services = args
  34. return runPS(dockerCli, opts)
  35. },
  36. }
  37. flags := cmd.Flags()
  38. flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only display task IDs")
  39. flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate output")
  40. flags.BoolVar(&opts.noResolve, "no-resolve", false, "Do not map IDs to Names")
  41. flags.StringVar(&opts.format, "format", "", "Pretty-print tasks using a Go template")
  42. flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
  43. return cmd
  44. }
  45. func runPS(dockerCli *command.DockerCli, opts psOptions) error {
  46. client := dockerCli.Client()
  47. ctx := context.Background()
  48. filter := opts.filter.Value()
  49. serviceIDFilter := filters.NewArgs()
  50. serviceNameFilter := filters.NewArgs()
  51. for _, service := range opts.services {
  52. // default to container runtime
  53. serviceIDFilter.Add("id", service)
  54. serviceIDFilter.Add("runtimes", string(swarmtypes.RuntimeContainer))
  55. serviceNameFilter.Add("name", service)
  56. serviceNameFilter.Add("runtimes", string(swarmtypes.RuntimeContainer))
  57. }
  58. serviceByIDList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceIDFilter})
  59. if err != nil {
  60. return err
  61. }
  62. serviceByNameList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceNameFilter})
  63. if err != nil {
  64. return err
  65. }
  66. for _, service := range opts.services {
  67. serviceCount := 0
  68. // Lookup by ID/Prefix
  69. for _, serviceEntry := range serviceByIDList {
  70. if strings.HasPrefix(serviceEntry.ID, service) {
  71. filter.Add("service", serviceEntry.ID)
  72. serviceCount++
  73. }
  74. }
  75. // Lookup by Name/Prefix
  76. for _, serviceEntry := range serviceByNameList {
  77. if strings.HasPrefix(serviceEntry.Spec.Annotations.Name, service) {
  78. filter.Add("service", serviceEntry.ID)
  79. serviceCount++
  80. }
  81. }
  82. // If nothing has been found, return immediately.
  83. if serviceCount == 0 {
  84. return errors.Errorf("no such services: %s", service)
  85. }
  86. }
  87. if filter.Include("node") {
  88. nodeFilters := filter.Get("node")
  89. for _, nodeFilter := range nodeFilters {
  90. nodeReference, err := node.Reference(ctx, client, nodeFilter)
  91. if err != nil {
  92. return err
  93. }
  94. filter.Del("node", nodeFilter)
  95. filter.Add("node", nodeReference)
  96. }
  97. }
  98. tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter})
  99. if err != nil {
  100. return err
  101. }
  102. format := opts.format
  103. if len(format) == 0 {
  104. if len(dockerCli.ConfigFile().TasksFormat) > 0 && !opts.quiet {
  105. format = dockerCli.ConfigFile().TasksFormat
  106. } else {
  107. format = formatter.TableFormatKey
  108. }
  109. }
  110. return task.Print(dockerCli, ctx, tasks, idresolver.New(client, opts.noResolve), !opts.noTrunc, opts.quiet, format)
  111. }