github.com/vincentwoo/docker@v0.7.3-0.20160116130405-82401a4b13c0/volume/volume.go (about) 1 package volume 2 3 import ( 4 "os" 5 "runtime" 6 "strings" 7 8 "github.com/Sirupsen/logrus" 9 derr "github.com/docker/docker/errors" 10 "github.com/docker/docker/pkg/system" 11 ) 12 13 // DefaultDriverName is the driver name used for the driver 14 // implemented in the local package. 15 const DefaultDriverName string = "local" 16 17 // Driver is for creating and removing volumes. 18 type Driver interface { 19 // Name returns the name of the volume driver. 20 Name() string 21 // Create makes a new volume with the given id. 22 Create(name string, opts map[string]string) (Volume, error) 23 // Remove deletes the volume. 24 Remove(vol Volume) (err error) 25 // List lists all the volumes the driver has 26 List() ([]Volume, error) 27 // Get retreives the volume with the requested name 28 Get(name string) (Volume, error) 29 } 30 31 // Volume is a place to store data. It is backed by a specific driver, and can be mounted. 32 type Volume interface { 33 // Name returns the name of the volume 34 Name() string 35 // DriverName returns the name of the driver which owns this volume. 36 DriverName() string 37 // Path returns the absolute path to the volume. 38 Path() string 39 // Mount mounts the volume and returns the absolute path to 40 // where it can be consumed. 41 Mount() (string, error) 42 // Unmount unmounts the volume when it is no longer in use. 43 Unmount() error 44 } 45 46 // MountPoint is the intersection point between a volume and a container. It 47 // specifies which volume is to be used and where inside a container it should 48 // be mounted. 49 type MountPoint struct { 50 Source string // Container host directory 51 Destination string // Inside the container 52 RW bool // True if writable 53 Name string // Name set by user 54 Driver string // Volume driver to use 55 Volume Volume `json:"-"` 56 57 // Note Mode is not used on Windows 58 Mode string `json:"Relabel"` // Originally field was `Relabel`" 59 60 // Note Propagation is not used on Windows 61 Propagation string // Mount propagation string 62 } 63 64 // Setup sets up a mount point by either mounting the volume if it is 65 // configured, or creating the source directory if supplied. 66 func (m *MountPoint) Setup() (string, error) { 67 if m.Volume != nil { 68 return m.Volume.Mount() 69 } 70 if len(m.Source) > 0 { 71 if _, err := os.Stat(m.Source); err != nil { 72 if !os.IsNotExist(err) { 73 return "", err 74 } 75 if runtime.GOOS != "windows" { // Windows does not have deprecation issues here 76 logrus.Warnf("Auto-creating non-existent volume host path %s, this is deprecated and will be removed soon", m.Source) 77 if err := system.MkdirAll(m.Source, 0755); err != nil { 78 return "", err 79 } 80 } 81 } 82 return m.Source, nil 83 } 84 return "", derr.ErrorCodeMountSetup 85 } 86 87 // Path returns the path of a volume in a mount point. 88 func (m *MountPoint) Path() string { 89 if m.Volume != nil { 90 return m.Volume.Path() 91 } 92 return m.Source 93 } 94 95 // ParseVolumesFrom ensure that the supplied volumes-from is valid. 96 func ParseVolumesFrom(spec string) (string, string, error) { 97 if len(spec) == 0 { 98 return "", "", derr.ErrorCodeVolumeFromBlank.WithArgs(spec) 99 } 100 101 specParts := strings.SplitN(spec, ":", 2) 102 id := specParts[0] 103 mode := "rw" 104 105 if len(specParts) == 2 { 106 mode = specParts[1] 107 if !ValidMountMode(mode) { 108 return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode) 109 } 110 // For now don't allow propagation properties while importing 111 // volumes from data container. These volumes will inherit 112 // the same propagation property as of the original volume 113 // in data container. This probably can be relaxed in future. 114 if HasPropagation(mode) { 115 return "", "", derr.ErrorCodeVolumeInvalidMode.WithArgs(mode) 116 } 117 } 118 return id, mode, nil 119 }