github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/state/store/extensions.go (about) 1 package store 2 3 import ( 4 "errors" 5 "strings" 6 7 "github.com/docker/swarmkit/api" 8 memdb "github.com/hashicorp/go-memdb" 9 ) 10 11 const tableExtension = "extension" 12 13 func init() { 14 register(ObjectStoreConfig{ 15 Table: &memdb.TableSchema{ 16 Name: tableExtension, 17 Indexes: map[string]*memdb.IndexSchema{ 18 indexID: { 19 Name: indexID, 20 Unique: true, 21 Indexer: extensionIndexerByID{}, 22 }, 23 indexName: { 24 Name: indexName, 25 Unique: true, 26 Indexer: extensionIndexerByName{}, 27 }, 28 indexCustom: { 29 Name: indexCustom, 30 Indexer: extensionCustomIndexer{}, 31 AllowMissing: true, 32 }, 33 }, 34 }, 35 Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error { 36 var err error 37 snapshot.Extensions, err = FindExtensions(tx, All) 38 return err 39 }, 40 Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { 41 toStoreObj := make([]api.StoreObject, len(snapshot.Extensions)) 42 for i, x := range snapshot.Extensions { 43 toStoreObj[i] = extensionEntry{x} 44 } 45 return RestoreTable(tx, tableExtension, toStoreObj) 46 }, 47 ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { 48 switch v := sa.Target.(type) { 49 case *api.StoreAction_Extension: 50 obj := v.Extension 51 switch sa.Action { 52 case api.StoreActionKindCreate: 53 return CreateExtension(tx, obj) 54 case api.StoreActionKindUpdate: 55 return UpdateExtension(tx, obj) 56 case api.StoreActionKindRemove: 57 return DeleteExtension(tx, obj.ID) 58 } 59 } 60 return errUnknownStoreAction 61 }, 62 }) 63 } 64 65 type extensionEntry struct { 66 *api.Extension 67 } 68 69 func (e extensionEntry) CopyStoreObject() api.StoreObject { 70 return extensionEntry{Extension: e.Extension.Copy()} 71 } 72 73 // ensure that when update events are emitted, we unwrap extensionEntry 74 func (e extensionEntry) EventUpdate(oldObject api.StoreObject) api.Event { 75 if oldObject != nil { 76 return api.EventUpdateExtension{Extension: e.Extension, OldExtension: oldObject.(extensionEntry).Extension} 77 } 78 return api.EventUpdateExtension{Extension: e.Extension} 79 } 80 81 // CreateExtension adds a new extension to the store. 82 // Returns ErrExist if the ID is already taken. 83 func CreateExtension(tx Tx, e *api.Extension) error { 84 // Ensure the name is not already in use. 85 if tx.lookup(tableExtension, indexName, strings.ToLower(e.Annotations.Name)) != nil { 86 return ErrNameConflict 87 } 88 89 // It can't conflict with built-in kinds either. 90 if _, ok := schema.Tables[e.Annotations.Name]; ok { 91 return ErrNameConflict 92 } 93 94 return tx.create(tableExtension, extensionEntry{e}) 95 } 96 97 // UpdateExtension updates an existing extension in the store. 98 // Returns ErrNotExist if the object doesn't exist. 99 func UpdateExtension(tx Tx, e *api.Extension) error { 100 // TODO(aaronl): For the moment, extensions are immutable 101 return errors.New("extensions are immutable") 102 } 103 104 // DeleteExtension removes an extension from the store. 105 // Returns ErrNotExist if the object doesn't exist. 106 func DeleteExtension(tx Tx, id string) error { 107 e := tx.get(tableExtension, id) 108 if e == nil { 109 return ErrNotExist 110 } 111 112 resources, err := FindResources(tx, ByKind(e.(extensionEntry).Annotations.Name)) 113 if err != nil { 114 return err 115 } 116 117 if len(resources) != 0 { 118 return errors.New("cannot delete extension because objects of this type exist in the data store") 119 } 120 121 return tx.delete(tableExtension, id) 122 } 123 124 // GetExtension looks up an extension by ID. 125 // Returns nil if the object doesn't exist. 126 func GetExtension(tx ReadTx, id string) *api.Extension { 127 e := tx.get(tableExtension, id) 128 if e == nil { 129 return nil 130 } 131 return e.(extensionEntry).Extension 132 } 133 134 // FindExtensions selects a set of extensions and returns them. 135 func FindExtensions(tx ReadTx, by By) ([]*api.Extension, error) { 136 checkType := func(by By) error { 137 switch by.(type) { 138 case byIDPrefix, byName, byCustom, byCustomPrefix: 139 return nil 140 default: 141 return ErrInvalidFindBy 142 } 143 } 144 145 extensionList := []*api.Extension{} 146 appendResult := func(o api.StoreObject) { 147 extensionList = append(extensionList, o.(extensionEntry).Extension) 148 } 149 150 err := tx.find(tableExtension, by, checkType, appendResult) 151 return extensionList, err 152 } 153 154 type extensionIndexerByID struct{} 155 156 func (indexer extensionIndexerByID) FromArgs(args ...interface{}) ([]byte, error) { 157 return api.ExtensionIndexerByID{}.FromArgs(args...) 158 } 159 func (indexer extensionIndexerByID) PrefixFromArgs(args ...interface{}) ([]byte, error) { 160 return api.ExtensionIndexerByID{}.PrefixFromArgs(args...) 161 } 162 func (indexer extensionIndexerByID) FromObject(obj interface{}) (bool, []byte, error) { 163 return api.ExtensionIndexerByID{}.FromObject(obj.(extensionEntry).Extension) 164 } 165 166 type extensionIndexerByName struct{} 167 168 func (indexer extensionIndexerByName) FromArgs(args ...interface{}) ([]byte, error) { 169 return api.ExtensionIndexerByName{}.FromArgs(args...) 170 } 171 func (indexer extensionIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) { 172 return api.ExtensionIndexerByName{}.PrefixFromArgs(args...) 173 } 174 func (indexer extensionIndexerByName) FromObject(obj interface{}) (bool, []byte, error) { 175 return api.ExtensionIndexerByName{}.FromObject(obj.(extensionEntry).Extension) 176 } 177 178 type extensionCustomIndexer struct{} 179 180 func (indexer extensionCustomIndexer) FromArgs(args ...interface{}) ([]byte, error) { 181 return api.ExtensionCustomIndexer{}.FromArgs(args...) 182 } 183 func (indexer extensionCustomIndexer) PrefixFromArgs(args ...interface{}) ([]byte, error) { 184 return api.ExtensionCustomIndexer{}.PrefixFromArgs(args...) 185 } 186 func (indexer extensionCustomIndexer) FromObject(obj interface{}) (bool, [][]byte, error) { 187 return api.ExtensionCustomIndexer{}.FromObject(obj.(extensionEntry).Extension) 188 }