123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package store
- import (
- "errors"
- "strings"
- "github.com/docker/swarmkit/api"
- memdb "github.com/hashicorp/go-memdb"
- )
- const tableExtension = "extension"
- func init() {
- register(ObjectStoreConfig{
- Table: &memdb.TableSchema{
- Name: tableExtension,
- Indexes: map[string]*memdb.IndexSchema{
- indexID: {
- Name: indexID,
- Unique: true,
- Indexer: extensionIndexerByID{},
- },
- indexName: {
- Name: indexName,
- Unique: true,
- Indexer: extensionIndexerByName{},
- },
- indexCustom: {
- Name: indexCustom,
- Indexer: extensionCustomIndexer{},
- AllowMissing: true,
- },
- },
- },
- Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error {
- var err error
- snapshot.Extensions, err = FindExtensions(tx, All)
- return err
- },
- Restore: func(tx Tx, snapshot *api.StoreSnapshot) error {
- extensions, err := FindExtensions(tx, All)
- if err != nil {
- return err
- }
- for _, e := range extensions {
- if err := DeleteExtension(tx, e.ID); err != nil {
- return err
- }
- }
- for _, e := range snapshot.Extensions {
- if err := CreateExtension(tx, e); err != nil {
- return err
- }
- }
- return nil
- },
- ApplyStoreAction: func(tx Tx, sa api.StoreAction) error {
- switch v := sa.Target.(type) {
- case *api.StoreAction_Extension:
- obj := v.Extension
- switch sa.Action {
- case api.StoreActionKindCreate:
- return CreateExtension(tx, obj)
- case api.StoreActionKindUpdate:
- return UpdateExtension(tx, obj)
- case api.StoreActionKindRemove:
- return DeleteExtension(tx, obj.ID)
- }
- }
- return errUnknownStoreAction
- },
- })
- }
- type extensionEntry struct {
- *api.Extension
- }
- func (e extensionEntry) CopyStoreObject() api.StoreObject {
- return extensionEntry{Extension: e.Extension.Copy()}
- }
- // CreateExtension adds a new extension to the store.
- // Returns ErrExist if the ID is already taken.
- func CreateExtension(tx Tx, e *api.Extension) error {
- // Ensure the name is not already in use.
- if tx.lookup(tableExtension, indexName, strings.ToLower(e.Annotations.Name)) != nil {
- return ErrNameConflict
- }
- // It can't conflict with built-in kinds either.
- if _, ok := schema.Tables[e.Annotations.Name]; ok {
- return ErrNameConflict
- }
- return tx.create(tableExtension, extensionEntry{e})
- }
- // UpdateExtension updates an existing extension in the store.
- // Returns ErrNotExist if the object doesn't exist.
- func UpdateExtension(tx Tx, e *api.Extension) error {
- // TODO(aaronl): For the moment, extensions are immutable
- return errors.New("extensions are immutable")
- }
- // DeleteExtension removes an extension from the store.
- // Returns ErrNotExist if the object doesn't exist.
- func DeleteExtension(tx Tx, id string) error {
- e := tx.get(tableExtension, id)
- if e == nil {
- return ErrNotExist
- }
- resources, err := FindResources(tx, ByKind(e.(extensionEntry).Annotations.Name))
- if err != nil {
- return err
- }
- if len(resources) != 0 {
- return errors.New("cannot delete extension because objects of this type exist in the data store")
- }
- return tx.delete(tableExtension, id)
- }
- // GetExtension looks up an extension by ID.
- // Returns nil if the object doesn't exist.
- func GetExtension(tx ReadTx, id string) *api.Extension {
- e := tx.get(tableExtension, id)
- if e == nil {
- return nil
- }
- return e.(extensionEntry).Extension
- }
- // FindExtensions selects a set of extensions and returns them.
- func FindExtensions(tx ReadTx, by By) ([]*api.Extension, error) {
- checkType := func(by By) error {
- switch by.(type) {
- case byIDPrefix, byName, byCustom, byCustomPrefix:
- return nil
- default:
- return ErrInvalidFindBy
- }
- }
- extensionList := []*api.Extension{}
- appendResult := func(o api.StoreObject) {
- extensionList = append(extensionList, o.(extensionEntry).Extension)
- }
- err := tx.find(tableExtension, by, checkType, appendResult)
- return extensionList, err
- }
- type extensionIndexerByID struct{}
- func (indexer extensionIndexerByID) FromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionIndexerByID{}.FromArgs(args...)
- }
- func (indexer extensionIndexerByID) PrefixFromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionIndexerByID{}.PrefixFromArgs(args...)
- }
- func (indexer extensionIndexerByID) FromObject(obj interface{}) (bool, []byte, error) {
- return api.ExtensionIndexerByID{}.FromObject(obj.(extensionEntry).Extension)
- }
- type extensionIndexerByName struct{}
- func (indexer extensionIndexerByName) FromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionIndexerByName{}.FromArgs(args...)
- }
- func (indexer extensionIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionIndexerByName{}.PrefixFromArgs(args...)
- }
- func (indexer extensionIndexerByName) FromObject(obj interface{}) (bool, []byte, error) {
- return api.ExtensionIndexerByName{}.FromObject(obj.(extensionEntry).Extension)
- }
- type extensionCustomIndexer struct{}
- func (indexer extensionCustomIndexer) FromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionCustomIndexer{}.FromArgs(args...)
- }
- func (indexer extensionCustomIndexer) PrefixFromArgs(args ...interface{}) ([]byte, error) {
- return api.ExtensionCustomIndexer{}.PrefixFromArgs(args...)
- }
- func (indexer extensionCustomIndexer) FromObject(obj interface{}) (bool, [][]byte, error) {
- return api.ExtensionCustomIndexer{}.FromObject(obj.(extensionEntry).Extension)
- }
|