github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/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 }