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  }