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  }