2018-03-19 17:16:26 -04:00
package drivers // import "github.com/docker/docker/volume/drivers"
2015-05-19 16:05:25 -04:00
2016-02-24 20:45:38 -05:00
import (
2016-04-11 11:17:52 -04:00
"errors"
"strings"
2017-05-17 17:19:13 -04:00
"time"
2016-02-24 20:45:38 -05:00
"github.com/docker/docker/volume"
2017-07-26 17:42:13 -04:00
"github.com/sirupsen/logrus"
2016-02-24 20:45:38 -05:00
)
2015-05-19 16:05:25 -04:00
2016-04-11 11:17:52 -04:00
var (
errNoSuchVolume = errors . New ( "no such volume" )
)
2015-05-19 16:05:25 -04:00
type volumeDriverAdapter struct {
2016-04-11 11:17:52 -04:00
name string
2017-12-14 10:27:10 -05:00
scopePath func ( s string ) string
2016-04-11 11:17:52 -04:00
capabilities * volume . Capability
2018-04-24 21:45:00 -04:00
proxy volumeDriver
2015-05-19 16:05:25 -04:00
}
func ( a * volumeDriverAdapter ) Name ( ) string {
return a . name
}
2015-06-12 09:25:32 -04:00
func ( a * volumeDriverAdapter ) Create ( name string , opts map [ string ] string ) ( volume . Volume , error ) {
2016-02-10 12:19:32 -05:00
if err := a . proxy . Create ( name , opts ) ; err != nil {
2015-05-19 16:05:25 -04:00
return nil , err
}
2015-05-22 13:37:00 -04:00
return & volumeAdapter {
2017-12-14 10:27:10 -05:00
proxy : a . proxy ,
name : name ,
driverName : a . name ,
scopePath : a . scopePath ,
2016-03-16 17:52:34 -04:00
} , nil
2015-05-19 16:05:25 -04:00
}
func ( a * volumeDriverAdapter ) Remove ( v volume . Volume ) error {
return a . proxy . Remove ( v . Name ( ) )
}
2015-09-23 16:29:14 -04:00
func ( a * volumeDriverAdapter ) List ( ) ( [ ] volume . Volume , error ) {
ls , err := a . proxy . List ( )
if err != nil {
return nil , err
}
var out [ ] volume . Volume
for _ , vp := range ls {
out = append ( out , & volumeAdapter {
2017-12-14 10:27:10 -05:00
proxy : a . proxy ,
name : vp . Name ,
scopePath : a . scopePath ,
driverName : a . name ,
eMount : a . scopePath ( vp . Mountpoint ) ,
2015-09-23 16:29:14 -04:00
} )
}
return out , nil
}
func ( a * volumeDriverAdapter ) Get ( name string ) ( volume . Volume , error ) {
v , err := a . proxy . Get ( name )
if err != nil {
2016-02-10 12:19:32 -05:00
return nil , err
2015-09-23 16:29:14 -04:00
}
2016-02-24 20:45:38 -05:00
// plugin may have returned no volume and no error
if v == nil {
2016-04-11 11:17:52 -04:00
return nil , errNoSuchVolume
2016-02-24 20:45:38 -05:00
}
2015-09-23 16:29:14 -04:00
return & volumeAdapter {
2017-12-14 10:27:10 -05:00
proxy : a . proxy ,
name : v . Name ,
driverName : a . Name ( ) ,
eMount : v . Mountpoint ,
createdAt : v . CreatedAt ,
status : v . Status ,
scopePath : a . scopePath ,
2015-09-23 16:29:14 -04:00
} , nil
}
2016-04-11 11:17:52 -04:00
func ( a * volumeDriverAdapter ) Scope ( ) string {
cap := a . getCapabilities ( )
return cap . Scope
}
func ( a * volumeDriverAdapter ) getCapabilities ( ) volume . Capability {
if a . capabilities != nil {
return * a . capabilities
}
cap , err := a . proxy . Capabilities ( )
if err != nil {
// `GetCapabilities` is a not a required endpoint.
// On error assume it's a local-only driver
2018-03-22 17:11:03 -04:00
logrus . WithError ( err ) . WithField ( "driver" , a . name ) . Debug ( "Volume driver returned an error while trying to query its capabilities, using default capabilities" )
2016-04-11 11:17:52 -04:00
return volume . Capability { Scope : volume . LocalScope }
}
// don't spam the warn log below just because the plugin didn't provide a scope
if len ( cap . Scope ) == 0 {
cap . Scope = volume . LocalScope
}
cap . Scope = strings . ToLower ( cap . Scope )
if cap . Scope != volume . LocalScope && cap . Scope != volume . GlobalScope {
2018-03-22 17:11:03 -04:00
logrus . WithField ( "driver" , a . Name ( ) ) . WithField ( "scope" , a . Scope ) . Warn ( "Volume driver returned an invalid scope" )
2016-04-11 11:17:52 -04:00
cap . Scope = volume . LocalScope
}
a . capabilities = & cap
return cap
}
2015-05-19 16:05:25 -04:00
type volumeAdapter struct {
2018-04-24 21:45:00 -04:00
proxy volumeDriver
2017-12-14 10:27:10 -05:00
name string
scopePath func ( string ) string
driverName string
eMount string // ephemeral host volume path
createdAt time . Time // time the directory was created
status map [ string ] interface { }
2015-05-19 16:05:25 -04:00
}
2015-06-12 09:25:32 -04:00
type proxyVolume struct {
Name string
Mountpoint string
2017-05-17 17:19:13 -04:00
CreatedAt time . Time
2016-03-07 15:44:43 -05:00
Status map [ string ] interface { }
2015-06-12 09:25:32 -04:00
}
2015-05-19 16:05:25 -04:00
func ( a * volumeAdapter ) Name ( ) string {
return a . name
}
func ( a * volumeAdapter ) DriverName ( ) string {
return a . driverName
}
func ( a * volumeAdapter ) Path ( ) string {
2016-04-12 17:09:55 -04:00
if len ( a . eMount ) == 0 {
2016-11-22 14:21:34 -05:00
mountpoint , _ := a . proxy . Path ( a . name )
2017-12-14 10:27:10 -05:00
a . eMount = a . scopePath ( mountpoint )
2015-05-22 13:37:00 -04:00
}
2016-04-12 17:09:55 -04:00
return a . eMount
}
func ( a * volumeAdapter ) CachedPath ( ) string {
return a . eMount
2015-05-19 16:05:25 -04:00
}
2016-03-07 21:41:44 -05:00
func ( a * volumeAdapter ) Mount ( id string ) ( string , error ) {
2016-11-22 14:21:34 -05:00
mountpoint , err := a . proxy . Mount ( a . name , id )
2017-12-14 10:27:10 -05:00
a . eMount = a . scopePath ( mountpoint )
2015-05-22 13:37:00 -04:00
return a . eMount , err
2015-05-19 16:05:25 -04:00
}
2016-03-07 21:41:44 -05:00
func ( a * volumeAdapter ) Unmount ( id string ) error {
err := a . proxy . Unmount ( a . name , id )
2016-04-12 17:09:55 -04:00
if err == nil {
a . eMount = ""
}
return err
2015-05-19 16:05:25 -04:00
}
2016-03-07 15:44:43 -05:00
2017-05-17 17:19:13 -04:00
func ( a * volumeAdapter ) CreatedAt ( ) ( time . Time , error ) {
return a . createdAt , nil
}
2016-03-07 15:44:43 -05:00
func ( a * volumeAdapter ) Status ( ) map [ string ] interface { } {
out := make ( map [ string ] interface { } , len ( a . status ) )
for k , v := range a . status {
out [ k ] = v
}
return out
}