github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/volume/drivers/extpoint.go (about) 1 //go:generate pluginrpc-gen -i $GOFILE -o proxy.go -type volumeDriver -name VolumeDriver 2 3 package volumedrivers 4 5 import ( 6 "fmt" 7 "sync" 8 9 "github.com/docker/docker/pkg/plugins" 10 "github.com/docker/docker/volume" 11 ) 12 13 // currently created by hand. generation tool would generate this like: 14 // $ extpoint-gen Driver > volume/extpoint.go 15 16 var drivers = &driverExtpoint{extensions: make(map[string]volume.Driver)} 17 18 const extName = "VolumeDriver" 19 20 // NewVolumeDriver returns a driver has the given name mapped on the given client. 21 func NewVolumeDriver(name string, c client) volume.Driver { 22 proxy := &volumeDriverProxy{c} 23 return &volumeDriverAdapter{name, proxy} 24 } 25 26 type opts map[string]string 27 type list []*proxyVolume 28 29 // volumeDriver defines the available functions that volume plugins must implement. 30 // This interface is only defined to generate the proxy objects. 31 // It's not intended to be public or reused. 32 type volumeDriver interface { 33 // Create a volume with the given name 34 Create(name string, opts opts) (err error) 35 // Remove the volume with the given name 36 Remove(name string) (err error) 37 // Get the mountpoint of the given volume 38 Path(name string) (mountpoint string, err error) 39 // Mount the given volume and return the mountpoint 40 Mount(name string) (mountpoint string, err error) 41 // Unmount the given volume 42 Unmount(name string) (err error) 43 // List lists all the volumes known to the driver 44 List() (volumes list, err error) 45 // Get retreives the volume with the requested name 46 Get(name string) (volume *proxyVolume, err error) 47 } 48 49 type driverExtpoint struct { 50 extensions map[string]volume.Driver 51 sync.Mutex 52 } 53 54 // Register associates the given driver to the given name, checking if 55 // the name is already associated 56 func Register(extension volume.Driver, name string) bool { 57 drivers.Lock() 58 defer drivers.Unlock() 59 if name == "" { 60 return false 61 } 62 _, exists := drivers.extensions[name] 63 if exists { 64 return false 65 } 66 drivers.extensions[name] = extension 67 return true 68 } 69 70 // Unregister dissociates the name from it's driver, if the association exists. 71 func Unregister(name string) bool { 72 drivers.Lock() 73 defer drivers.Unlock() 74 _, exists := drivers.extensions[name] 75 if !exists { 76 return false 77 } 78 delete(drivers.extensions, name) 79 return true 80 } 81 82 // Lookup returns the driver associated with the given name. If a 83 // driver with the given name has not been registered it checks if 84 // there is a VolumeDriver plugin available with the given name. 85 func Lookup(name string) (volume.Driver, error) { 86 drivers.Lock() 87 ext, ok := drivers.extensions[name] 88 drivers.Unlock() 89 if ok { 90 return ext, nil 91 } 92 pl, err := plugins.Get(name, extName) 93 if err != nil { 94 return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err) 95 } 96 97 drivers.Lock() 98 defer drivers.Unlock() 99 if ext, ok := drivers.extensions[name]; ok { 100 return ext, nil 101 } 102 103 d := NewVolumeDriver(name, pl.Client) 104 drivers.extensions[name] = d 105 return d, nil 106 } 107 108 // GetDriver returns a volume driver by it's name. 109 // If the driver is empty, it looks for the local driver. 110 func GetDriver(name string) (volume.Driver, error) { 111 if name == "" { 112 name = volume.DefaultDriverName 113 } 114 return Lookup(name) 115 } 116 117 // GetDriverList returns list of volume drivers registered. 118 // If no driver is registered, empty string list will be returned. 119 func GetDriverList() []string { 120 var driverList []string 121 for driverName := range drivers.extensions { 122 driverList = append(driverList, driverName) 123 } 124 return driverList 125 } 126 127 // GetAllDrivers lists all the registered drivers 128 func GetAllDrivers() ([]volume.Driver, error) { 129 plugins, err := plugins.GetAll(extName) 130 if err != nil { 131 return nil, err 132 } 133 var ds []volume.Driver 134 135 drivers.Lock() 136 defer drivers.Unlock() 137 138 for _, d := range drivers.extensions { 139 ds = append(ds, d) 140 } 141 142 for _, p := range plugins { 143 ext, ok := drivers.extensions[p.Name] 144 if ok { 145 continue 146 } 147 ext = NewVolumeDriver(p.Name, p.Client) 148 drivers.extensions[p.Name] = ext 149 ds = append(ds, ext) 150 } 151 return ds, nil 152 }