github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/list.go (about) 1 package service 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "text/tabwriter" 8 9 "github.com/docker/swarmkit/api" 10 "github.com/docker/swarmkit/cmd/swarmctl/common" 11 "github.com/spf13/cobra" 12 ) 13 14 var ( 15 listCmd = &cobra.Command{ 16 Use: "ls", 17 Short: "List services", 18 RunE: func(cmd *cobra.Command, args []string) error { 19 if len(args) != 0 { 20 return errors.New("ls command takes no arguments") 21 } 22 23 flags := cmd.Flags() 24 25 quiet, err := flags.GetBool("quiet") 26 if err != nil { 27 return err 28 } 29 30 c, err := common.Dial(cmd) 31 if err != nil { 32 return err 33 } 34 r, err := c.ListServices(common.Context(cmd), &api.ListServicesRequest{}) 35 if err != nil { 36 return err 37 } 38 39 nr, err := c.ListNodes(common.Context(cmd), &api.ListNodesRequest{}) 40 if err != nil { 41 return err 42 } 43 liveNodes := make(map[string]struct{}) 44 for _, n := range nr.Nodes { 45 if n.Status.State != api.NodeStatus_DOWN { 46 liveNodes[n.ID] = struct{}{} 47 } 48 } 49 50 var output func(j *api.Service) 51 52 if !quiet { 53 tr, err := c.ListTasks(common.Context(cmd), &api.ListTasksRequest{}) 54 if err != nil { 55 return err 56 } 57 58 running := map[string]int{} 59 for _, task := range tr.Tasks { 60 if _, nodeLive := liveNodes[task.NodeID]; nodeLive && 61 task.Status.State == api.TaskStateRunning { 62 running[task.ServiceID]++ 63 } 64 } 65 66 w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0) 67 defer func() { 68 // Ignore flushing errors - there's nothing we can do. 69 _ = w.Flush() 70 }() 71 common.PrintHeader(w, "ID", "Name", "Image", "Replicas") 72 output = func(s *api.Service) { 73 spec := s.Spec 74 var reference string 75 76 if spec.Task.GetContainer() != nil { 77 reference = spec.Task.GetContainer().Image 78 } 79 80 fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", 81 s.ID, 82 spec.Annotations.Name, 83 reference, 84 getServiceReplicasTxt(s, running[s.ID]), 85 ) 86 } 87 88 } else { 89 output = func(j *api.Service) { fmt.Println(j.ID) } 90 } 91 92 for _, j := range r.Services { 93 output(j) 94 } 95 return nil 96 }, 97 } 98 ) 99 100 func init() { 101 listCmd.Flags().BoolP("quiet", "q", false, "Only display IDs") 102 }