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