|
@@ -6,10 +6,12 @@ import (
|
|
|
"path/filepath"
|
|
|
|
|
|
"github.com/docker/docker/daemon/graphdriver"
|
|
|
+ "github.com/docker/docker/daemon/graphdriver/quota"
|
|
|
"github.com/docker/docker/pkg/chrootarchive"
|
|
|
"github.com/docker/docker/pkg/containerfs"
|
|
|
"github.com/docker/docker/pkg/idtools"
|
|
|
"github.com/docker/docker/pkg/system"
|
|
|
+ units "github.com/docker/go-units"
|
|
|
"github.com/opencontainers/selinux/go-selinux/label"
|
|
|
)
|
|
|
|
|
@@ -33,6 +35,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|
|
if err := idtools.MkdirAllAndChown(home, 0700, rootIDs); err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
+
|
|
|
+ if err := setupDriverQuota(d); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
|
|
|
}
|
|
|
|
|
@@ -41,6 +48,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|
|
// In order to support layering, files are copied from the parent layer into the new layer. There is no copy-on-write support.
|
|
|
// Driver must be wrapped in NaiveDiffDriver to be used as a graphdriver.Driver
|
|
|
type Driver struct {
|
|
|
+ driverQuota
|
|
|
home string
|
|
|
idMappings *idtools.IDMappings
|
|
|
}
|
|
@@ -67,15 +75,38 @@ func (d *Driver) Cleanup() error {
|
|
|
// CreateReadWrite creates a layer that is writable for use as a container
|
|
|
// file system.
|
|
|
func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
|
|
|
- return d.Create(id, parent, opts)
|
|
|
+ var err error
|
|
|
+ var size int64
|
|
|
+
|
|
|
+ if opts != nil {
|
|
|
+ for key, val := range opts.StorageOpt {
|
|
|
+ switch key {
|
|
|
+ case "size":
|
|
|
+ if !d.quotaSupported() {
|
|
|
+ return quota.ErrQuotaNotSupported
|
|
|
+ }
|
|
|
+ if size, err = units.RAMInBytes(val); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ return fmt.Errorf("Storage opt %s not supported", key)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return d.create(id, parent, uint64(size))
|
|
|
}
|
|
|
|
|
|
// Create prepares the filesystem for the VFS driver and copies the directory for the given id under the parent.
|
|
|
func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
|
|
|
if opts != nil && len(opts.StorageOpt) != 0 {
|
|
|
- return fmt.Errorf("--storage-opt is not supported for vfs")
|
|
|
+ return fmt.Errorf("--storage-opt is not supported for vfs on read-only layers")
|
|
|
}
|
|
|
|
|
|
+ return d.create(id, parent, 0)
|
|
|
+}
|
|
|
+
|
|
|
+func (d *Driver) create(id, parent string, size uint64) error {
|
|
|
dir := d.dir(id)
|
|
|
rootIDs := d.idMappings.RootPair()
|
|
|
if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0700, rootIDs); err != nil {
|
|
@@ -84,6 +115,13 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
|
|
|
if err := idtools.MkdirAndChown(dir, 0755, rootIDs); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
+
|
|
|
+ if size != 0 {
|
|
|
+ if err := d.setupQuota(dir, size); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
labelOpts := []string{"level:s0"}
|
|
|
if _, mountLabel, err := label.InitLabels(labelOpts); err == nil {
|
|
|
label.SetFileLabel(dir, mountLabel)
|