github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/daemon/graphdriver/vfs/driver.go (about) 1 // +build linux windows 2 3 package vfs 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 10 "github.com/docker/docker/daemon/graphdriver" 11 "github.com/docker/docker/pkg/chrootarchive" 12 "github.com/docker/docker/pkg/system" 13 "github.com/opencontainers/runc/libcontainer/label" 14 ) 15 16 func init() { 17 graphdriver.Register("vfs", Init) 18 } 19 20 // Init returns a new VFS driver. 21 // This sets the home directory for the driver and returns NaiveDiffDriver. 22 func Init(home string, options []string) (graphdriver.Driver, error) { 23 d := &Driver{ 24 home: home, 25 } 26 return graphdriver.NaiveDiffDriver(d), nil 27 } 28 29 // Driver holds information about the driver, home directory of the driver. 30 // Driver implements graphdriver.ProtoDriver. It uses only basic vfs operations. 31 // In order to support layering, files are copied from the parent layer into the new layer. There is no copy-on-write support. 32 // Driver must be wrapped in NaiveDiffDriver to be used as a graphdriver.Driver 33 type Driver struct { 34 home string 35 } 36 37 func (d *Driver) String() string { 38 return "vfs" 39 } 40 41 // Status is used for implementing the graphdriver.ProtoDriver interface. VFS does not currently have any status information. 42 func (d *Driver) Status() [][2]string { 43 return nil 44 } 45 46 // GetMetadata is used for implementing the graphdriver.ProtoDriver interface. VFS does not currently have any meta data. 47 func (d *Driver) GetMetadata(id string) (map[string]string, error) { 48 return nil, nil 49 } 50 51 // Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver. 52 func (d *Driver) Cleanup() error { 53 return nil 54 } 55 56 // Create prepares the filesystem for the VFS driver and copies the directory for the given id under the parent. 57 func (d *Driver) Create(id, parent string) error { 58 dir := d.dir(id) 59 if err := system.MkdirAll(filepath.Dir(dir), 0700); err != nil { 60 return err 61 } 62 if err := os.Mkdir(dir, 0755); err != nil { 63 return err 64 } 65 opts := []string{"level:s0"} 66 if _, mountLabel, err := label.InitLabels(opts); err == nil { 67 label.SetFileLabel(dir, mountLabel) 68 } 69 if parent == "" { 70 return nil 71 } 72 parentDir, err := d.Get(parent, "") 73 if err != nil { 74 return fmt.Errorf("%s: %s", parent, err) 75 } 76 if err := chrootarchive.CopyWithTar(parentDir, dir); err != nil { 77 return err 78 } 79 return nil 80 } 81 82 func (d *Driver) dir(id string) string { 83 return filepath.Join(d.home, "dir", filepath.Base(id)) 84 } 85 86 // Remove deletes the content from the directory for a given id. 87 func (d *Driver) Remove(id string) error { 88 if _, err := os.Stat(d.dir(id)); err != nil { 89 return err 90 } 91 return os.RemoveAll(d.dir(id)) 92 } 93 94 // Get returns the directory for the given id. 95 func (d *Driver) Get(id, mountLabel string) (string, error) { 96 dir := d.dir(id) 97 if st, err := os.Stat(dir); err != nil { 98 return "", err 99 } else if !st.IsDir() { 100 return "", fmt.Errorf("%s: not a directory", dir) 101 } 102 return dir, nil 103 } 104 105 // Put is a noop for vfs that return nil for the error, since this driver has no runtime resources to clean up. 106 func (d *Driver) Put(id string) error { 107 // The vfs driver has no runtime resources (e.g. mounts) 108 // to clean up, so we don't need anything here 109 return nil 110 } 111 112 // Exists checks to see if the directory exists for the given id. 113 func (d *Driver) Exists(id string) bool { 114 _, err := os.Stat(d.dir(id)) 115 return err == nil 116 }