github.com/45cali/docker@v1.11.1/volume/drivers/extpoint.go (about)

     1  //go:generate pluginrpc-gen -i $GOFILE -o proxy.go -type volumeDriver -name VolumeDriver
     2  
     3  package volumedrivers
     4  
     5  import (
     6  	"fmt"
     7  	"sync"
     8  
     9  	"github.com/docker/docker/pkg/locker"
    10  	"github.com/docker/docker/pkg/plugins"
    11  	"github.com/docker/docker/volume"
    12  )
    13  
    14  // currently created by hand. generation tool would generate this like:
    15  // $ extpoint-gen Driver > volume/extpoint.go
    16  
    17  var drivers = &driverExtpoint{extensions: make(map[string]volume.Driver), driverLock: &locker.Locker{}}
    18  
    19  const extName = "VolumeDriver"
    20  
    21  // NewVolumeDriver returns a driver has the given name mapped on the given client.
    22  func NewVolumeDriver(name string, c client) volume.Driver {
    23  	proxy := &volumeDriverProxy{c}
    24  	return &volumeDriverAdapter{name: name, proxy: proxy}
    25  }
    26  
    27  type opts map[string]string
    28  type list []*proxyVolume
    29  
    30  // volumeDriver defines the available functions that volume plugins must implement.
    31  // This interface is only defined to generate the proxy objects.
    32  // It's not intended to be public or reused.
    33  type volumeDriver interface {
    34  	// Create a volume with the given name
    35  	Create(name string, opts opts) (err error)
    36  	// Remove the volume with the given name
    37  	Remove(name string) (err error)
    38  	// Get the mountpoint of the given volume
    39  	Path(name string) (mountpoint string, err error)
    40  	// Mount the given volume and return the mountpoint
    41  	Mount(name string) (mountpoint string, err error)
    42  	// Unmount the given volume
    43  	Unmount(name string) (err error)
    44  	// List lists all the volumes known to the driver
    45  	List() (volumes list, err error)
    46  	// Get retrieves the volume with the requested name
    47  	Get(name string) (volume *proxyVolume, err error)
    48  }
    49  
    50  type driverExtpoint struct {
    51  	extensions map[string]volume.Driver
    52  	sync.Mutex
    53  	driverLock *locker.Locker
    54  }
    55  
    56  // Register associates the given driver to the given name, checking if
    57  // the name is already associated
    58  func Register(extension volume.Driver, name string) bool {
    59  	if name == "" {
    60  		return false
    61  	}
    62  
    63  	drivers.Lock()
    64  	defer drivers.Unlock()
    65  
    66  	_, exists := drivers.extensions[name]
    67  	if exists {
    68  		return false
    69  	}
    70  	drivers.extensions[name] = extension
    71  	return true
    72  }
    73  
    74  // Unregister dissociates the name from its driver, if the association exists.
    75  func Unregister(name string) bool {
    76  	drivers.Lock()
    77  	defer drivers.Unlock()
    78  
    79  	_, exists := drivers.extensions[name]
    80  	if !exists {
    81  		return false
    82  	}
    83  	delete(drivers.extensions, name)
    84  	return true
    85  }
    86  
    87  // Lookup returns the driver associated with the given name. If a
    88  // driver with the given name has not been registered it checks if
    89  // there is a VolumeDriver plugin available with the given name.
    90  func Lookup(name string) (volume.Driver, error) {
    91  	drivers.driverLock.Lock(name)
    92  	defer drivers.driverLock.Unlock(name)
    93  
    94  	drivers.Lock()
    95  	ext, ok := drivers.extensions[name]
    96  	drivers.Unlock()
    97  	if ok {
    98  		return ext, nil
    99  	}
   100  
   101  	pl, err := plugins.Get(name, extName)
   102  	if err != nil {
   103  		return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err)
   104  	}
   105  
   106  	drivers.Lock()
   107  	defer drivers.Unlock()
   108  	if ext, ok := drivers.extensions[name]; ok {
   109  		return ext, nil
   110  	}
   111  
   112  	d := NewVolumeDriver(name, pl.Client)
   113  	drivers.extensions[name] = d
   114  	return d, nil
   115  }
   116  
   117  // GetDriver returns a volume driver by its name.
   118  // If the driver is empty, it looks for the local driver.
   119  func GetDriver(name string) (volume.Driver, error) {
   120  	if name == "" {
   121  		name = volume.DefaultDriverName
   122  	}
   123  	return Lookup(name)
   124  }
   125  
   126  // GetDriverList returns list of volume drivers registered.
   127  // If no driver is registered, empty string list will be returned.
   128  func GetDriverList() []string {
   129  	var driverList []string
   130  	drivers.Lock()
   131  	for driverName := range drivers.extensions {
   132  		driverList = append(driverList, driverName)
   133  	}
   134  	drivers.Unlock()
   135  	return driverList
   136  }
   137  
   138  // GetAllDrivers lists all the registered drivers
   139  func GetAllDrivers() ([]volume.Driver, error) {
   140  	plugins, err := plugins.GetAll(extName)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	var ds []volume.Driver
   145  
   146  	drivers.Lock()
   147  	defer drivers.Unlock()
   148  
   149  	for _, d := range drivers.extensions {
   150  		ds = append(ds, d)
   151  	}
   152  
   153  	for _, p := range plugins {
   154  		ext, ok := drivers.extensions[p.Name]
   155  		if ok {
   156  			continue
   157  		}
   158  
   159  		ext = NewVolumeDriver(p.Name, p.Client)
   160  		drivers.extensions[p.Name] = ext
   161  		ds = append(ds, ext)
   162  	}
   163  	return ds, nil
   164  }