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