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  }