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  }