1 package factory 2 3 import ( 4 "fmt" 5 6 storagedriver "github.com/docker/distribution/registry/storage/driver" 7 ) 8 9 // driverFactories stores an internal mapping between storage driver names and their respective 10 // factories 11 var driverFactories = make(map[string]StorageDriverFactory) 12 13 // StorageDriverFactory is a factory interface for creating storagedriver.StorageDriver interfaces 14 // Storage drivers should call Register() with a factory to make the driver available by name. 15 // Individual StorageDriver implementations generally register with the factory via the Register 16 // func (below) in their init() funcs, and as such they should be imported anonymously before use. 17 // See below for an example of how to register and get a StorageDriver for S3 18 // 19 // import _ "github.com/docker/distribution/registry/storage/driver/s3-aws" 20 // s3Driver, err = factory.Create("s3", storageParams) 21 // // assuming no error, s3Driver is the StorageDriver that communicates with S3 according to storageParams 22 type StorageDriverFactory interface { 23 // Create returns a new storagedriver.StorageDriver with the given parameters 24 // Parameters will vary by driver and may be ignored 25 // Each parameter key must only consist of lowercase letters and numbers 26 Create(parameters map[string]interface{}) (storagedriver.StorageDriver, error) 27 } 28 29 // Register makes a storage driver available by the provided name. 30 // If Register is called twice with the same name or if driver factory is nil, it panics. 31 // Additionally, it is not concurrency safe. Most Storage Drivers call this function 32 // in their init() functions. See the documentation for StorageDriverFactory for more. 33 func Register(name string, factory StorageDriverFactory) { 34 if factory == nil { 35 panic("Must not provide nil StorageDriverFactory") 36 } 37 _, registered := driverFactories[name] 38 if registered { 39 panic(fmt.Sprintf("StorageDriverFactory named %s already registered", name)) 40 } 41 42 driverFactories[name] = factory 43 } 44 45 // Create a new storagedriver.StorageDriver with the given name and 46 // parameters. To use a driver, the StorageDriverFactory must first be 47 // registered with the given name. If no drivers are found, an 48 // InvalidStorageDriverError is returned 49 func Create(name string, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { 50 driverFactory, ok := driverFactories[name] 51 if !ok { 52 return nil, InvalidStorageDriverError{name} 53 } 54 return driverFactory.Create(parameters) 55 } 56 57 // InvalidStorageDriverError records an attempt to construct an unregistered storage driver 58 type InvalidStorageDriverError struct { 59 Name string 60 } 61 62 func (err InvalidStorageDriverError) Error() string { 63 return fmt.Sprintf("StorageDriver not registered: %s", err.Name) 64 } 65