github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/controlapi/task.go (about) 1 package controlapi 2 3 import ( 4 "context" 5 6 "github.com/docker/swarmkit/api" 7 "github.com/docker/swarmkit/api/naming" 8 "github.com/docker/swarmkit/manager/orchestrator" 9 "github.com/docker/swarmkit/manager/state/store" 10 "google.golang.org/grpc/codes" 11 "google.golang.org/grpc/status" 12 ) 13 14 // GetTask returns a Task given a TaskID. 15 // - Returns `InvalidArgument` if TaskID is not provided. 16 // - Returns `NotFound` if the Task is not found. 17 func (s *Server) GetTask(ctx context.Context, request *api.GetTaskRequest) (*api.GetTaskResponse, error) { 18 if request.TaskID == "" { 19 return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error()) 20 } 21 22 var task *api.Task 23 s.store.View(func(tx store.ReadTx) { 24 task = store.GetTask(tx, request.TaskID) 25 }) 26 if task == nil { 27 return nil, status.Errorf(codes.NotFound, "task %s not found", request.TaskID) 28 } 29 return &api.GetTaskResponse{ 30 Task: task, 31 }, nil 32 } 33 34 // RemoveTask removes a Task referenced by TaskID. 35 // - Returns `InvalidArgument` if TaskID is not provided. 36 // - Returns `NotFound` if the Task is not found. 37 // - Returns an error if the deletion fails. 38 func (s *Server) RemoveTask(ctx context.Context, request *api.RemoveTaskRequest) (*api.RemoveTaskResponse, error) { 39 if request.TaskID == "" { 40 return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error()) 41 } 42 43 err := s.store.Update(func(tx store.Tx) error { 44 return store.DeleteTask(tx, request.TaskID) 45 }) 46 if err != nil { 47 if err == store.ErrNotExist { 48 return nil, status.Errorf(codes.NotFound, "task %s not found", request.TaskID) 49 } 50 return nil, err 51 } 52 return &api.RemoveTaskResponse{}, nil 53 } 54 55 func filterTasks(candidates []*api.Task, filters ...func(*api.Task) bool) []*api.Task { 56 result := []*api.Task{} 57 58 for _, c := range candidates { 59 match := true 60 for _, f := range filters { 61 if !f(c) { 62 match = false 63 break 64 } 65 } 66 if match { 67 result = append(result, c) 68 } 69 } 70 71 return result 72 } 73 74 // ListTasks returns a list of all tasks. 75 func (s *Server) ListTasks(ctx context.Context, request *api.ListTasksRequest) (*api.ListTasksResponse, error) { 76 var ( 77 tasks []*api.Task 78 err error 79 ) 80 81 s.store.View(func(tx store.ReadTx) { 82 switch { 83 case request.Filters != nil && len(request.Filters.Names) > 0: 84 tasks, err = store.FindTasks(tx, buildFilters(store.ByName, request.Filters.Names)) 85 case request.Filters != nil && len(request.Filters.NamePrefixes) > 0: 86 tasks, err = store.FindTasks(tx, buildFilters(store.ByNamePrefix, request.Filters.NamePrefixes)) 87 case request.Filters != nil && len(request.Filters.IDPrefixes) > 0: 88 tasks, err = store.FindTasks(tx, buildFilters(store.ByIDPrefix, request.Filters.IDPrefixes)) 89 case request.Filters != nil && len(request.Filters.ServiceIDs) > 0: 90 tasks, err = store.FindTasks(tx, buildFilters(store.ByServiceID, request.Filters.ServiceIDs)) 91 case request.Filters != nil && len(request.Filters.Runtimes) > 0: 92 tasks, err = store.FindTasks(tx, buildFilters(store.ByRuntime, request.Filters.Runtimes)) 93 case request.Filters != nil && len(request.Filters.NodeIDs) > 0: 94 tasks, err = store.FindTasks(tx, buildFilters(store.ByNodeID, request.Filters.NodeIDs)) 95 case request.Filters != nil && len(request.Filters.DesiredStates) > 0: 96 filters := make([]store.By, 0, len(request.Filters.DesiredStates)) 97 for _, v := range request.Filters.DesiredStates { 98 filters = append(filters, store.ByDesiredState(v)) 99 } 100 tasks, err = store.FindTasks(tx, store.Or(filters...)) 101 default: 102 tasks, err = store.FindTasks(tx, store.All) 103 } 104 105 if err != nil || request.Filters == nil { 106 return 107 } 108 109 tasks = filterTasks(tasks, 110 func(e *api.Task) bool { 111 return filterContains(naming.Task(e), request.Filters.Names) 112 }, 113 func(e *api.Task) bool { 114 return filterContainsPrefix(naming.Task(e), request.Filters.NamePrefixes) 115 }, 116 func(e *api.Task) bool { 117 return filterContainsPrefix(e.ID, request.Filters.IDPrefixes) 118 }, 119 func(e *api.Task) bool { 120 return filterMatchLabels(e.ServiceAnnotations.Labels, request.Filters.Labels) 121 }, 122 func(e *api.Task) bool { 123 return filterContains(e.ServiceID, request.Filters.ServiceIDs) 124 }, 125 func(e *api.Task) bool { 126 return filterContains(e.NodeID, request.Filters.NodeIDs) 127 }, 128 func(e *api.Task) bool { 129 if len(request.Filters.Runtimes) == 0 { 130 return true 131 } 132 r, err := naming.Runtime(e.Spec) 133 if err != nil { 134 return false 135 } 136 return filterContains(r, request.Filters.Runtimes) 137 }, 138 func(e *api.Task) bool { 139 if len(request.Filters.DesiredStates) == 0 { 140 return true 141 } 142 for _, c := range request.Filters.DesiredStates { 143 if c == e.DesiredState { 144 return true 145 } 146 } 147 return false 148 }, 149 func(e *api.Task) bool { 150 if !request.Filters.UpToDate { 151 return true 152 } 153 154 service := store.GetService(tx, e.ServiceID) 155 if service == nil { 156 return false 157 } 158 159 n := store.GetNode(tx, e.NodeID) 160 return !orchestrator.IsTaskDirty(service, e, n) 161 }, 162 ) 163 }) 164 165 if err != nil { 166 return nil, err 167 } 168 169 return &api.ListTasksResponse{ 170 Tasks: tasks, 171 }, nil 172 }