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