github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/state/store/clusters.go (about) 1 package store 2 3 import ( 4 "strings" 5 6 "github.com/docker/swarmkit/api" 7 memdb "github.com/hashicorp/go-memdb" 8 ) 9 10 const ( 11 tableCluster = "cluster" 12 13 // DefaultClusterName is the default name to use for the cluster 14 // object. 15 DefaultClusterName = "default" 16 ) 17 18 func init() { 19 register(ObjectStoreConfig{ 20 Table: &memdb.TableSchema{ 21 Name: tableCluster, 22 Indexes: map[string]*memdb.IndexSchema{ 23 indexID: { 24 Name: indexID, 25 Unique: true, 26 Indexer: api.ClusterIndexerByID{}, 27 }, 28 indexName: { 29 Name: indexName, 30 Unique: true, 31 Indexer: api.ClusterIndexerByName{}, 32 }, 33 indexCustom: { 34 Name: indexCustom, 35 Indexer: api.ClusterCustomIndexer{}, 36 AllowMissing: true, 37 }, 38 }, 39 }, 40 Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error { 41 var err error 42 snapshot.Clusters, err = FindClusters(tx, All) 43 return err 44 }, 45 Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { 46 toStoreObj := make([]api.StoreObject, len(snapshot.Clusters)) 47 for i, x := range snapshot.Clusters { 48 toStoreObj[i] = x 49 } 50 return RestoreTable(tx, tableCluster, toStoreObj) 51 }, 52 ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { 53 switch v := sa.Target.(type) { 54 case *api.StoreAction_Cluster: 55 obj := v.Cluster 56 switch sa.Action { 57 case api.StoreActionKindCreate: 58 return CreateCluster(tx, obj) 59 case api.StoreActionKindUpdate: 60 return UpdateCluster(tx, obj) 61 case api.StoreActionKindRemove: 62 return DeleteCluster(tx, obj.ID) 63 } 64 } 65 return errUnknownStoreAction 66 }, 67 }) 68 } 69 70 // CreateCluster adds a new cluster to the store. 71 // Returns ErrExist if the ID is already taken. 72 func CreateCluster(tx Tx, c *api.Cluster) error { 73 // Ensure the name is not already in use. 74 if tx.lookup(tableCluster, indexName, strings.ToLower(c.Spec.Annotations.Name)) != nil { 75 return ErrNameConflict 76 } 77 78 return tx.create(tableCluster, c) 79 } 80 81 // UpdateCluster updates an existing cluster in the store. 82 // Returns ErrNotExist if the cluster doesn't exist. 83 func UpdateCluster(tx Tx, c *api.Cluster) error { 84 // Ensure the name is either not in use or already used by this same Cluster. 85 if existing := tx.lookup(tableCluster, indexName, strings.ToLower(c.Spec.Annotations.Name)); existing != nil { 86 if existing.GetID() != c.ID { 87 return ErrNameConflict 88 } 89 } 90 91 return tx.update(tableCluster, c) 92 } 93 94 // DeleteCluster removes a cluster from the store. 95 // Returns ErrNotExist if the cluster doesn't exist. 96 func DeleteCluster(tx Tx, id string) error { 97 return tx.delete(tableCluster, id) 98 } 99 100 // GetCluster looks up a cluster by ID. 101 // Returns nil if the cluster doesn't exist. 102 func GetCluster(tx ReadTx, id string) *api.Cluster { 103 n := tx.get(tableCluster, id) 104 if n == nil { 105 return nil 106 } 107 return n.(*api.Cluster) 108 } 109 110 // FindClusters selects a set of clusters and returns them. 111 func FindClusters(tx ReadTx, by By) ([]*api.Cluster, error) { 112 checkType := func(by By) error { 113 switch by.(type) { 114 case byName, byNamePrefix, byIDPrefix, byCustom, byCustomPrefix: 115 return nil 116 default: 117 return ErrInvalidFindBy 118 } 119 } 120 121 clusterList := []*api.Cluster{} 122 appendResult := func(o api.StoreObject) { 123 clusterList = append(clusterList, o.(*api.Cluster)) 124 } 125 126 err := tx.find(tableCluster, by, checkType, appendResult) 127 return clusterList, err 128 }