clusters.go 3.4 KB

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