github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/state/store/tasks.go (about) 1 package store 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/docker/swarmkit/api" 8 "github.com/docker/swarmkit/api/naming" 9 memdb "github.com/hashicorp/go-memdb" 10 ) 11 12 const tableTask = "task" 13 14 func init() { 15 register(ObjectStoreConfig{ 16 Table: &memdb.TableSchema{ 17 Name: tableTask, 18 Indexes: map[string]*memdb.IndexSchema{ 19 indexID: { 20 Name: indexID, 21 Unique: true, 22 Indexer: api.TaskIndexerByID{}, 23 }, 24 indexName: { 25 Name: indexName, 26 AllowMissing: true, 27 Indexer: taskIndexerByName{}, 28 }, 29 indexRuntime: { 30 Name: indexRuntime, 31 AllowMissing: true, 32 Indexer: taskIndexerByRuntime{}, 33 }, 34 indexServiceID: { 35 Name: indexServiceID, 36 AllowMissing: true, 37 Indexer: taskIndexerByServiceID{}, 38 }, 39 indexNodeID: { 40 Name: indexNodeID, 41 AllowMissing: true, 42 Indexer: taskIndexerByNodeID{}, 43 }, 44 indexSlot: { 45 Name: indexSlot, 46 AllowMissing: true, 47 Indexer: taskIndexerBySlot{}, 48 }, 49 indexDesiredState: { 50 Name: indexDesiredState, 51 Indexer: taskIndexerByDesiredState{}, 52 }, 53 indexTaskState: { 54 Name: indexTaskState, 55 Indexer: taskIndexerByTaskState{}, 56 }, 57 indexNetwork: { 58 Name: indexNetwork, 59 AllowMissing: true, 60 Indexer: taskIndexerByNetwork{}, 61 }, 62 indexSecret: { 63 Name: indexSecret, 64 AllowMissing: true, 65 Indexer: taskIndexerBySecret{}, 66 }, 67 indexConfig: { 68 Name: indexConfig, 69 AllowMissing: true, 70 Indexer: taskIndexerByConfig{}, 71 }, 72 indexCustom: { 73 Name: indexCustom, 74 Indexer: api.TaskCustomIndexer{}, 75 AllowMissing: true, 76 }, 77 }, 78 }, 79 Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error { 80 var err error 81 snapshot.Tasks, err = FindTasks(tx, All) 82 return err 83 }, 84 Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { 85 toStoreObj := make([]api.StoreObject, len(snapshot.Tasks)) 86 for i, x := range snapshot.Tasks { 87 toStoreObj[i] = x 88 } 89 return RestoreTable(tx, tableTask, toStoreObj) 90 }, 91 ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { 92 switch v := sa.Target.(type) { 93 case *api.StoreAction_Task: 94 obj := v.Task 95 switch sa.Action { 96 case api.StoreActionKindCreate: 97 return CreateTask(tx, obj) 98 case api.StoreActionKindUpdate: 99 return UpdateTask(tx, obj) 100 case api.StoreActionKindRemove: 101 return DeleteTask(tx, obj.ID) 102 } 103 } 104 return errUnknownStoreAction 105 }, 106 }) 107 } 108 109 // CreateTask adds a new task to the store. 110 // Returns ErrExist if the ID is already taken. 111 func CreateTask(tx Tx, t *api.Task) error { 112 return tx.create(tableTask, t) 113 } 114 115 // UpdateTask updates an existing task in the store. 116 // Returns ErrNotExist if the node doesn't exist. 117 func UpdateTask(tx Tx, t *api.Task) error { 118 return tx.update(tableTask, t) 119 } 120 121 // DeleteTask removes a task from the store. 122 // Returns ErrNotExist if the task doesn't exist. 123 func DeleteTask(tx Tx, id string) error { 124 return tx.delete(tableTask, id) 125 } 126 127 // GetTask looks up a task by ID. 128 // Returns nil if the task doesn't exist. 129 func GetTask(tx ReadTx, id string) *api.Task { 130 t := tx.get(tableTask, id) 131 if t == nil { 132 return nil 133 } 134 return t.(*api.Task) 135 } 136 137 // FindTasks selects a set of tasks and returns them. 138 func FindTasks(tx ReadTx, by By) ([]*api.Task, error) { 139 checkType := func(by By) error { 140 switch by.(type) { 141 case byName, byNamePrefix, byIDPrefix, byRuntime, byDesiredState, byTaskState, byNode, byService, bySlot, byReferencedNetworkID, byReferencedSecretID, byReferencedConfigID, byCustom, byCustomPrefix: 142 return nil 143 default: 144 return ErrInvalidFindBy 145 } 146 } 147 148 taskList := []*api.Task{} 149 appendResult := func(o api.StoreObject) { 150 taskList = append(taskList, o.(*api.Task)) 151 } 152 153 err := tx.find(tableTask, by, checkType, appendResult) 154 return taskList, err 155 } 156 157 type taskIndexerByName struct{} 158 159 func (ti taskIndexerByName) FromArgs(args ...interface{}) ([]byte, error) { 160 return fromArgs(args...) 161 } 162 163 func (ti taskIndexerByName) FromObject(obj interface{}) (bool, []byte, error) { 164 t := obj.(*api.Task) 165 166 name := naming.Task(t) 167 168 // Add the null character as a terminator 169 return true, []byte(strings.ToLower(name) + "\x00"), nil 170 } 171 172 func (ti taskIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) { 173 return prefixFromArgs(args...) 174 } 175 176 type taskIndexerByRuntime struct{} 177 178 func (ti taskIndexerByRuntime) FromArgs(args ...interface{}) ([]byte, error) { 179 return fromArgs(args...) 180 } 181 182 func (ti taskIndexerByRuntime) FromObject(obj interface{}) (bool, []byte, error) { 183 t := obj.(*api.Task) 184 r, err := naming.Runtime(t.Spec) 185 if err != nil { 186 return false, nil, nil 187 } 188 return true, []byte(r + "\x00"), nil 189 } 190 191 func (ti taskIndexerByRuntime) PrefixFromArgs(args ...interface{}) ([]byte, error) { 192 return prefixFromArgs(args...) 193 } 194 195 type taskIndexerByServiceID struct{} 196 197 func (ti taskIndexerByServiceID) FromArgs(args ...interface{}) ([]byte, error) { 198 return fromArgs(args...) 199 } 200 201 func (ti taskIndexerByServiceID) FromObject(obj interface{}) (bool, []byte, error) { 202 t := obj.(*api.Task) 203 204 // Add the null character as a terminator 205 val := t.ServiceID + "\x00" 206 return true, []byte(val), nil 207 } 208 209 type taskIndexerByNodeID struct{} 210 211 func (ti taskIndexerByNodeID) FromArgs(args ...interface{}) ([]byte, error) { 212 return fromArgs(args...) 213 } 214 215 func (ti taskIndexerByNodeID) FromObject(obj interface{}) (bool, []byte, error) { 216 t := obj.(*api.Task) 217 218 // Add the null character as a terminator 219 val := t.NodeID + "\x00" 220 return true, []byte(val), nil 221 } 222 223 type taskIndexerBySlot struct{} 224 225 func (ti taskIndexerBySlot) FromArgs(args ...interface{}) ([]byte, error) { 226 return fromArgs(args...) 227 } 228 229 func (ti taskIndexerBySlot) FromObject(obj interface{}) (bool, []byte, error) { 230 t := obj.(*api.Task) 231 232 // Add the null character as a terminator 233 val := t.ServiceID + "\x00" + strconv.FormatUint(t.Slot, 10) + "\x00" 234 return true, []byte(val), nil 235 } 236 237 type taskIndexerByDesiredState struct{} 238 239 func (ti taskIndexerByDesiredState) FromArgs(args ...interface{}) ([]byte, error) { 240 return fromArgs(args...) 241 } 242 243 func (ti taskIndexerByDesiredState) FromObject(obj interface{}) (bool, []byte, error) { 244 t := obj.(*api.Task) 245 246 // Add the null character as a terminator 247 return true, []byte(strconv.FormatInt(int64(t.DesiredState), 10) + "\x00"), nil 248 } 249 250 type taskIndexerByNetwork struct{} 251 252 func (ti taskIndexerByNetwork) FromArgs(args ...interface{}) ([]byte, error) { 253 return fromArgs(args...) 254 } 255 256 func (ti taskIndexerByNetwork) FromObject(obj interface{}) (bool, [][]byte, error) { 257 t := obj.(*api.Task) 258 259 var networkIDs [][]byte 260 261 for _, na := range t.Spec.Networks { 262 // Add the null character as a terminator 263 networkIDs = append(networkIDs, []byte(na.Target+"\x00")) 264 } 265 266 return len(networkIDs) != 0, networkIDs, nil 267 } 268 269 type taskIndexerBySecret struct{} 270 271 func (ti taskIndexerBySecret) FromArgs(args ...interface{}) ([]byte, error) { 272 return fromArgs(args...) 273 } 274 275 func (ti taskIndexerBySecret) FromObject(obj interface{}) (bool, [][]byte, error) { 276 t := obj.(*api.Task) 277 278 container := t.Spec.GetContainer() 279 if container == nil { 280 return false, nil, nil 281 } 282 283 var secretIDs [][]byte 284 285 for _, secretRef := range container.Secrets { 286 // Add the null character as a terminator 287 secretIDs = append(secretIDs, []byte(secretRef.SecretID+"\x00")) 288 } 289 290 return len(secretIDs) != 0, secretIDs, nil 291 } 292 293 type taskIndexerByConfig struct{} 294 295 func (ti taskIndexerByConfig) FromArgs(args ...interface{}) ([]byte, error) { 296 return fromArgs(args...) 297 } 298 299 func (ti taskIndexerByConfig) FromObject(obj interface{}) (bool, [][]byte, error) { 300 t, ok := obj.(*api.Task) 301 if !ok { 302 panic("unexpected type passed to FromObject") 303 } 304 305 container := t.Spec.GetContainer() 306 if container == nil { 307 return false, nil, nil 308 } 309 310 var configIDs [][]byte 311 312 for _, configRef := range container.Configs { 313 // Add the null character as a terminator 314 configIDs = append(configIDs, []byte(configRef.ConfigID+"\x00")) 315 } 316 317 return len(configIDs) != 0, configIDs, nil 318 } 319 320 type taskIndexerByTaskState struct{} 321 322 func (ts taskIndexerByTaskState) FromArgs(args ...interface{}) ([]byte, error) { 323 return fromArgs(args...) 324 } 325 326 func (ts taskIndexerByTaskState) FromObject(obj interface{}) (bool, []byte, error) { 327 t := obj.(*api.Task) 328 329 // Add the null character as a terminator 330 return true, []byte(strconv.FormatInt(int64(t.Status.State), 10) + "\x00"), nil 331 }