2013-11-04 01:54:51 +00:00
|
|
|
package graphdriver
|
2013-10-31 18:07:54 -07:00
|
|
|
|
2013-11-04 15:22:34 -08:00
|
|
|
import (
|
2014-03-27 17:41:06 +01:00
|
|
|
"errors"
|
2013-11-04 15:22:34 -08:00
|
|
|
"fmt"
|
2013-11-19 03:13:22 -08:00
|
|
|
"os"
|
2013-11-08 11:36:58 -08:00
|
|
|
"path"
|
2014-06-05 12:50:53 -07:00
|
|
|
|
2014-09-29 23:23:36 -07:00
|
|
|
"github.com/docker/docker/pkg/archive"
|
2013-11-04 15:22:34 -08:00
|
|
|
)
|
|
|
|
|
2014-06-02 19:26:41 -06:00
|
|
|
type FsMagic uint64
|
|
|
|
|
|
|
|
const (
|
|
|
|
FsMagicBtrfs = FsMagic(0x9123683E)
|
|
|
|
FsMagicAufs = FsMagic(0x61756673)
|
|
|
|
)
|
|
|
|
|
2014-06-05 10:34:20 +02:00
|
|
|
type InitFunc func(root string, options []string) (Driver, error)
|
2013-11-04 20:51:12 -08:00
|
|
|
|
2014-09-16 12:13:50 -07:00
|
|
|
// ProtoDriver defines the basic capabilities of a driver.
|
|
|
|
// This interface exists solely to be a minimum set of methods
|
|
|
|
// for client code which choose not to implement the entire Driver
|
|
|
|
// interface and use the NaiveDiffDriver wrapper constructor.
|
|
|
|
//
|
|
|
|
// Use of ProtoDriver directly by client code is not recommended.
|
|
|
|
type ProtoDriver interface {
|
2014-09-10 20:30:52 -07:00
|
|
|
// String returns a string representation of this driver.
|
2013-11-15 10:24:48 +01:00
|
|
|
String() string
|
2014-09-10 20:30:52 -07:00
|
|
|
// Create creates a new, empty, filesystem layer with the
|
|
|
|
// specified id and parent. Parent may be "".
|
2014-04-17 23:47:27 +00:00
|
|
|
Create(id, parent string) error
|
2014-09-16 12:13:50 -07:00
|
|
|
// Remove attempts to remove the filesystem layer with this id.
|
2013-11-07 20:34:01 +00:00
|
|
|
Remove(id string) error
|
2014-09-10 20:30:52 -07:00
|
|
|
// Get returns the mountpoint for the layered filesystem referred
|
|
|
|
// to by this id. You can optionally specify a mountLabel or "".
|
|
|
|
// Returns the absolute path to the mounted layered filesystem.
|
2014-04-17 23:47:27 +00:00
|
|
|
Get(id, mountLabel string) (dir string, err error)
|
2014-09-10 20:30:52 -07:00
|
|
|
// Put releases the system resources for the specified id,
|
|
|
|
// e.g, unmounting layered filesystem.
|
2013-12-05 22:18:02 +01:00
|
|
|
Put(id string)
|
2014-09-10 20:30:52 -07:00
|
|
|
// Exists returns whether a filesystem layer with the specified
|
|
|
|
// ID exists on this driver.
|
2013-11-19 02:32:08 -08:00
|
|
|
Exists(id string) bool
|
2014-09-10 20:30:52 -07:00
|
|
|
// Status returns a set of key-value pairs which give low
|
|
|
|
// level diagnostic status about this driver.
|
2013-11-15 11:04:02 +01:00
|
|
|
Status() [][2]string
|
2014-09-10 20:30:52 -07:00
|
|
|
// Cleanup performs necessary tasks to release resources
|
|
|
|
// held by the driver, e.g., unmounting all layered filesystems
|
|
|
|
// known to this driver.
|
2013-11-11 17:17:38 -08:00
|
|
|
Cleanup() error
|
|
|
|
}
|
|
|
|
|
2014-09-16 12:13:50 -07:00
|
|
|
// Driver is the interface for layered/snapshot file system drivers.
|
2014-09-10 20:30:52 -07:00
|
|
|
type Driver interface {
|
2014-09-16 12:13:50 -07:00
|
|
|
ProtoDriver
|
2014-09-10 20:30:52 -07:00
|
|
|
// Diff produces an archive of the changes between the specified
|
|
|
|
// layer and its parent layer which may be "".
|
|
|
|
Diff(id, parent string) (archive.Archive, error)
|
|
|
|
// Changes produces a list of changes between the specified layer
|
|
|
|
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
|
|
|
Changes(id, parent string) ([]archive.Change, error)
|
|
|
|
// ApplyDiff extracts the changeset from the given diff into the
|
|
|
|
// layer with the specified id and parent, returning the size of the
|
|
|
|
// new layer in bytes.
|
2014-12-17 18:26:03 -08:00
|
|
|
ApplyDiff(id, parent string, diff archive.ArchiveReader) (size int64, err error)
|
2014-09-10 20:30:52 -07:00
|
|
|
// DiffSize calculates the changes between the specified id
|
|
|
|
// and its parent and returns the size in bytes of the changes
|
|
|
|
// relative to its base filesystem directory.
|
2014-12-17 18:26:03 -08:00
|
|
|
DiffSize(id, parent string) (size int64, err error)
|
2013-11-11 16:47:36 +01:00
|
|
|
}
|
|
|
|
|
2013-11-04 15:22:34 -08:00
|
|
|
var (
|
2013-11-20 11:39:15 -08:00
|
|
|
DefaultDriver string
|
2013-11-04 15:22:34 -08:00
|
|
|
// All registred drivers
|
|
|
|
drivers map[string]InitFunc
|
|
|
|
// Slice of drivers that should be used in an order
|
|
|
|
priority = []string{
|
|
|
|
"aufs",
|
2014-03-24 14:15:04 +00:00
|
|
|
"btrfs",
|
2013-11-04 15:22:34 -08:00
|
|
|
"devicemapper",
|
2013-11-25 10:28:17 -08:00
|
|
|
"vfs",
|
2014-08-19 11:23:55 +02:00
|
|
|
// experimental, has to be enabled manually for now
|
2014-12-03 13:57:23 +01:00
|
|
|
"overlay",
|
2013-11-04 15:22:34 -08:00
|
|
|
}
|
2014-03-27 17:41:06 +01:00
|
|
|
|
2014-05-29 22:55:59 +03:00
|
|
|
ErrNotSupported = errors.New("driver not supported")
|
|
|
|
ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
|
|
|
|
ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
|
2013-11-04 15:22:34 -08:00
|
|
|
)
|
|
|
|
|
2013-11-07 20:31:50 +00:00
|
|
|
func init() {
|
|
|
|
drivers = make(map[string]InitFunc)
|
|
|
|
}
|
|
|
|
|
2013-11-04 15:22:34 -08:00
|
|
|
func Register(name string, initFunc InitFunc) error {
|
|
|
|
if _, exists := drivers[name]; exists {
|
|
|
|
return fmt.Errorf("Name already registered %s", name)
|
|
|
|
}
|
|
|
|
drivers[name] = initFunc
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-06-05 10:34:20 +02:00
|
|
|
func GetDriver(name, home string, options []string) (Driver, error) {
|
2013-11-08 02:49:32 +00:00
|
|
|
if initFunc, exists := drivers[name]; exists {
|
2014-06-05 10:34:20 +02:00
|
|
|
return initFunc(path.Join(home, name), options)
|
2013-11-08 02:49:32 +00:00
|
|
|
}
|
2014-03-27 17:41:06 +01:00
|
|
|
return nil, ErrNotSupported
|
2013-11-08 02:49:32 +00:00
|
|
|
}
|
|
|
|
|
2014-06-05 10:34:20 +02:00
|
|
|
func New(root string, options []string) (driver Driver, err error) {
|
2013-11-20 11:39:15 -08:00
|
|
|
for _, name := range []string{os.Getenv("DOCKER_DRIVER"), DefaultDriver} {
|
2013-11-19 03:13:22 -08:00
|
|
|
if name != "" {
|
2014-06-05 10:34:20 +02:00
|
|
|
return GetDriver(name, root, options)
|
2013-11-19 03:13:22 -08:00
|
|
|
}
|
2013-11-08 02:49:32 +00:00
|
|
|
}
|
2013-11-19 03:13:22 -08:00
|
|
|
|
2013-11-04 15:22:34 -08:00
|
|
|
// Check for priority drivers first
|
|
|
|
for _, name := range priority {
|
2014-06-05 10:34:20 +02:00
|
|
|
driver, err = GetDriver(name, root, options)
|
2014-03-27 17:41:06 +01:00
|
|
|
if err != nil {
|
2014-05-29 22:55:59 +03:00
|
|
|
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
2014-03-27 17:41:06 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
return nil, err
|
2013-11-04 15:22:34 -08:00
|
|
|
}
|
2013-11-08 02:49:32 +00:00
|
|
|
return driver, nil
|
2013-11-04 15:22:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check all registered drivers if no priority driver is found
|
|
|
|
for _, initFunc := range drivers {
|
2014-06-05 10:34:20 +02:00
|
|
|
if driver, err = initFunc(root, options); err != nil {
|
2014-05-29 22:55:59 +03:00
|
|
|
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
2014-03-27 17:41:06 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
return nil, err
|
2013-11-04 15:22:34 -08:00
|
|
|
}
|
|
|
|
return driver, nil
|
|
|
|
}
|
2014-03-27 17:41:06 +01:00
|
|
|
return nil, fmt.Errorf("No supported storage backend found")
|
2013-11-04 15:22:34 -08:00
|
|
|
}
|