github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/volume/drivers/adapter.go (about) 1 package volumedrivers 2 3 import ( 4 "errors" 5 "strings" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/volume" 9 ) 10 11 var ( 12 errNoSuchVolume = errors.New("no such volume") 13 ) 14 15 type volumeDriverAdapter struct { 16 name string 17 capabilities *volume.Capability 18 proxy *volumeDriverProxy 19 } 20 21 func (a *volumeDriverAdapter) Name() string { 22 return a.name 23 } 24 25 func (a *volumeDriverAdapter) Create(name string, opts map[string]string) (volume.Volume, error) { 26 if err := a.proxy.Create(name, opts); err != nil { 27 return nil, err 28 } 29 return &volumeAdapter{ 30 proxy: a.proxy, 31 name: name, 32 driverName: a.name, 33 }, nil 34 } 35 36 func (a *volumeDriverAdapter) Remove(v volume.Volume) error { 37 return a.proxy.Remove(v.Name()) 38 } 39 40 func (a *volumeDriverAdapter) List() ([]volume.Volume, error) { 41 ls, err := a.proxy.List() 42 if err != nil { 43 return nil, err 44 } 45 46 var out []volume.Volume 47 for _, vp := range ls { 48 out = append(out, &volumeAdapter{ 49 proxy: a.proxy, 50 name: vp.Name, 51 driverName: a.name, 52 eMount: vp.Mountpoint, 53 }) 54 } 55 return out, nil 56 } 57 58 func (a *volumeDriverAdapter) Get(name string) (volume.Volume, error) { 59 v, err := a.proxy.Get(name) 60 if err != nil { 61 return nil, err 62 } 63 64 // plugin may have returned no volume and no error 65 if v == nil { 66 return nil, errNoSuchVolume 67 } 68 69 return &volumeAdapter{ 70 proxy: a.proxy, 71 name: v.Name, 72 driverName: a.Name(), 73 eMount: v.Mountpoint, 74 status: v.Status, 75 }, nil 76 } 77 78 func (a *volumeDriverAdapter) Scope() string { 79 cap := a.getCapabilities() 80 return cap.Scope 81 } 82 83 func (a *volumeDriverAdapter) getCapabilities() volume.Capability { 84 if a.capabilities != nil { 85 return *a.capabilities 86 } 87 cap, err := a.proxy.Capabilities() 88 if err != nil { 89 // `GetCapabilities` is a not a required endpoint. 90 // On error assume it's a local-only driver 91 logrus.Warnf("Volume driver %s returned an error while trying to query its capabilities, using default capabilties: %v", a.name, err) 92 return volume.Capability{Scope: volume.LocalScope} 93 } 94 95 // don't spam the warn log below just because the plugin didn't provide a scope 96 if len(cap.Scope) == 0 { 97 cap.Scope = volume.LocalScope 98 } 99 100 cap.Scope = strings.ToLower(cap.Scope) 101 if cap.Scope != volume.LocalScope && cap.Scope != volume.GlobalScope { 102 logrus.Warnf("Volume driver %q returned an invalid scope: %q", a.Name(), cap.Scope) 103 cap.Scope = volume.LocalScope 104 } 105 106 a.capabilities = &cap 107 return cap 108 } 109 110 type volumeAdapter struct { 111 proxy *volumeDriverProxy 112 name string 113 driverName string 114 eMount string // ephemeral host volume path 115 status map[string]interface{} 116 } 117 118 type proxyVolume struct { 119 Name string 120 Mountpoint string 121 Status map[string]interface{} 122 } 123 124 func (a *volumeAdapter) Name() string { 125 return a.name 126 } 127 128 func (a *volumeAdapter) DriverName() string { 129 return a.driverName 130 } 131 132 func (a *volumeAdapter) Path() string { 133 if len(a.eMount) == 0 { 134 a.eMount, _ = a.proxy.Path(a.name) 135 } 136 return a.eMount 137 } 138 139 func (a *volumeAdapter) CachedPath() string { 140 return a.eMount 141 } 142 143 func (a *volumeAdapter) Mount(id string) (string, error) { 144 var err error 145 a.eMount, err = a.proxy.Mount(a.name, id) 146 return a.eMount, err 147 } 148 149 func (a *volumeAdapter) Unmount(id string) error { 150 err := a.proxy.Unmount(a.name, id) 151 if err == nil { 152 a.eMount = "" 153 } 154 return err 155 } 156 157 func (a *volumeAdapter) Status() map[string]interface{} { 158 out := make(map[string]interface{}, len(a.status)) 159 for k, v := range a.status { 160 out[k] = v 161 } 162 return out 163 }