github.com/containerd/Containerd@v1.4.13/runtime/task_list.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package runtime
    18  
    19  import (
    20  	"context"
    21  	"sync"
    22  
    23  	"github.com/containerd/containerd/namespaces"
    24  	"github.com/pkg/errors"
    25  )
    26  
    27  var (
    28  	// ErrTaskNotExists is returned when a task does not exist
    29  	ErrTaskNotExists = errors.New("task does not exist")
    30  	// ErrTaskAlreadyExists is returned when a task already exists
    31  	ErrTaskAlreadyExists = errors.New("task already exists")
    32  )
    33  
    34  // NewTaskList returns a new TaskList
    35  func NewTaskList() *TaskList {
    36  	return &TaskList{
    37  		tasks: make(map[string]map[string]Task),
    38  	}
    39  }
    40  
    41  // TaskList holds and provides locking around tasks
    42  type TaskList struct {
    43  	mu    sync.Mutex
    44  	tasks map[string]map[string]Task
    45  }
    46  
    47  // Get a task
    48  func (l *TaskList) Get(ctx context.Context, id string) (Task, error) {
    49  	l.mu.Lock()
    50  	defer l.mu.Unlock()
    51  	namespace, err := namespaces.NamespaceRequired(ctx)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	tasks, ok := l.tasks[namespace]
    56  	if !ok {
    57  		return nil, ErrTaskNotExists
    58  	}
    59  	t, ok := tasks[id]
    60  	if !ok {
    61  		return nil, ErrTaskNotExists
    62  	}
    63  	return t, nil
    64  }
    65  
    66  // GetAll tasks under a namespace
    67  func (l *TaskList) GetAll(ctx context.Context, noNS bool) ([]Task, error) {
    68  	l.mu.Lock()
    69  	defer l.mu.Unlock()
    70  	var o []Task
    71  	if noNS {
    72  		for ns := range l.tasks {
    73  			for _, t := range l.tasks[ns] {
    74  				o = append(o, t)
    75  			}
    76  		}
    77  		return o, nil
    78  	}
    79  	namespace, err := namespaces.NamespaceRequired(ctx)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	tasks, ok := l.tasks[namespace]
    84  	if !ok {
    85  		return o, nil
    86  	}
    87  	for _, t := range tasks {
    88  		o = append(o, t)
    89  	}
    90  	return o, nil
    91  }
    92  
    93  // Add a task
    94  func (l *TaskList) Add(ctx context.Context, t Task) error {
    95  	namespace, err := namespaces.NamespaceRequired(ctx)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	return l.AddWithNamespace(namespace, t)
   100  }
   101  
   102  // AddWithNamespace adds a task with the provided namespace
   103  func (l *TaskList) AddWithNamespace(namespace string, t Task) error {
   104  	l.mu.Lock()
   105  	defer l.mu.Unlock()
   106  
   107  	id := t.ID()
   108  	if _, ok := l.tasks[namespace]; !ok {
   109  		l.tasks[namespace] = make(map[string]Task)
   110  	}
   111  	if _, ok := l.tasks[namespace][id]; ok {
   112  		return errors.Wrap(ErrTaskAlreadyExists, id)
   113  	}
   114  	l.tasks[namespace][id] = t
   115  	return nil
   116  }
   117  
   118  // Delete a task
   119  func (l *TaskList) Delete(ctx context.Context, id string) {
   120  	l.mu.Lock()
   121  	defer l.mu.Unlock()
   122  	namespace, err := namespaces.NamespaceRequired(ctx)
   123  	if err != nil {
   124  		return
   125  	}
   126  	tasks, ok := l.tasks[namespace]
   127  	if ok {
   128  		delete(tasks, id)
   129  	}
   130  }