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