summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/containers/storage/containers_ffjson.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/aufs/aufs.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/btrfs/btrfs.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/driver.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/driver.go3
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/check.go66
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go46
-rw-r--r--vendor/github.com/containers/storage/drivers/template.go45
-rw-r--r--vendor/github.com/containers/storage/drivers/vfs/driver.go8
-rw-r--r--vendor/github.com/containers/storage/drivers/windows/windows.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs.go65
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go21
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go59
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_unsupported.go2
-rw-r--r--vendor/github.com/containers/storage/images.go4
-rw-r--r--vendor/github.com/containers/storage/images_ffjson.go2
-rw-r--r--vendor/github.com/containers/storage/layers.go44
-rw-r--r--vendor/github.com/containers/storage/layers_ffjson.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/example_changes.go97
-rw-r--r--vendor/github.com/containers/storage/store.go60
-rw-r--r--vendor/github.com/containers/storage/vendor.conf2
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label.go4
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go62
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go36
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go8
-rw-r--r--vendor/github.com/urfave/cli/help.go2
-rw-r--r--vendor/github.com/varlink/go/.gitignore1
-rw-r--r--vendor/github.com/varlink/go/.travis.yml6
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink/main.go295
-rw-r--r--vendor/github.com/varlink/go/varlink/bridge.go59
-rw-r--r--vendor/github.com/varlink/go/varlink/bridge_windows.go57
-rw-r--r--vendor/github.com/varlink/go/varlink/connection.go7
-rw-r--r--vendor/github.com/varlink/go/varlink/service.go67
-rw-r--r--vendor/github.com/varlink/go/varlink/socketactivation.go63
-rw-r--r--vendor/github.com/varlink/go/varlink/socketactivation_windows.go7
36 files changed, 981 insertions, 243 deletions
diff --git a/vendor/github.com/containers/storage/containers_ffjson.go b/vendor/github.com/containers/storage/containers_ffjson.go
index aef6becfe..40b912bb3 100644
--- a/vendor/github.com/containers/storage/containers_ffjson.go
+++ b/vendor/github.com/containers/storage/containers_ffjson.go
@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
-// source: containers.go
+// source: ./containers.go
package storage
diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
index ca69816be..e821bc0c5 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
@@ -253,6 +253,11 @@ func (a *Driver) AdditionalImageStores() []string {
return nil
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (a *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ return graphdriver.NaiveCreateFromTemplate(a, id, template, templateIDMappings, parent, parentIDMappings, opts, readWrite)
+}
+
// CreateReadWrite creates a layer that is writable for use as a container
// file system.
func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
index 567cda9d3..30254d9fb 100644
--- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
+++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
@@ -490,6 +490,11 @@ func (d *Driver) quotasDirID(id string) string {
return path.Join(d.quotasDir(), id)
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ return d.Create(id, template, opts)
+}
+
// 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 {
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
index 39a4fbe2c..13677c93a 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
@@ -123,6 +123,11 @@ func (d *Driver) Cleanup() error {
return err
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ return d.Create(id, template, opts)
+}
+
// 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 {
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index 476b55160..dda172574 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -72,6 +72,9 @@ type ProtoDriver interface {
// specified id and parent and options passed in opts. Parent
// may be "" and opts may be nil.
Create(id, parent string, opts *CreateOpts) error
+ // CreateFromTemplate creates a new filesystem layer with the specified id
+ // and parent, with contents identical to the specified template layer.
+ CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error
// Remove attempts to remove the filesystem layer with this id.
Remove(id string) error
// Get returns the mountpoint for the layered filesystem referred
diff --git a/vendor/github.com/containers/storage/drivers/overlay/check.go b/vendor/github.com/containers/storage/drivers/overlay/check.go
index 590d517fa..a566e4afd 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/check.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/check.go
@@ -10,6 +10,8 @@ import (
"path/filepath"
"syscall"
+ "github.com/containers/storage/pkg/ioutils"
+ "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/system"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -57,10 +59,11 @@ func doesSupportNativeDiff(d, mountOpts string) error {
}
opts := fmt.Sprintf("lowerdir=%s:%s,upperdir=%s,workdir=%s", path.Join(td, "l2"), path.Join(td, "l1"), path.Join(td, "l3"), path.Join(td, "work"))
- if mountOpts != "" {
- opts = fmt.Sprintf("%s,%s", opts, mountOpts)
+ flags, data := mount.ParseOptions(mountOpts)
+ if data != "" {
+ opts = fmt.Sprintf("%s,%s", opts, data)
}
- if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", 0, opts); err != nil {
+ if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", uintptr(flags), opts); err != nil {
return errors.Wrap(err, "failed to mount overlay")
}
defer func() {
@@ -103,3 +106,60 @@ func doesSupportNativeDiff(d, mountOpts string) error {
return nil
}
+
+// doesMetacopy checks if the filesystem is going to optimize changes to
+// metadata by using nodes marked with an "overlay.metacopy" attribute to avoid
+// copying up a file from a lower layer unless/until its contents are being
+// modified
+func doesMetacopy(d, mountOpts string) (bool, error) {
+ td, err := ioutil.TempDir(d, "metacopy-check")
+ if err != nil {
+ return false, err
+ }
+ defer func() {
+ if err := os.RemoveAll(td); err != nil {
+ logrus.Warnf("Failed to remove check directory %v: %v", td, err)
+ }
+ }()
+
+ // Make directories l1, l2, work, merged
+ if err := os.MkdirAll(filepath.Join(td, "l1"), 0755); err != nil {
+ return false, err
+ }
+ if err := ioutils.AtomicWriteFile(filepath.Join(td, "l1", "f"), []byte{0xff}, 0700); err != nil {
+ return false, err
+ }
+ if err := os.MkdirAll(filepath.Join(td, "l2"), 0755); err != nil {
+ return false, err
+ }
+ if err := os.Mkdir(filepath.Join(td, "work"), 0755); err != nil {
+ return false, err
+ }
+ if err := os.Mkdir(filepath.Join(td, "merged"), 0755); err != nil {
+ return false, err
+ }
+ // Mount using the mandatory options and configured options
+ opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", path.Join(td, "l1"), path.Join(td, "l2"), path.Join(td, "work"))
+ flags, data := mount.ParseOptions(mountOpts)
+ if data != "" {
+ opts = fmt.Sprintf("%s,%s", opts, data)
+ }
+ if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", uintptr(flags), opts); err != nil {
+ return false, errors.Wrap(err, "failed to mount overlay for metacopy check")
+ }
+ defer func() {
+ if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil {
+ logrus.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
+ }
+ }()
+ // Make a change that only impacts the inode, and check if the pulled-up copy is marked
+ // as a metadata-only copy
+ if err := os.Chmod(filepath.Join(td, "merged", "f"), 0600); err != nil {
+ return false, errors.Wrap(err, "error changing permissions on file for metacopy check")
+ }
+ metacopy, err := system.Lgetxattr(filepath.Join(td, "l2", "f"), "trusted.overlay.metacopy")
+ if err != nil {
+ return false, errors.Wrap(err, "metacopy flag was not set on file in upper layer")
+ }
+ return metacopy != nil, nil
+}
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index 2455b6736..57d6dd63a 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -85,13 +85,12 @@ const (
)
type overlayOptions struct {
- overrideKernelCheck bool
- imageStores []string
- quota quota.Quota
- mountProgram string
- ostreeRepo string
- skipMountHome bool
- mountOptions string
+ imageStores []string
+ quota quota.Quota
+ mountProgram string
+ ostreeRepo string
+ skipMountHome bool
+ mountOptions string
}
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
@@ -105,6 +104,7 @@ type Driver struct {
options overlayOptions
naiveDiff graphdriver.DiffDriver
supportsDType bool
+ usingMetacopy bool
locker *locker.Locker
convert map[string]bool
}
@@ -158,6 +158,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
+ var usingMetacopy bool
var supportsDType bool
if opts.mountProgram != "" {
supportsDType = true
@@ -172,6 +173,17 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
}
return nil, errors.Wrap(err, "kernel does not support overlay fs")
}
+ usingMetacopy, err = doesMetacopy(home, opts.mountOptions)
+ if err == nil {
+ if usingMetacopy {
+ logrus.Debugf("overlay test mount indicated that metacopy is being used")
+ } else {
+ logrus.Debugf("overlay test mount indicated that metacopy is not being used")
+ }
+ } else {
+ logrus.Warnf("overlay test mount did not indicate whether or not metacopy is being used: %v", err)
+ return nil, err
+ }
}
if !opts.skipMountHome {
@@ -193,6 +205,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
gidMaps: gidMaps,
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
supportsDType: supportsDType,
+ usingMetacopy: usingMetacopy,
locker: locker.New(),
options: *opts,
convert: make(map[string]bool),
@@ -212,7 +225,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, fmt.Errorf("Storage option overlay.size only supported for backingFS XFS. Found %v", backingFs)
}
- logrus.Debugf("backingFs=%s, projectQuotaSupported=%v, useNativeDiff=%v", backingFs, projectQuotaSupported, !d.useNaiveDiff())
+ logrus.Debugf("backingFs=%s, projectQuotaSupported=%v, useNativeDiff=%v, usingMetacopy=%v", backingFs, projectQuotaSupported, !d.useNaiveDiff(), d.usingMetacopy)
return d, nil
}
@@ -226,12 +239,6 @@ func parseOptions(options []string) (*overlayOptions, error) {
}
key = strings.ToLower(key)
switch key {
- case ".override_kernel_check", "overlay.override_kernel_check", "overlay2.override_kernel_check":
- logrus.Debugf("overlay: override_kernelcheck=%s", val)
- o.overrideKernelCheck, err = strconv.ParseBool(val)
- if err != nil {
- return nil, err
- }
case ".mountopt", "overlay.mountopt", "overlay2.mountopt":
o.mountOptions = val
case ".size", "overlay.size", "overlay2.size":
@@ -375,6 +382,7 @@ func (d *Driver) Status() [][2]string {
{"Backing Filesystem", backingFs},
{"Supports d_type", strconv.FormatBool(d.supportsDType)},
{"Native Overlay Diff", strconv.FormatBool(!d.useNaiveDiff())},
+ {"Using metacopy", strconv.FormatBool(d.usingMetacopy)},
}
}
@@ -410,6 +418,14 @@ func (d *Driver) Cleanup() error {
return mount.Unmount(d.home)
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ if readWrite {
+ return d.CreateReadWrite(id, template, opts)
+ }
+ return d.Create(id, template, opts)
+}
+
// 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 {
@@ -793,6 +809,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
mountTarget = path.Join(id, "merged")
}
flags, data := mount.ParseOptions(mountData)
+ logrus.Debugf("overlay: mount_data=%s", mountData)
if err := mountFunc("overlay", mountTarget, "overlay", uintptr(flags), data); err != nil {
return "", fmt.Errorf("error creating overlay mount to %s: %v", mountTarget, err)
}
@@ -986,6 +1003,7 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
// Mount the new layer and handle ownership changes and possible copy_ups in it.
options := graphdriver.MountOpts{
MountLabel: mountLabel,
+ Options: strings.Split(d.options.mountOptions, ","),
}
layerFs, err := d.get(id, true, options)
if err != nil {
diff --git a/vendor/github.com/containers/storage/drivers/template.go b/vendor/github.com/containers/storage/drivers/template.go
new file mode 100644
index 000000000..dfcbffb83
--- /dev/null
+++ b/vendor/github.com/containers/storage/drivers/template.go
@@ -0,0 +1,45 @@
+package graphdriver
+
+import (
+ "github.com/sirupsen/logrus"
+
+ "github.com/containers/storage/pkg/idtools"
+)
+
+// TemplateDriver is just barely enough of a driver that we can implement a
+// naive version of CreateFromTemplate on top of it.
+type TemplateDriver interface {
+ DiffDriver
+ CreateReadWrite(id, parent string, opts *CreateOpts) error
+ Create(id, parent string, opts *CreateOpts) error
+ Remove(id string) error
+}
+
+// CreateFromTemplate creates a layer with the same contents and parent as
+// another layer. Internally, it may even depend on that other layer
+// continuing to exist, as if it were actually a child of the child layer.
+func NaiveCreateFromTemplate(d TemplateDriver, id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error {
+ var err error
+ if readWrite {
+ err = d.CreateReadWrite(id, parent, opts)
+ } else {
+ err = d.Create(id, parent, opts)
+ }
+ if err != nil {
+ return err
+ }
+ diff, err := d.Diff(template, templateIDMappings, parent, parentIDMappings, opts.MountLabel)
+ if err != nil {
+ if err2 := d.Remove(id); err2 != nil {
+ logrus.Errorf("error removing layer %q: %v", id, err2)
+ }
+ return err
+ }
+ if _, err = d.ApplyDiff(id, templateIDMappings, parent, opts.MountLabel, diff); err != nil {
+ if err2 := d.Remove(id); err2 != nil {
+ logrus.Errorf("error removing layer %q: %v", id, err2)
+ }
+ return err
+ }
+ return nil
+}
diff --git a/vendor/github.com/containers/storage/drivers/vfs/driver.go b/vendor/github.com/containers/storage/drivers/vfs/driver.go
index f7f3c75ba..5941ccc17 100644
--- a/vendor/github.com/containers/storage/drivers/vfs/driver.go
+++ b/vendor/github.com/containers/storage/drivers/vfs/driver.go
@@ -99,6 +99,14 @@ func (d *Driver) Cleanup() error {
return nil
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ if readWrite {
+ return d.CreateReadWrite(id, template, opts)
+ }
+ return d.Create(id, template, opts)
+}
+
// 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 {
diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go
index c6d86a4ab..c7df1c1fe 100644
--- a/vendor/github.com/containers/storage/drivers/windows/windows.go
+++ b/vendor/github.com/containers/storage/drivers/windows/windows.go
@@ -185,6 +185,11 @@ func (d *Driver) Exists(id string) bool {
return result
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ return graphdriver.NaiveCreateFromTemplate(d, id, template, templateIDMappings, parent, parentIDMappings, opts, readWrite)
+}
+
// 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 {
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
index c3ce6e869..eaa9e8bc5 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
@@ -1,4 +1,4 @@
-// +build linux freebsd solaris
+// +build linux freebsd
package zfs
@@ -16,7 +16,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
- zfs "github.com/mistifyio/go-zfs"
+ "github.com/mistifyio/go-zfs"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -38,7 +38,7 @@ type Logger struct{}
// Log wraps log message from ZFS driver with a prefix '[zfs]'.
func (*Logger) Log(cmd []string) {
- logrus.Debugf("[zfs] %s", strings.Join(cmd, " "))
+ logrus.WithField("storage-driver", "zfs").Debugf("%s", strings.Join(cmd, " "))
}
// Init returns a new ZFS driver.
@@ -47,14 +47,16 @@ func (*Logger) Log(cmd []string) {
func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
var err error
+ logger := logrus.WithField("storage-driver", "zfs")
+
if _, err := exec.LookPath("zfs"); err != nil {
- logrus.Debugf("[zfs] zfs command is not available: %v", err)
+ logger.Debugf("zfs command is not available: %v", err)
return nil, errors.Wrap(graphdriver.ErrPrerequisites, "the 'zfs' command is not available")
}
file, err := os.OpenFile("/dev/zfs", os.O_RDWR, 0600)
if err != nil {
- logrus.Debugf("[zfs] cannot open /dev/zfs: %v", err)
+ logger.Debugf("cannot open /dev/zfs: %v", err)
return nil, errors.Wrapf(graphdriver.ErrPrerequisites, "could not open /dev/zfs: %v", err)
}
defer file.Close()
@@ -109,9 +111,6 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri
return nil, fmt.Errorf("Failed to create '%s': %v", base, err)
}
- if err := mount.MakePrivate(base); err != nil {
- return nil, err
- }
d := &Driver{
dataset: rootDataset,
options: options,
@@ -157,7 +156,7 @@ func lookupZfsDataset(rootdir string) (string, error) {
}
for _, m := range mounts {
if err := unix.Stat(m.Mountpoint, &stat); err != nil {
- logrus.Debugf("[zfs] failed to stat '%s' while scanning for zfs mount: %v", m.Mountpoint, err)
+ logrus.WithField("storage-driver", "zfs").Debugf("failed to stat '%s' while scanning for zfs mount: %v", m.Mountpoint, err)
continue // may fail on fuse file systems
}
@@ -184,7 +183,7 @@ func (d *Driver) String() string {
return "zfs"
}
-// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
+// Cleanup is called on when program exits, it is a no-op for ZFS.
func (d *Driver) Cleanup() error {
return nil
}
@@ -260,6 +259,11 @@ func (d *Driver) mountPath(id string) string {
return path.Join(d.options.mountPath, "graph", getMountpoint(id))
}
+// CreateFromTemplate creates a layer with the same contents and parent as another layer.
+func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *graphdriver.CreateOpts, readWrite bool) error {
+ return d.Create(id, template, opts)
+}
+
// 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 {
@@ -360,11 +364,25 @@ func (d *Driver) Remove(id string) error {
}
// Get returns the mountpoint for the given id after creating the target directories if necessary.
-func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
+func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
+
mountpoint := d.mountPath(id)
if count := d.ctr.Increment(mountpoint); count > 1 {
return mountpoint, nil
}
+ defer func() {
+ if retErr != nil {
+ if c := d.ctr.Decrement(mountpoint); c <= 0 {
+ if mntErr := unix.Unmount(mountpoint, 0); mntErr != nil {
+ logrus.WithField("storage-driver", "zfs").Errorf("Error unmounting %v: %v", mountpoint, mntErr)
+ }
+ if rmErr := unix.Rmdir(mountpoint); rmErr != nil && !os.IsNotExist(rmErr) {
+ logrus.WithField("storage-driver", "zfs").Debugf("Failed to remove %s: %v", id, rmErr)
+ }
+
+ }
+ }
+ }()
mountOptions := d.options.mountOptions
if len(options.Options) > 0 {
@@ -373,29 +391,24 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
filesystem := d.zfsPath(id)
opts := label.FormatMountLabel(mountOptions, options.MountLabel)
- logrus.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, opts)
+ logrus.WithField("storage-driver", "zfs").Debugf(`mount("%s", "%s", "%s")`, filesystem, mountpoint, opts)
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
if err != nil {
- d.ctr.Decrement(mountpoint)
return "", err
}
// Create the target directories if they don't exist
if err := idtools.MkdirAllAs(mountpoint, 0755, rootUID, rootGID); err != nil {
- d.ctr.Decrement(mountpoint)
return "", err
}
if err := mount.Mount(filesystem, mountpoint, "zfs", opts); err != nil {
- d.ctr.Decrement(mountpoint)
- return "", fmt.Errorf("error creating zfs mount of %s to %s: %v", filesystem, mountpoint, err)
+ return "", errors.Wrap(err, "error creating zfs mount")
}
// this could be our first mount after creation of the filesystem, and the root dir may still have root
// permissions instead of the remapped root uid:gid (if user namespaces are enabled):
if err := os.Chown(mountpoint, rootUID, rootGID); err != nil {
- mount.Unmount(mountpoint)
- d.ctr.Decrement(mountpoint)
return "", fmt.Errorf("error modifying zfs mountpoint (%s) directory ownership: %v", mountpoint, err)
}
@@ -408,16 +421,18 @@ func (d *Driver) Put(id string) error {
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}
- mounted, err := graphdriver.Mounted(graphdriver.FsMagicZfs, mountpoint)
- if err != nil || !mounted {
- return err
- }
- logrus.Debugf(`[zfs] unmount("%s")`, mountpoint)
+ logger := logrus.WithField("storage-driver", "zfs")
- if err := mount.Unmount(mountpoint); err != nil {
- return fmt.Errorf("error unmounting to %s: %v", mountpoint, err)
+ logger.Debugf(`unmount("%s")`, mountpoint)
+
+ if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
+ logger.Warnf("Failed to unmount %s mount %s: %v", id, mountpoint, err)
+ }
+ if err := unix.Rmdir(mountpoint); err != nil && !os.IsNotExist(err) {
+ logger.Debugf("Failed to remove %s mount point %s: %v", id, mountpoint, err)
}
+
return nil
}
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
index 69c0448d3..bf6905159 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
@@ -18,7 +18,7 @@ func checkRootdirFs(rootdir string) error {
// on FreeBSD buf.Fstypename contains ['z', 'f', 's', 0 ... ]
if (buf.Fstypename[0] != 122) || (buf.Fstypename[1] != 102) || (buf.Fstypename[2] != 115) || (buf.Fstypename[3] != 0) {
- logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
+ logrus.WithField("storage-driver", "zfs").Debugf("no zfs dataset found for rootdir '%s'", rootdir)
return errors.Wrapf(graphdriver.ErrPrerequisites, "no zfs dataset found for rootdir '%s'", rootdir)
}
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
index da298047d..fb1ef3a3d 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
@@ -1,23 +1,24 @@
package zfs
import (
- "fmt"
-
"github.com/containers/storage/drivers"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
)
-func checkRootdirFs(rootdir string) error {
- var buf unix.Statfs_t
- if err := unix.Statfs(rootdir, &buf); err != nil {
- return fmt.Errorf("Failed to access '%s': %s", rootdir, err)
+func checkRootdirFs(rootDir string) error {
+ fsMagic, err := graphdriver.GetFSMagic(rootDir)
+ if err != nil {
+ return err
+ }
+ backingFS := "unknown"
+ if fsName, ok := graphdriver.FsNames[fsMagic]; ok {
+ backingFS = fsName
}
- if graphdriver.FsMagic(buf.Type) != graphdriver.FsMagicZfs {
- logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
- return errors.Wrapf(graphdriver.ErrPrerequisites, "no zfs dataset found for rootdir '%s'", rootdir)
+ if fsMagic != graphdriver.FsMagicZfs {
+ logrus.WithField("root", rootDir).WithField("backingFS", backingFS).WithField("storage-driver", "zfs").Error("No zfs dataset found for root")
+ return errors.Wrapf(graphdriver.ErrPrerequisites, "no zfs dataset found for rootdir '%s'", rootDir)
}
return nil
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go
deleted file mode 100644
index 2383bf3bf..000000000
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// +build solaris,cgo
-
-package zfs
-
-/*
-#include <sys/statvfs.h>
-#include <stdlib.h>
-
-static inline struct statvfs *getstatfs(char *s) {
- struct statvfs *buf;
- int err;
- buf = (struct statvfs *)malloc(sizeof(struct statvfs));
- err = statvfs(s, buf);
- return buf;
-}
-*/
-import "C"
-import (
- "path/filepath"
- "strings"
- "unsafe"
-
- "github.com/containers/storage/drivers"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-func checkRootdirFs(rootdir string) error {
-
- cs := C.CString(filepath.Dir(rootdir))
- defer C.free(unsafe.Pointer(cs))
- buf := C.getstatfs(cs)
- defer C.free(unsafe.Pointer(buf))
-
- // on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
- if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
- (buf.f_basetype[3] != 0) {
- logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
- return errors.Wrapf(graphdriver.ErrPrerequisites, "no zfs dataset found for rootdir '%s'", rootdir)
- }
-
- return nil
-}
-
-/* rootfs is introduced to comply with the OCI spec
-which states that root filesystem must be mounted at <CID>/rootfs/ instead of <CID>/
-*/
-func getMountpoint(id string) string {
- maxlen := 12
-
- // we need to preserve filesystem suffix
- suffix := strings.SplitN(id, "-", 2)
-
- if len(suffix) > 1 {
- return filepath.Join(id[:maxlen]+"-"+suffix[1], "rootfs", "root")
- }
-
- return filepath.Join(id[:maxlen], "rootfs", "root")
-}
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_unsupported.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_unsupported.go
index ce8daadaf..643b169bc 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_unsupported.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_unsupported.go
@@ -1,4 +1,4 @@
-// +build !linux,!freebsd,!solaris
+// +build !linux,!freebsd
package zfs
diff --git a/vendor/github.com/containers/storage/images.go b/vendor/github.com/containers/storage/images.go
index b10501b08..d99842534 100644
--- a/vendor/github.com/containers/storage/images.go
+++ b/vendor/github.com/containers/storage/images.go
@@ -42,7 +42,9 @@ type Image struct {
// MappedTopLayers are the IDs of alternate versions of the top layer
// which have the same contents and parent, and which differ from
- // TopLayer only in which ID mappings they use.
+ // TopLayer only in which ID mappings they use. When the image is
+ // to be removed, they should be removed before the TopLayer, as the
+ // graph driver may depend on that.
MappedTopLayers []string `json:"mapped-layers,omitempty"`
// Metadata is data we keep for the convenience of the caller. It is not
diff --git a/vendor/github.com/containers/storage/images_ffjson.go b/vendor/github.com/containers/storage/images_ffjson.go
index 6b40ebd59..539acfe93 100644
--- a/vendor/github.com/containers/storage/images_ffjson.go
+++ b/vendor/github.com/containers/storage/images_ffjson.go
@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
-// source: images.go
+// source: ./images.go
package storage
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 299d2f818..cdc3cbba9 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -551,9 +551,20 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
}
}
parent := ""
- var parentMappings *idtools.IDMappings
if parentLayer != nil {
parent = parentLayer.ID
+ }
+ var parentMappings, templateIDMappings, oldMappings *idtools.IDMappings
+ if moreOptions.TemplateLayer != "" {
+ templateLayer, ok := r.lookup(moreOptions.TemplateLayer)
+ if !ok {
+ return nil, -1, ErrLayerUnknown
+ }
+ templateIDMappings = idtools.NewIDMappingsFromMaps(templateLayer.UIDMap, templateLayer.GIDMap)
+ } else {
+ templateIDMappings = &idtools.IDMappings{}
+ }
+ if parentLayer != nil {
parentMappings = idtools.NewIDMappingsFromMaps(parentLayer.UIDMap, parentLayer.GIDMap)
} else {
parentMappings = &idtools.IDMappings{}
@@ -566,23 +577,34 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
MountLabel: mountLabel,
StorageOpt: options,
}
- if writeable {
- if err = r.driver.CreateReadWrite(id, parent, &opts); err != nil {
+ if moreOptions.TemplateLayer != "" {
+ if err = r.driver.CreateFromTemplate(id, moreOptions.TemplateLayer, templateIDMappings, parent, parentMappings, &opts, writeable); err != nil {
if id != "" {
- return nil, -1, errors.Wrapf(err, "error creating read-write layer with ID %q", id)
+ return nil, -1, errors.Wrapf(err, "error creating copy of template layer %q with ID %q", moreOptions.TemplateLayer, id)
}
- return nil, -1, errors.Wrapf(err, "error creating read-write layer")
+ return nil, -1, errors.Wrapf(err, "error creating copy of template layer %q", moreOptions.TemplateLayer)
}
+ oldMappings = templateIDMappings
} else {
- if err = r.driver.Create(id, parent, &opts); err != nil {
- if id != "" {
- return nil, -1, errors.Wrapf(err, "error creating layer with ID %q", id)
+ if writeable {
+ if err = r.driver.CreateReadWrite(id, parent, &opts); err != nil {
+ if id != "" {
+ return nil, -1, errors.Wrapf(err, "error creating read-write layer with ID %q", id)
+ }
+ return nil, -1, errors.Wrapf(err, "error creating read-write layer")
+ }
+ } else {
+ if err = r.driver.Create(id, parent, &opts); err != nil {
+ if id != "" {
+ return nil, -1, errors.Wrapf(err, "error creating layer with ID %q", id)
+ }
+ return nil, -1, errors.Wrapf(err, "error creating layer")
}
- return nil, -1, errors.Wrapf(err, "error creating layer")
}
+ oldMappings = parentMappings
}
- if !reflect.DeepEqual(parentMappings.UIDs(), idMappings.UIDs()) || !reflect.DeepEqual(parentMappings.GIDs(), idMappings.GIDs()) {
- if err = r.driver.UpdateLayerIDMap(id, parentMappings, idMappings, mountLabel); err != nil {
+ if !reflect.DeepEqual(oldMappings.UIDs(), idMappings.UIDs()) || !reflect.DeepEqual(oldMappings.GIDs(), idMappings.GIDs()) {
+ if err = r.driver.UpdateLayerIDMap(id, oldMappings, idMappings, mountLabel); err != nil {
// We don't have a record of this layer, but at least
// try to clean it up underneath us.
r.driver.Remove(id)
diff --git a/vendor/github.com/containers/storage/layers_ffjson.go b/vendor/github.com/containers/storage/layers_ffjson.go
index 125b5d8c9..09b5d0f33 100644
--- a/vendor/github.com/containers/storage/layers_ffjson.go
+++ b/vendor/github.com/containers/storage/layers_ffjson.go
@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
-// source: layers.go
+// source: ./layers.go
package storage
diff --git a/vendor/github.com/containers/storage/pkg/archive/example_changes.go b/vendor/github.com/containers/storage/pkg/archive/example_changes.go
new file mode 100644
index 000000000..70f9c5564
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/archive/example_changes.go
@@ -0,0 +1,97 @@
+// +build ignore
+
+// Simple tool to create an archive stream from an old and new directory
+//
+// By default it will stream the comparison of two temporary directories with junk files
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+
+ "github.com/containers/storage/pkg/archive"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ flDebug = flag.Bool("D", false, "debugging output")
+ flNewDir = flag.String("newdir", "", "")
+ flOldDir = flag.String("olddir", "", "")
+ log = logrus.New()
+)
+
+func main() {
+ flag.Usage = func() {
+ fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)")
+ fmt.Printf("%s [OPTIONS]\n", os.Args[0])
+ flag.PrintDefaults()
+ }
+ flag.Parse()
+ log.Out = os.Stderr
+ if (len(os.Getenv("DEBUG")) > 0) || *flDebug {
+ logrus.SetLevel(logrus.DebugLevel)
+ }
+ var newDir, oldDir string
+
+ if len(*flNewDir) == 0 {
+ var err error
+ newDir, err = ioutil.TempDir("", "storage-test-newDir")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(newDir)
+ if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ newDir = *flNewDir
+ }
+
+ if len(*flOldDir) == 0 {
+ oldDir, err := ioutil.TempDir("", "storage-test-oldDir")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(oldDir)
+ } else {
+ oldDir = *flOldDir
+ }
+
+ changes, err := archive.ChangesDirs(newDir, oldDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ a, err := archive.ExportChanges(newDir, changes)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer a.Close()
+
+ i, err := io.Copy(os.Stdout, a)
+ if err != nil && err != io.EOF {
+ log.Fatal(err)
+ }
+ fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i)
+}
+
+func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) {
+ fileData := []byte("fooo")
+ for n := 0; n < numberOfFiles; n++ {
+ fileName := fmt.Sprintf("file-%d", n)
+ if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil {
+ return 0, err
+ }
+ if makeLinks {
+ if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil {
+ return 0, err
+ }
+ }
+ }
+ totalSize := numberOfFiles * len(fileData)
+ return totalSize, nil
+}
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index 5877c3b06..3fe305cc1 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -482,6 +482,10 @@ type LayerOptions struct {
// inherit settings from its parent layer or, if it has no parent
// layer, the Store object.
IDMappingOptions
+ // TemplateLayer is the ID of a layer whose contents will be used to
+ // initialize this layer. If set, it should be a child of the layer
+ // which we want to use as the parent of the new layer.
+ TemplateLayer string
}
// ImageOptions is used for passing options to a Store's CreateImage() method.
@@ -973,7 +977,7 @@ func (s *store) CreateImage(id string, names []string, layer, metadata string, o
return ristore.Create(id, names, layer, metadata, creationDate, options.Digest)
}
-func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, readWrite bool, rlstore LayerStore, lstores []ROLayerStore, options IDMappingOptions) (*Layer, error) {
+func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, createMappedLayer bool, rlstore LayerStore, lstores []ROLayerStore, options IDMappingOptions) (*Layer, error) {
layerMatchesMappingOptions := func(layer *Layer, options IDMappingOptions) bool {
// If the driver supports shifting and the layer has no mappings, we can use it.
if s.graphDriver.SupportsShifting() && len(layer.UIDMap) == 0 && len(layer.GIDMap) == 0 {
@@ -994,7 +998,6 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, read
return reflect.DeepEqual(layer.UIDMap, options.UIDMap) && reflect.DeepEqual(layer.GIDMap, options.GIDMap)
}
var layer, parentLayer *Layer
- var layerHomeStore ROLayerStore
// Locate the image's top layer and its parent, if it has one.
for _, store := range append([]ROLayerStore{rlstore}, lstores...) {
if store != rlstore {
@@ -1027,7 +1030,6 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, read
if layer == nil {
layer = cLayer
parentLayer = cParentLayer
- layerHomeStore = store
}
}
}
@@ -1037,27 +1039,25 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, read
}
// The top layer's mappings don't match the ones we want, but it's in a read-only
// image store, so we can't create and add a mapped copy of the layer to the image.
- if !readWrite {
+ // We'll have to do the mapping for the container itself, elsewhere.
+ if !createMappedLayer {
return layer, nil
}
// The top layer's mappings don't match the ones we want, and it's in an image store
// that lets us edit image metadata...
if istore, ok := ristore.(*imageStore); ok {
- // ... so extract the layer's contents, create a new copy of it with the
- // desired mappings, and register it as an alternate top layer in the image.
- noCompression := archive.Uncompressed
- diffOptions := DiffOptions{
- Compression: &noCompression,
- }
- rc, err := layerHomeStore.Diff("", layer.ID, &diffOptions)
- if err != nil {
- return nil, errors.Wrapf(err, "error reading layer %q to create an ID-mapped version of it", layer.ID)
- }
- defer rc.Close()
-
+ // ... so create a duplicate of the layer with the desired mappings, and
+ // register it as an alternate top layer in the image.
var layerOptions LayerOptions
if s.graphDriver.SupportsShifting() {
- layerOptions = LayerOptions{IDMappingOptions: IDMappingOptions{HostUIDMapping: true, HostGIDMapping: true, UIDMap: nil, GIDMap: nil}}
+ layerOptions = LayerOptions{
+ IDMappingOptions: IDMappingOptions{
+ HostUIDMapping: true,
+ HostGIDMapping: true,
+ UIDMap: nil,
+ GIDMap: nil,
+ },
+ }
} else {
layerOptions = LayerOptions{
IDMappingOptions: IDMappingOptions{
@@ -1068,9 +1068,10 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, read
},
}
}
- mappedLayer, _, err := rlstore.Put("", parentLayer, nil, layer.MountLabel, nil, &layerOptions, false, nil, rc)
+ layerOptions.TemplateLayer = layer.ID
+ mappedLayer, _, err := rlstore.Put("", parentLayer, nil, layer.MountLabel, nil, &layerOptions, false, nil, nil)
if err != nil {
- return nil, errors.Wrapf(err, "error creating ID-mapped copy of layer %q", layer.ID)
+ return nil, errors.Wrapf(err, "error creating an ID-mapped copy of layer %q", layer.ID)
}
if err = istore.addMappedTopLayer(image.ID, mappedLayer.ID); err != nil {
if err2 := rlstore.Delete(mappedLayer.ID); err2 != nil {
@@ -1144,7 +1145,9 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
}
imageID = cimage.ID
- ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, imageHomeStore == istore, rlstore, lstores, idMappingsOptions)
+ createMappedLayer := imageHomeStore == istore
+
+ ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, createMappedLayer, rlstore, lstores, idMappingsOptions)
if err != nil {
return nil, err
}
@@ -1170,7 +1173,14 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
}
var layerOptions *LayerOptions
if s.graphDriver.SupportsShifting() {
- layerOptions = &LayerOptions{IDMappingOptions: IDMappingOptions{HostUIDMapping: true, HostGIDMapping: true, UIDMap: nil, GIDMap: nil}}
+ layerOptions = &LayerOptions{
+ IDMappingOptions: IDMappingOptions{
+ HostUIDMapping: true,
+ HostGIDMapping: true,
+ UIDMap: nil,
+ GIDMap: nil,
+ },
+ }
} else {
layerOptions = &LayerOptions{
IDMappingOptions: IDMappingOptions{
@@ -2091,10 +2101,10 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error)
break
}
lastRemoved = layer
- layersToRemove = append(layersToRemove, lastRemoved)
if layer == image.TopLayer {
layersToRemove = append(layersToRemove, image.MappedTopLayers...)
}
+ layersToRemove = append(layersToRemove, lastRemoved)
layer = parent
}
} else {
@@ -3064,9 +3074,6 @@ type OptionsConfig struct {
// Size
Size string `toml:"size"`
- // OverrideKernelCheck
- OverrideKernelCheck string `toml:"override_kernel_check"`
-
// RemapUIDs is a list of default UID mappings to use for layers.
RemapUIDs string `toml:"remap-uids"`
// RemapGIDs is a list of default GID mappings to use for layers.
@@ -3191,9 +3198,6 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
if config.Storage.Options.MountOpt != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.MountOpt))
}
- if config.Storage.Options.OverrideKernelCheck != "" {
- storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.override_kernel_check=%s", config.Storage.Driver, config.Storage.Options.OverrideKernelCheck))
- }
if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup == "" {
config.Storage.Options.RemapGroup = config.Storage.Options.RemapUser
}
diff --git a/vendor/github.com/containers/storage/vendor.conf b/vendor/github.com/containers/storage/vendor.conf
index 936321b12..04af9010b 100644
--- a/vendor/github.com/containers/storage/vendor.conf
+++ b/vendor/github.com/containers/storage/vendor.conf
@@ -8,7 +8,7 @@ github.com/mattn/go-shellwords 753a2322a99f87c0eff284980e77f53041555bc6
github.com/mistifyio/go-zfs c0224de804d438efd11ea6e52ada8014537d6062
github.com/opencontainers/go-digest master
github.com/opencontainers/runc 6c22e77604689db8725fa866f0f2ec0b3e8c3a07
-github.com/opencontainers/selinux 36a9bc45a08c85f2c52bd9eb32e20267876773bd
+github.com/opencontainers/selinux v1.1
github.com/ostreedev/ostree-go master
github.com/pborman/uuid 1b00554d822231195d1babd97ff4a781231955c9
github.com/pkg/errors master
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index bb27ac936..4e9a8c54f 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -75,8 +75,8 @@ func ReleaseLabel(label string) error {
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) []string {
- return nil
+func DupSecOpt(src string) ([]string, error) {
+ return nil, nil
}
// DisableSecOpt returns a security opt that can disable labeling
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index de214b2d5..d4e26909d 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -4,6 +4,8 @@ package label
import (
"fmt"
+ "os"
+ "os/user"
"strings"
"github.com/opencontainers/selinux/go-selinux"
@@ -35,8 +37,15 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
ReleaseLabel(mountLabel)
}
}()
- pcon := selinux.NewContext(processLabel)
- mcon := selinux.NewContext(mountLabel)
+ pcon, err := selinux.NewContext(processLabel)
+ if err != nil {
+ return "", "", err
+ }
+
+ mcon, err := selinux.NewContext(mountLabel)
+ if err != nil {
+ return "", "", err
+ }
for _, opt := range options {
if opt == "disable" {
return "", mountLabel, nil
@@ -146,13 +155,56 @@ func Relabel(path string, fileLabel string, shared bool) error {
return nil
}
- exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true, "/tmp": true, "/home": true, "/run": true, "/var": true, "/root": true}
+ exclude_paths := map[string]bool{
+ "/": true,
+ "/bin": true,
+ "/boot": true,
+ "/dev": true,
+ "/etc": true,
+ "/etc/passwd": true,
+ "/etc/pki": true,
+ "/etc/shadow": true,
+ "/home": true,
+ "/lib": true,
+ "/lib64": true,
+ "/media": true,
+ "/opt": true,
+ "/proc": true,
+ "/root": true,
+ "/run": true,
+ "/sbin": true,
+ "/srv": true,
+ "/sys": true,
+ "/tmp": true,
+ "/usr": true,
+ "/var": true,
+ "/var/lib": true,
+ "/var/log": true,
+ }
+
+ if home := os.Getenv("HOME"); home != "" {
+ exclude_paths[home] = true
+ }
+
+ if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" {
+ if usr, err := user.Lookup(sudoUser); err == nil {
+ exclude_paths[usr.HomeDir] = true
+ }
+ }
+
+ if path != "/" {
+ path = strings.TrimSuffix(path, "/")
+ }
if exclude_paths[path] {
return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
}
if shared {
- c := selinux.NewContext(fileLabel)
+ c, err := selinux.NewContext(fileLabel)
+ if err != nil {
+ return err
+ }
+
c["level"] = "s0"
fileLabel = c.Get()
}
@@ -195,7 +247,7 @@ func ReleaseLabel(label string) error {
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) []string {
+func DupSecOpt(src string) ([]string, error) {
return selinux.DupSecOpt(src)
}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index 7832f7497..5adafd317 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -52,6 +52,8 @@ var (
ErrMCSAlreadyExists = errors.New("MCS label already exists")
// ErrEmptyPath is returned when an empty path has been specified.
ErrEmptyPath = errors.New("empty path")
+ // InvalidLabel is returned when an invalid label is specified.
+ InvalidLabel = errors.New("Invalid Label")
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
roFileLabel string
@@ -405,11 +407,14 @@ func (c Context) Get() string {
}
// NewContext creates a new Context struct from the specified label
-func NewContext(label string) Context {
+func NewContext(label string) (Context, error) {
c := make(Context)
if len(label) != 0 {
con := strings.SplitN(label, ":", 4)
+ if len(con) < 3 {
+ return c, InvalidLabel
+ }
c["user"] = con[0]
c["role"] = con[1]
c["type"] = con[2]
@@ -417,7 +422,7 @@ func NewContext(label string) Context {
c["level"] = con[3]
}
}
- return c
+ return c, nil
}
// ClearLabels clears all reserved labels
@@ -630,12 +635,12 @@ func ContainerLabels() (processLabel string, fileLabel string) {
roFileLabel = fileLabel
}
exit:
- scon := NewContext(processLabel)
+ scon, _ := NewContext(processLabel)
if scon["level"] != "" {
mcs := uniqMcs(1024)
scon["level"] = mcs
processLabel = scon.Get()
- scon = NewContext(fileLabel)
+ scon, _ = NewContext(fileLabel)
scon["level"] = mcs
fileLabel = scon.Get()
}
@@ -661,8 +666,14 @@ func CopyLevel(src, dest string) (string, error) {
if err := SecurityCheckContext(dest); err != nil {
return "", err
}
- scon := NewContext(src)
- tcon := NewContext(dest)
+ scon, err := NewContext(src)
+ if err != nil {
+ return "", err
+ }
+ tcon, err := NewContext(dest)
+ if err != nil {
+ return "", err
+ }
mcsDelete(tcon["level"])
mcsAdd(scon["level"])
tcon["level"] = scon["level"]
@@ -714,15 +725,18 @@ func Chcon(fpath string, label string, recurse bool) error {
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
-func DupSecOpt(src string) []string {
+func DupSecOpt(src string) ([]string, error) {
if src == "" {
- return nil
+ return nil, nil
+ }
+ con, err := NewContext(src)
+ if err != nil {
+ return nil, err
}
- con := NewContext(src)
if con["user"] == "" ||
con["role"] == "" ||
con["type"] == "" {
- return nil
+ return nil, nil
}
dup := []string{"user:" + con["user"],
"role:" + con["role"],
@@ -733,7 +747,7 @@ func DupSecOpt(src string) []string {
dup = append(dup, "level:"+con["level"])
}
- return dup
+ return dup, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index 99efa155a..9497acbd0 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -115,9 +115,9 @@ func (c Context) Get() string {
}
// NewContext creates a new Context struct from the specified label
-func NewContext(label string) Context {
+func NewContext(label string) (Context, error) {
c := make(Context)
- return c
+ return c, nil
}
// ClearLabels clears all reserved MLS/MCS levels
@@ -195,8 +195,8 @@ func Chcon(fpath string, label string, recurse bool) error {
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
-func DupSecOpt(src string) []string {
- return nil
+func DupSecOpt(src string) ([]string, error) {
+ return nil, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
diff --git a/vendor/github.com/urfave/cli/help.go b/vendor/github.com/urfave/cli/help.go
index 65874fa2f..a0e949f72 100644
--- a/vendor/github.com/urfave/cli/help.go
+++ b/vendor/github.com/urfave/cli/help.go
@@ -82,7 +82,7 @@ OPTIONS:
var helpCommand = Command{
Name: "help",
Aliases: []string{"h"},
- Usage: "Shows a list of commands or help for one command",
+ Usage: "Show a list of commands or help for one command",
ArgsUsage: "[command]",
Action: func(c *Context) error {
args := c.Args()
diff --git a/vendor/github.com/varlink/go/.gitignore b/vendor/github.com/varlink/go/.gitignore
index 69e30cff1..a43b0e2d3 100644
--- a/vendor/github.com/varlink/go/.gitignore
+++ b/vendor/github.com/varlink/go/.gitignore
@@ -1 +1,2 @@
/cmd/varlink-go-certification/orgvarlinkcertification/orgvarlinkcertification.go
+/.idea
diff --git a/vendor/github.com/varlink/go/.travis.yml b/vendor/github.com/varlink/go/.travis.yml
index c090a924f..fa9963500 100644
--- a/vendor/github.com/varlink/go/.travis.yml
+++ b/vendor/github.com/varlink/go/.travis.yml
@@ -1,11 +1,13 @@
language: go
sudo: false
go:
-- '1.9'
-- 1.10.x
+- '1.10'
+- 1.11.x
install:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
+- go get github.com/TylerBrock/colorjson
+- go get github.com/fatih/color
script:
- go generate ./...
- '"$HOME/gopath/bin/goveralls" -v -show -service=travis-ci -repotoken "$COVERALLS_TOKEN"'
diff --git a/vendor/github.com/varlink/go/cmd/varlink/main.go b/vendor/github.com/varlink/go/cmd/varlink/main.go
new file mode 100644
index 000000000..1de4e1a45
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink/main.go
@@ -0,0 +1,295 @@
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "github.com/TylerBrock/colorjson"
+ "github.com/fatih/color"
+ "github.com/varlink/go/varlink"
+ "os"
+ "strings"
+)
+
+var bold = color.New(color.Bold)
+var errorBoldRed = bold.Sprint(color.New(color.FgRed).Sprint("Error:"))
+var bridge string
+
+func ErrPrintf(format string, a ...interface{}) {
+ fmt.Fprintf(os.Stderr, "%s ", errorBoldRed)
+ fmt.Fprintf(os.Stderr, format, a...)
+}
+
+func print_usage(set *flag.FlagSet, arg_help string) {
+ if set == nil {
+ fmt.Fprintf(os.Stderr, "Usage: %s [GLOBAL OPTIONS] COMMAND ...\n", os.Args[0])
+ } else {
+ fmt.Fprintf(os.Stderr, "Usage: %s [GLOBAL OPTIONS] %s [OPTIONS] %s\n", os.Args[0], set.Name(), arg_help)
+ }
+
+ fmt.Fprintln(os.Stderr, "\nGlobal Options:")
+ flag.PrintDefaults()
+
+ if set == nil {
+ fmt.Fprintln(os.Stderr, "\nCommands:")
+ fmt.Fprintln(os.Stderr, " info\tPrint information about a service")
+ fmt.Fprintln(os.Stderr, " help\tPrint interface description or service information")
+ fmt.Fprintln(os.Stderr, " call\tCall a method")
+ } else {
+ fmt.Fprintln(os.Stderr, "\nOptions:")
+ set.PrintDefaults()
+ }
+ os.Exit(1)
+}
+
+func varlink_call(args []string) {
+ var err error
+ var oneway bool
+
+ callFlags := flag.NewFlagSet("help", flag.ExitOnError)
+ callFlags.BoolVar(&oneway, "-oneway", false, "Use bridge for connection")
+ var help bool
+ callFlags.BoolVar(&help, "help", false, "Prints help information")
+ var usage = func() { print_usage(callFlags, "<[ADDRESS/]INTERFACE.METHOD> [ARGUMENTS]") }
+ callFlags.Usage = usage
+
+ _ = callFlags.Parse(args)
+
+ if help {
+ usage()
+ }
+
+ var con *varlink.Connection
+ var address string
+ var methodName string
+
+ if len(bridge) != 0 {
+ con, err = varlink.NewBridge(bridge)
+
+ if err != nil {
+ ErrPrintf("Cannot connect with bridge '%s': %v\n", bridge, err)
+ os.Exit(2)
+ }
+ address = "bridge:" + bridge
+ methodName = callFlags.Arg(0)
+ } else {
+ uri := callFlags.Arg(0)
+ if uri == "" {
+ usage()
+ }
+
+ li := strings.LastIndex(uri, "/")
+
+ if li == -1 {
+ ErrPrintf("Invalid address '%s'\n", uri)
+ os.Exit(2)
+ }
+
+ address = uri[:li]
+ methodName = uri[li+1:]
+
+ con, err = varlink.NewConnection(address)
+
+ if err != nil {
+ ErrPrintf("Cannot connect to '%s': %v\n", address, err)
+ os.Exit(2)
+ }
+ }
+ var parameters string
+ var params json.RawMessage
+
+ parameters = callFlags.Arg(1)
+ if parameters == "" {
+ params = nil
+ } else {
+ json.Unmarshal([]byte(parameters), &params)
+ }
+
+ var flags uint64
+ flags = 0
+ if oneway {
+ flags |= varlink.Oneway
+ }
+ recv, err := con.Send(methodName, params, flags)
+
+ var retval map[string]interface{}
+
+ // FIXME: Use cont
+ _, err = recv(&retval)
+
+ f := colorjson.NewFormatter()
+ f.Indent = 2
+ f.KeyColor = color.New(color.FgCyan)
+ f.StringColor = color.New(color.FgMagenta)
+ f.NumberColor = color.New(color.FgMagenta)
+ f.BoolColor = color.New(color.FgMagenta)
+ f.NullColor = color.New(color.FgMagenta)
+
+ if err != nil {
+ ErrPrintf("Error calling '%s': %v\n", methodName, err)
+ switch e := err.(type) {
+ case *varlink.Error:
+ println(e.Name)
+ errorRawParameters := e.Parameters.(*json.RawMessage)
+
+ if errorRawParameters == nil {
+ break
+ }
+ var param map[string]interface{}
+ _ = json.Unmarshal(*errorRawParameters, &param)
+ c, _ := f.Marshal(param)
+ ErrPrintf("%v\n", string(c))
+ }
+ os.Exit(2)
+ }
+ c, _ := f.Marshal(retval)
+ fmt.Println(string(c))
+}
+
+func varlink_help(args []string) {
+ var err error
+
+ helpFlags := flag.NewFlagSet("help", flag.ExitOnError)
+ var help bool
+ helpFlags.BoolVar(&help, "help", false, "Prints help information")
+ var usage = func() { print_usage(helpFlags, "<[ADDRESS/]INTERFACE>") }
+ helpFlags.Usage = usage
+
+ _ = helpFlags.Parse(args)
+
+ if help {
+ usage()
+ }
+
+ var con *varlink.Connection
+ var address string
+ var interfaceName string
+
+ if len(bridge) != 0 {
+ con, err = varlink.NewBridge(bridge)
+
+ if err != nil {
+ ErrPrintf("Cannot connect with bridge '%s': %v\n", bridge, err)
+ os.Exit(2)
+ }
+ address = "bridge:" + bridge
+ interfaceName = helpFlags.Arg(0)
+ } else {
+ uri := helpFlags.Arg(0)
+ if uri == "" && bridge == "" {
+ ErrPrintf("No ADDRESS or activation or bridge\n\n")
+ usage()
+ }
+
+ li := strings.LastIndex(uri, "/")
+
+ if li == -1 {
+ ErrPrintf("Invalid address '%s'\n", uri)
+ os.Exit(2)
+ }
+
+ address = uri[:li]
+
+ con, err = varlink.NewConnection(address)
+
+ if err != nil {
+ ErrPrintf("Cannot connect to '%s': %v\n", address, err)
+ os.Exit(2)
+ }
+
+ interfaceName = uri[li+1:]
+ }
+ description, err := con.GetInterfaceDescription(interfaceName)
+
+ if err != nil {
+ ErrPrintf("Cannot get interface description for '%s': %v\n", interfaceName, err)
+ os.Exit(2)
+ }
+
+ fmt.Println(description)
+}
+
+func varlink_info(args []string) {
+ var err error
+ infoFlags := flag.NewFlagSet("info", flag.ExitOnError)
+ var help bool
+ infoFlags.BoolVar(&help, "help", false, "Prints help information")
+ var usage = func() { print_usage(infoFlags, "[ADDRESS]") }
+ infoFlags.Usage = usage
+
+ _ = infoFlags.Parse(args)
+
+ if help {
+ usage()
+ }
+
+ var con *varlink.Connection
+ var address string
+
+ if len(bridge) != 0 {
+ con, err = varlink.NewBridge(bridge)
+
+ if err != nil {
+ ErrPrintf("Cannot connect with bridge '%s': %v\n", bridge, err)
+ os.Exit(2)
+ }
+ address = "bridge:" + bridge
+ } else {
+ address = infoFlags.Arg(0)
+
+ if address == "" && bridge == "" {
+ ErrPrintf("No ADDRESS or activation or bridge\n\n")
+ usage()
+ }
+
+ con, err = varlink.NewConnection(address)
+
+ if err != nil {
+ ErrPrintf("Cannot connect to '%s': %v\n", address, err)
+ os.Exit(2)
+ }
+ }
+
+ var vendor, product, version, url string
+ var interfaces []string
+
+ err = con.GetInfo(&vendor, &product, &version, &url, &interfaces)
+
+ if err != nil {
+ ErrPrintf("Cannot get info for '%s': %v\n", address, err)
+ os.Exit(2)
+ }
+
+ fmt.Printf("%s %s\n", bold.Sprint("Vendor:"), vendor)
+ fmt.Printf("%s %s\n", bold.Sprint("Product:"), product)
+ fmt.Printf("%s %s\n", bold.Sprint("Version:"), version)
+ fmt.Printf("%s %s\n", bold.Sprint("URL:"), url)
+ fmt.Printf("%s\n %s\n\n", bold.Sprint("Interfaces:"), strings.Join(interfaces[:], "\n "))
+}
+
+func main() {
+ var debug bool
+ var colorMode string
+
+ flag.CommandLine.Usage = func() { print_usage(nil, "") }
+ flag.BoolVar(&debug, "debug", false, "Enable debug output")
+ flag.StringVar(&bridge, "bridge", "", "Use bridge for connection")
+ flag.StringVar(&colorMode, "color", "auto", "colorize output [default: auto] [possible values: on, off, auto]")
+
+ flag.Parse()
+
+ if colorMode != "on" && (os.Getenv("TERM") == "" || colorMode == "off") {
+ color.NoColor = true // disables colorized output
+ }
+
+ switch flag.Arg(0) {
+ case "info":
+ varlink_info(flag.Args()[1:])
+ case "help":
+ varlink_help(flag.Args()[1:])
+ case "call":
+ varlink_call(flag.Args()[1:])
+ default:
+ print_usage(nil, "")
+ }
+}
diff --git a/vendor/github.com/varlink/go/varlink/bridge.go b/vendor/github.com/varlink/go/varlink/bridge.go
new file mode 100644
index 000000000..b20c0925a
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/bridge.go
@@ -0,0 +1,59 @@
+// +build !windows
+
+package varlink
+
+import (
+ "bufio"
+ "io"
+ "log"
+ "net"
+ "os/exec"
+)
+
+type PipeCon struct {
+ net.Conn
+ reader *io.ReadCloser
+ writer *io.WriteCloser
+}
+
+func (p PipeCon) Close() error {
+ err1 := (*p.reader).Close()
+ err2 := (*p.writer).Close()
+ if err1 != nil {
+ return err1
+ }
+ if err2 != nil {
+ return err2
+ }
+ return nil
+}
+
+// NewConnection returns a new connection to the given address.
+func NewBridge(bridge string) (*Connection, error) {
+ //var err error
+
+ c := Connection{}
+ cmd := exec.Command("sh", "-c", bridge)
+ r, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ w, err := cmd.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+ c.conn = PipeCon{nil, &r, &w}
+ c.address = ""
+ c.reader = bufio.NewReader(r)
+ c.writer = bufio.NewWriter(w)
+
+ go func() {
+ err := cmd.Run()
+ if err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ return &c, nil
+}
+
diff --git a/vendor/github.com/varlink/go/varlink/bridge_windows.go b/vendor/github.com/varlink/go/varlink/bridge_windows.go
new file mode 100644
index 000000000..692367a1a
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/bridge_windows.go
@@ -0,0 +1,57 @@
+package varlink
+
+import (
+ "bufio"
+ "io"
+ "log"
+ "net"
+ "os/exec"
+)
+
+type PipeCon struct {
+ net.Conn
+ reader *io.ReadCloser
+ writer *io.WriteCloser
+}
+
+func (p PipeCon) Close() error {
+ err1 := (*p.reader).Close()
+ err2 := (*p.writer).Close()
+ if err1 != nil {
+ return err1
+ }
+ if err2 != nil {
+ return err2
+ }
+ return nil
+}
+
+// NewConnection returns a new connection to the given address.
+func NewBridge(bridge string) (*Connection, error) {
+ //var err error
+
+ c := Connection{}
+ cmd := exec.Command("cmd", "/C", bridge)
+ r, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ w, err := cmd.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+ c.conn = PipeCon{nil, &r, &w}
+ c.address = ""
+ c.reader = bufio.NewReader(r)
+ c.writer = bufio.NewWriter(w)
+
+ go func() {
+ err := cmd.Run()
+ if err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ return &c, nil
+}
+
diff --git a/vendor/github.com/varlink/go/varlink/connection.go b/vendor/github.com/varlink/go/varlink/connection.go
index 43bec6393..ac9542408 100644
--- a/vendor/github.com/varlink/go/varlink/connection.go
+++ b/vendor/github.com/varlink/go/varlink/connection.go
@@ -3,6 +3,7 @@ package varlink
import (
"bufio"
"encoding/json"
+ "fmt"
"net"
"strings"
)
@@ -18,6 +19,7 @@ const (
// Error is a varlink error returned from a method call.
type Error struct {
+ error
Name string
Parameters interface{}
}
@@ -189,6 +191,11 @@ func NewConnection(address string) (*Connection, error) {
var err error
words := strings.SplitN(address, ":", 2)
+
+ if len(words) != 2 {
+ return nil, fmt.Errorf("Protocol missing")
+ }
+
protocol := words[0]
addr := words[1]
diff --git a/vendor/github.com/varlink/go/varlink/service.go b/vendor/github.com/varlink/go/varlink/service.go
index 551ba4e53..cb461f917 100644
--- a/vendor/github.com/varlink/go/varlink/service.go
+++ b/vendor/github.com/varlink/go/varlink/service.go
@@ -6,10 +6,8 @@ import (
"fmt"
"net"
"os"
- "strconv"
"strings"
"sync"
- "syscall"
"time"
)
@@ -110,58 +108,6 @@ func (s *Service) handleMessage(writer *bufio.Writer, request []byte) error {
return iface.VarlinkDispatch(c, methodname)
}
-func activationListener() net.Listener {
- pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
- if err != nil || pid != os.Getpid() {
- return nil
- }
-
- nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
- if err != nil || nfds < 1 {
- return nil
- }
-
- fd := -1
-
- // If more than one file descriptor is passed, find the
- // "varlink" tag. The first file descriptor is always 3.
- if nfds > 1 {
- fdnames, set := os.LookupEnv("LISTEN_FDNAMES")
- if !set {
- return nil
- }
-
- names := strings.Split(fdnames, ":")
- if len(names) != nfds {
- return nil
- }
-
- for i, name := range names {
- if name == "varlink" {
- fd = 3 + i
- break
- }
- }
-
- if fd < 0 {
- return nil
- }
-
- } else {
- fd = 3
- }
-
- syscall.CloseOnExec(fd)
-
- file := os.NewFile(uintptr(fd), "varlink")
- listener, err := net.FileListener(file)
- if err != nil {
- return nil
- }
-
- return listener
-}
-
// Shutdown shuts down the listener of a running service.
func (s *Service) Shutdown() {
s.running = false
@@ -253,18 +199,17 @@ func getListener(protocol string, address string) (net.Listener, error) {
}
func (s *Service) refreshTimeout(timeout time.Duration) error {
- switch s.protocol {
- case "unix":
- if err := s.listener.(*net.UnixListener).SetDeadline(time.Now().Add(timeout)); err != nil {
+ switch l := s.listener.(type) {
+ case *net.UnixListener:
+ if err:= l.SetDeadline(time.Now().Add(timeout)); err != nil {
return err
}
-
- case "tcp":
- if err := s.listener.(*net.TCPListener).SetDeadline(time.Now().Add(timeout)); err != nil {
+ case *net.TCPListener:
+ if err:= l.SetDeadline(time.Now().Add(timeout)); err != nil {
return err
}
- }
+ }
return nil
}
diff --git a/vendor/github.com/varlink/go/varlink/socketactivation.go b/vendor/github.com/varlink/go/varlink/socketactivation.go
new file mode 100644
index 000000000..a64c0dc8e
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/socketactivation.go
@@ -0,0 +1,63 @@
+// +build !windows
+
+package varlink
+
+import (
+ "net"
+ "os"
+ "strconv"
+ "strings"
+ "syscall"
+)
+
+func activationListener() net.Listener {
+ pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
+ if err != nil || pid != os.Getpid() {
+ return nil
+ }
+
+ nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
+ if err != nil || nfds < 1 {
+ return nil
+ }
+
+ fd := -1
+
+ // If more than one file descriptor is passed, find the
+ // "varlink" tag. The first file descriptor is always 3.
+ if nfds > 1 {
+ fdnames, set := os.LookupEnv("LISTEN_FDNAMES")
+ if !set {
+ return nil
+ }
+
+ names := strings.Split(fdnames, ":")
+ if len(names) != nfds {
+ return nil
+ }
+
+ for i, name := range names {
+ if name == "varlink" {
+ fd = 3 + i
+ break
+ }
+ }
+
+ if fd < 0 {
+ return nil
+ }
+
+ } else {
+ fd = 3
+ }
+
+ syscall.CloseOnExec(fd)
+
+ file := os.NewFile(uintptr(fd), "varlink")
+ listener, err := net.FileListener(file)
+ if err != nil {
+ return nil
+ }
+
+ return listener
+}
diff --git a/vendor/github.com/varlink/go/varlink/socketactivation_windows.go b/vendor/github.com/varlink/go/varlink/socketactivation_windows.go
new file mode 100644
index 000000000..fb0894531
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/socketactivation_windows.go
@@ -0,0 +1,7 @@
+package varlink
+
+import "net"
+
+func activationListener() net.Listener {
+ return nil
+}