|
| 1 | +package factory |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + |
| 6 | + "github.com/docker/docker-registry/storagedriver" |
| 7 | + "github.com/docker/docker-registry/storagedriver/ipc" |
| 8 | +) |
| 9 | + |
| 10 | +// Internal mapping between storage driver names and their respective factories |
| 11 | +var driverFactories = make(map[string]StorageDriverFactory) |
| 12 | + |
| 13 | +// Factory interface for the storagedriver.StorageDriver interface |
| 14 | +// Storage drivers should call Register() with a factory to make the driver available by name |
| 15 | +type StorageDriverFactory interface { |
| 16 | + // Creates and returns a new storagedriver.StorageDriver with the given parameters |
| 17 | + // Parameters will vary by driver and may be ignored |
| 18 | + // Each parameter key must only consist of lowercase letters and numbers |
| 19 | + Create(parameters map[string]string) (storagedriver.StorageDriver, error) |
| 20 | +} |
| 21 | + |
| 22 | +// Register makes a storage driver available by the provided name. |
| 23 | +// If Register is called twice with the same name or if driver factory is nil, it panics. |
| 24 | +func Register(name string, factory StorageDriverFactory) { |
| 25 | + if factory == nil { |
| 26 | + panic("Must not provide nil StorageDriverFactory") |
| 27 | + } |
| 28 | + _, registered := driverFactories[name] |
| 29 | + if registered { |
| 30 | + panic(fmt.Sprintf("StorageDriverFactory named %s already registered", name)) |
| 31 | + } |
| 32 | + |
| 33 | + driverFactories[name] = factory |
| 34 | +} |
| 35 | + |
| 36 | +// Create a new storagedriver.StorageDriver with the given name and parameters |
| 37 | +// To run in-process, the StorageDriverFactory must first be registered with the given name |
| 38 | +// If no in-process drivers are found with the given name, this attempts to create an IPC driver |
| 39 | +// If no in-process or external drivers are found, an InvalidStorageDriverError is returned |
| 40 | +func Create(name string, parameters map[string]string) (storagedriver.StorageDriver, error) { |
| 41 | + driverFactory, ok := driverFactories[name] |
| 42 | + if !ok { |
| 43 | + // No registered StorageDriverFactory found, try ipc |
| 44 | + driverClient, err := ipc.NewDriverClient(name, parameters) |
| 45 | + if err != nil { |
| 46 | + return nil, InvalidStorageDriverError{name} |
| 47 | + } |
| 48 | + err = driverClient.Start() |
| 49 | + if err != nil { |
| 50 | + return nil, err |
| 51 | + } |
| 52 | + return driverClient, nil |
| 53 | + } |
| 54 | + return driverFactory.Create(parameters) |
| 55 | +} |
| 56 | + |
| 57 | +// Error returned when attempting 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 | +} |
0 commit comments