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  }