diff --git a/daemon/execdriver/native/init.go b/daemon/execdriver/native/init.go
index c1c988d934..754d842c3b 100644
--- a/daemon/execdriver/native/init.go
+++ b/daemon/execdriver/native/init.go
@@ -13,7 +13,6 @@ import (
"github.com/docker/docker/pkg/reexec"
"github.com/docker/libcontainer"
"github.com/docker/libcontainer/namespaces"
- "github.com/docker/libcontainer/syncpipe"
)
func init() {
@@ -48,12 +47,7 @@ func initializer() {
writeError(err)
}
- syncPipe, err := syncpipe.NewSyncPipeFromFd(0, uintptr(*pipe))
- if err != nil {
- writeError(err)
- }
-
- if err := namespaces.Init(container, rootfs, *console, syncPipe, flag.Args()); err != nil {
+ if err := namespaces.Init(container, rootfs, *console, os.NewFile(uintptr(*pipe), "child"), flag.Args()); err != nil {
writeError(err)
}
diff --git a/daemon/execdriver/native/utils.go b/daemon/execdriver/native/utils.go
index e337cf4316..88aefaf382 100644
--- a/daemon/execdriver/native/utils.go
+++ b/daemon/execdriver/native/utils.go
@@ -3,10 +3,10 @@
package native
import (
+ "encoding/json"
"os"
"github.com/docker/libcontainer"
- "github.com/docker/libcontainer/syncpipe"
)
func findUserArgs() []string {
@@ -21,15 +21,9 @@ func findUserArgs() []string {
// loadConfigFromFd loads a container's config from the sync pipe that is provided by
// fd 3 when running a process
func loadConfigFromFd() (*libcontainer.Config, error) {
- syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3)
- if err != nil {
- return nil, err
- }
-
var config *libcontainer.Config
- if err := syncPipe.ReadFromParent(&config); err != nil {
+ if err := json.NewDecoder(os.NewFile(3, "child")).Decode(&config); err != nil {
return nil, err
}
-
return config, nil
}
diff --git a/hack/vendor.sh b/hack/vendor.sh
index 85be29303e..ae45dbe2d8 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -66,7 +66,7 @@ if [ "$1" = '--go' ]; then
mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
fi
-clone git github.com/docker/libcontainer f60d7b9195f8dc0b5d343abbc3293da7c17bb11c
+clone git github.com/docker/libcontainer fd6df76562137aa3b18e44b790cb484fe2b6fa0b
# see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
rm -rf src/github.com/docker/libcontainer/vendor
eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"
diff --git a/vendor/src/github.com/Sirupsen/logrus/formatter_bench_test.go b/vendor/src/github.com/Sirupsen/logrus/formatter_bench_test.go
new file mode 100644
index 0000000000..77989da629
--- /dev/null
+++ b/vendor/src/github.com/Sirupsen/logrus/formatter_bench_test.go
@@ -0,0 +1,88 @@
+package logrus
+
+import (
+ "testing"
+ "time"
+)
+
+// smallFields is a small size data set for benchmarking
+var smallFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+}
+
+// largeFields is a large size data set for benchmarking
+var largeFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+ "five": "six",
+ "seven": "eight",
+ "nine": "ten",
+ "eleven": "twelve",
+ "thirteen": "fourteen",
+ "fifteen": "sixteen",
+ "seventeen": "eighteen",
+ "nineteen": "twenty",
+ "a": "b",
+ "c": "d",
+ "e": "f",
+ "g": "h",
+ "i": "j",
+ "k": "l",
+ "m": "n",
+ "o": "p",
+ "q": "r",
+ "s": "t",
+ "u": "v",
+ "w": "x",
+ "y": "z",
+ "this": "will",
+ "make": "thirty",
+ "entries": "yeah",
+}
+
+func BenchmarkSmallTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func BenchmarkLargeTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
+}
+
+func BenchmarkSmallColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
+}
+
+func BenchmarkLargeColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
+}
+
+func BenchmarkSmallJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, smallFields)
+}
+
+func BenchmarkLargeJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, largeFields)
+}
+
+func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
+ entry := &Entry{
+ Time: time.Time{},
+ Level: InfoLevel,
+ Message: "message",
+ Data: fields,
+ }
+ var d []byte
+ var err error
+ for i := 0; i < b.N; i++ {
+ d, err = formatter.Format(entry)
+ if err != nil {
+ b.Fatal(err)
+ }
+ b.SetBytes(int64(len(d)))
+ }
+}
diff --git a/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
new file mode 100644
index 0000000000..ae61e9229a
--- /dev/null
+++ b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
@@ -0,0 +1,28 @@
+# Papertrail Hook for Logrus
+
+[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
+
+In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
+
+## Usage
+
+You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
+
+For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
+
+```go
+import (
+ "log/syslog"
+ "github.com/Sirupsen/logrus"
+ "github.com/Sirupsen/logrus/hooks/papertrail"
+)
+
+func main() {
+ log := logrus.New()
+ hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
+
+ if err == nil {
+ log.Hooks.Add(hook)
+ }
+}
+```
diff --git a/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
new file mode 100644
index 0000000000..48e2feaeb5
--- /dev/null
+++ b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
@@ -0,0 +1,54 @@
+package logrus_papertrail
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "time"
+
+ "github.com/Sirupsen/logrus"
+)
+
+const (
+ format = "Jan 2 15:04:05"
+)
+
+// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
+type PapertrailHook struct {
+ Host string
+ Port int
+ AppName string
+ UDPConn net.Conn
+}
+
+// NewPapertrailHook creates a hook to be added to an instance of logger.
+func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
+ conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
+ return &PapertrailHook{host, port, appName, conn}, err
+}
+
+// Fire is called when a log event is fired.
+func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
+ date := time.Now().Format(format)
+ payload := fmt.Sprintf("<22> %s %s: [%s] %s", date, hook.AppName, entry.Data["level"], entry.Message)
+
+ bytesWritten, err := hook.UDPConn.Write([]byte(payload))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
+ return err
+ }
+
+ return nil
+}
+
+// Levels returns the available logging levels.
+func (hook *PapertrailHook) Levels() []logrus.Level {
+ return []logrus.Level{
+ logrus.PanicLevel,
+ logrus.FatalLevel,
+ logrus.ErrorLevel,
+ logrus.WarnLevel,
+ logrus.InfoLevel,
+ logrus.DebugLevel,
+ }
+}
diff --git a/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
new file mode 100644
index 0000000000..96318d0030
--- /dev/null
+++ b/vendor/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
@@ -0,0 +1,26 @@
+package logrus_papertrail
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/stvp/go-udp-testing"
+)
+
+func TestWritingToUDP(t *testing.T) {
+ port := 16661
+ udp.SetAddr(fmt.Sprintf(":%d", port))
+
+ hook, err := NewPapertrailHook("localhost", port, "test")
+ if err != nil {
+ t.Errorf("Unable to connect to local UDP server.")
+ }
+
+ log := logrus.New()
+ log.Hooks.Add(hook)
+
+ udp.ShouldReceive(t, "foo", func() {
+ log.Info("foo")
+ })
+}
diff --git a/vendor/src/github.com/docker/libcontainer/.drone.yml b/vendor/src/github.com/docker/libcontainer/.drone.yml
new file mode 100755
index 0000000000..80d298f218
--- /dev/null
+++ b/vendor/src/github.com/docker/libcontainer/.drone.yml
@@ -0,0 +1,9 @@
+image: dockercore/libcontainer
+script:
+# Setup the DockerInDocker environment.
+ - /dind
+ - sed -i 's!docker/docker!docker/libcontainer!' /go/src/github.com/docker/docker/hack/make/.validate
+ - bash /go/src/github.com/docker/docker/hack/make/validate-dco
+ - bash /go/src/github.com/docker/docker/hack/make/validate-gofmt
+ - export GOPATH="$GOPATH:/go:$(pwd)/vendor" # Drone mucks with our GOPATH
+ - make direct-test
diff --git a/vendor/src/github.com/docker/libcontainer/.travis.yml b/vendor/src/github.com/docker/libcontainer/.travis.yml
deleted file mode 100644
index 3ce0e27e45..0000000000
--- a/vendor/src/github.com/docker/libcontainer/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-language: go
-go: 1.3
-
-# let us have pretty experimental Docker-based Travis workers
-sudo: false
-
-env:
- - TRAVIS_GLOBAL_WTF=1
- - _GOOS=linux _GOARCH=amd64 CGO_ENABLED=1
- - _GOOS=linux _GOARCH=amd64 CGO_ENABLED=0
-# - _GOOS=linux _GOARCH=386 CGO_ENABLED=1 # TODO add this once Travis can handle it (https://github.com/travis-ci/travis-ci/issues/2207#issuecomment-49625061)
- - _GOOS=linux _GOARCH=386 CGO_ENABLED=0
- - _GOOS=linux _GOARCH=arm CGO_ENABLED=0
-
-install:
- - go get code.google.com/p/go.tools/cmd/cover
- - mkdir -pv "${GOPATH%%:*}/src/github.com/docker" && [ -d "${GOPATH%%:*}/src/github.com/docker/libcontainer" ] || ln -sv "$(readlink -f .)" "${GOPATH%%:*}/src/github.com/docker/libcontainer"
- - if [ -z "$TRAVIS_GLOBAL_WTF" ]; then
- gvm cross "$_GOOS" "$_GOARCH";
- export GOOS="$_GOOS" GOARCH="$_GOARCH";
- fi
- - export GOPATH="$GOPATH:$(pwd)/vendor"
- - if [ -z "$TRAVIS_GLOBAL_WTF" ]; then go env; fi
- - go get -d -v ./... # TODO remove this if /docker/docker gets purged from our includes
- - if [ "$TRAVIS_GLOBAL_WTF" ]; then
- export DOCKER_PATH="${GOPATH%%:*}/src/github.com/docker/docker";
- mkdir -p "$DOCKER_PATH/hack/make";
- ( cd "$DOCKER_PATH/hack/make" && wget -c 'https://raw.githubusercontent.com/docker/docker/master/hack/make/'{.validate,validate-dco,validate-gofmt} );
- sed -i 's!docker/docker!docker/libcontainer!' "$DOCKER_PATH/hack/make/.validate";
- fi
-
-script:
- - if [ "$TRAVIS_GLOBAL_WTF" ]; then bash "$DOCKER_PATH/hack/make/validate-dco"; fi
- - if [ "$TRAVIS_GLOBAL_WTF" ]; then bash "$DOCKER_PATH/hack/make/validate-gofmt"; fi
- - if [ -z "$TRAVIS_GLOBAL_WTF" ]; then make direct-build; fi
- - if [ -z "$TRAVIS_GLOBAL_WTF" -a "$GOARCH" != 'arm' ]; then make direct-test-short; fi
diff --git a/vendor/src/github.com/docker/libcontainer/MAINTAINERS b/vendor/src/github.com/docker/libcontainer/MAINTAINERS
index 24011b0540..7295c6038f 100644
--- a/vendor/src/github.com/docker/libcontainer/MAINTAINERS
+++ b/vendor/src/github.com/docker/libcontainer/MAINTAINERS
@@ -2,5 +2,4 @@ Michael Crosby (@crosbymichael)
Rohit Jnagal (@rjnagal)
Victor Marmol (@vmarmol)
Mrunal Patel (@mrunalp)
-.travis.yml: Tianon Gravi (@tianon)
update-vendor.sh: Tianon Gravi (@tianon)
diff --git a/vendor/src/github.com/docker/libcontainer/README.md b/vendor/src/github.com/docker/libcontainer/README.md
index 3201df9b98..37047e68c8 100644
--- a/vendor/src/github.com/docker/libcontainer/README.md
+++ b/vendor/src/github.com/docker/libcontainer/README.md
@@ -1,4 +1,4 @@
-## libcontainer - reference implementation for containers [](https://travis-ci.org/docker/libcontainer)
+## libcontainer - reference implementation for containers [](https://ci.dockerproject.com/github.com/docker/libcontainer)
### Note on API changes:
diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
index f1afd49411..8b19a84b27 100644
--- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
+++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
@@ -57,7 +57,7 @@ func TestGetCgroupParamsInt(t *testing.T) {
if err != nil {
t.Fatal(err)
} else if value != 0 {
- t.Fatalf("Expected %d to equal %f", value, 0)
+ t.Fatalf("Expected %d to equal %d", value, 0)
}
// Success with negative values lesser than min int64
@@ -70,7 +70,7 @@ func TestGetCgroupParamsInt(t *testing.T) {
if err != nil {
t.Fatal(err)
} else if value != 0 {
- t.Fatalf("Expected %d to equal %f", value, 0)
+ t.Fatalf("Expected %d to equal %d", value, 0)
}
// Not a float.
diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
index 1f84a9c6f2..5155b67535 100644
--- a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
+++ b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
@@ -43,6 +43,13 @@ var (
}
)
+func newProp(name string, units interface{}) systemd.Property {
+ return systemd.Property{
+ Name: name,
+ Value: dbus.MakeVariant(units),
+ }
+}
+
func UseSystemd() bool {
s, err := os.Stat("/run/systemd/system")
if err != nil || !s.IsDir() {
@@ -99,27 +106,27 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
}
properties = append(properties,
- systemd.Property{"Slice", dbus.MakeVariant(slice)},
- systemd.Property{"Description", dbus.MakeVariant("docker container " + c.Name)},
- systemd.Property{"PIDs", dbus.MakeVariant([]uint32{uint32(pid)})},
+ systemd.PropSlice(slice),
+ systemd.PropDescription("docker container "+c.Name),
+ newProp("PIDs", []uint32{uint32(pid)}),
)
// Always enable accounting, this gets us the same behaviour as the fs implementation,
// plus the kernel has some problems with joining the memory cgroup at a later time.
properties = append(properties,
- systemd.Property{"MemoryAccounting", dbus.MakeVariant(true)},
- systemd.Property{"CPUAccounting", dbus.MakeVariant(true)},
- systemd.Property{"BlockIOAccounting", dbus.MakeVariant(true)})
+ newProp("MemoryAccounting", true),
+ newProp("CPUAccounting", true),
+ newProp("BlockIOAccounting", true))
if c.Memory != 0 {
properties = append(properties,
- systemd.Property{"MemoryLimit", dbus.MakeVariant(uint64(c.Memory))})
+ newProp("MemoryLimit", uint64(c.Memory)))
}
// TODO: MemoryReservation and MemorySwap not available in systemd
if c.CpuShares != 0 {
properties = append(properties,
- systemd.Property{"CPUShares", dbus.MakeVariant(uint64(c.CpuShares))})
+ newProp("CPUShares", uint64(c.CpuShares)))
}
if _, err := theConn.StartTransientUnit(unitName, "replace", properties...); err != nil {
diff --git a/vendor/src/github.com/docker/libcontainer/devices/devices.go b/vendor/src/github.com/docker/libcontainer/devices/devices.go
index 5bf80e8cd4..8e86d95292 100644
--- a/vendor/src/github.com/docker/libcontainer/devices/devices.go
+++ b/vendor/src/github.com/docker/libcontainer/devices/devices.go
@@ -103,7 +103,7 @@ func getDeviceNodes(path string) ([]*Device, error) {
switch {
case f.IsDir():
switch f.Name() {
- case "pts", "shm", "fd":
+ case "pts", "shm", "fd", "mqueue":
continue
default:
sub, err := getDeviceNodes(filepath.Join(path, f.Name()))
diff --git a/vendor/src/github.com/docker/libcontainer/integration/init_test.go b/vendor/src/github.com/docker/libcontainer/integration/init_test.go
index a0570f3245..9954c0f8e5 100644
--- a/vendor/src/github.com/docker/libcontainer/integration/init_test.go
+++ b/vendor/src/github.com/docker/libcontainer/integration/init_test.go
@@ -6,7 +6,6 @@ import (
"runtime"
"github.com/docker/libcontainer/namespaces"
- "github.com/docker/libcontainer/syncpipe"
)
// init runs the libcontainer initialization code because of the busybox style needs
@@ -27,12 +26,7 @@ func init() {
log.Fatal(err)
}
- syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3)
- if err != nil {
- log.Fatalf("unable to create sync pipe: %s", err)
- }
-
- if err := namespaces.Init(container, rootfs, "", syncPipe, os.Args[3:]); err != nil {
+ if err := namespaces.Init(container, rootfs, "", os.NewFile(3, "pipe"), os.Args[3:]); err != nil {
log.Fatalf("unable to initialize for container: %s", err)
}
os.Exit(1)
diff --git a/vendor/src/github.com/docker/libcontainer/label/label.go b/vendor/src/github.com/docker/libcontainer/label/label.go
index ce60296ea1..04a72aeae0 100644
--- a/vendor/src/github.com/docker/libcontainer/label/label.go
+++ b/vendor/src/github.com/docker/libcontainer/label/label.go
@@ -43,3 +43,15 @@ func ReserveLabel(label string) error {
func UnreserveLabel(label string) error {
return nil
}
+
+// DupSecOpt takes an 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
+}
+
+// DisableSecOpt returns a security opt that can disable labeling
+// support for future container processes
+func DisableSecOpt() []string {
+ return nil
+}
diff --git a/vendor/src/github.com/docker/libcontainer/label/label_selinux.go b/vendor/src/github.com/docker/libcontainer/label/label_selinux.go
index 65b84797b5..0b7d437f84 100644
--- a/vendor/src/github.com/docker/libcontainer/label/label_selinux.go
+++ b/vendor/src/github.com/docker/libcontainer/label/label_selinux.go
@@ -17,7 +17,6 @@ func InitLabels(options []string) (string, string, error) {
if !selinux.SelinuxEnabled() {
return "", "", nil
}
- var err error
processLabel, mountLabel := selinux.GetLxcContexts()
if processLabel != "" {
pcon := selinux.NewContext(processLabel)
@@ -38,7 +37,7 @@ func InitLabels(options []string) (string, string, error) {
processLabel = pcon.Get()
mountLabel = mcon.Get()
}
- return processLabel, mountLabel, err
+ return processLabel, mountLabel, nil
}
// DEPRECATED: The GenLabels function is only to be used during the transition to the official API.
@@ -130,3 +129,15 @@ func UnreserveLabel(label string) error {
selinux.FreeLxcContexts(label)
return nil
}
+
+// DupSecOpt takes an process label and returns security options that
+// can be used to set duplicate labels on future container processes
+func DupSecOpt(src string) []string {
+ return selinux.DupSecOpt(src)
+}
+
+// DisableSecOpt returns a security opt that can disable labeling
+// support for future container processes
+func DisableSecOpt() []string {
+ return selinux.DisableSecOpt()
+}
diff --git a/vendor/src/github.com/docker/libcontainer/label/label_selinux_test.go b/vendor/src/github.com/docker/libcontainer/label/label_selinux_test.go
index c83654f6b5..8629353f24 100644
--- a/vendor/src/github.com/docker/libcontainer/label/label_selinux_test.go
+++ b/vendor/src/github.com/docker/libcontainer/label/label_selinux_test.go
@@ -3,6 +3,7 @@
package label
import (
+ "strings"
"testing"
"github.com/docker/libcontainer/selinux"
@@ -33,7 +34,7 @@ func TestInit(t *testing.T) {
t.Fatal(err)
}
if plabel != "user_u:user_r:user_t:s0:c1,c15" || mlabel != "user_u:object_r:svirt_sandbox_file_t:s0:c1,c15" {
- t.Log("InitLabels User Failed")
+ t.Log("InitLabels User Match Failed")
t.Log(plabel, mlabel)
t.Fatal(err)
}
@@ -46,3 +47,43 @@ func TestInit(t *testing.T) {
}
}
}
+func TestDuplicateLabel(t *testing.T) {
+ secopt := DupSecOpt("system_u:system_r:svirt_lxc_net_t:s0:c1,c2")
+ t.Log(secopt)
+ for _, opt := range secopt {
+ con := strings.SplitN(opt, ":", 3)
+ if len(con) != 3 || con[0] != "label" {
+ t.Errorf("Invalid DupSecOpt return value")
+ continue
+ }
+ if con[1] == "user" {
+ if con[2] != "system_u" {
+ t.Errorf("DupSecOpt Failed user incorrect")
+ }
+ continue
+ }
+ if con[1] == "role" {
+ if con[2] != "system_r" {
+ t.Errorf("DupSecOpt Failed role incorrect")
+ }
+ continue
+ }
+ if con[1] == "type" {
+ if con[2] != "svirt_lxc_net_t" {
+ t.Errorf("DupSecOpt Failed type incorrect")
+ }
+ continue
+ }
+ if con[1] == "level" {
+ if con[2] != "s0:c1,c2" {
+ t.Errorf("DupSecOpt Failed level incorrect")
+ }
+ continue
+ }
+ t.Errorf("DupSecOpt Failed invalid field %q", con[1])
+ }
+ secopt = DisableSecOpt()
+ if secopt[0] != "label:disable" {
+ t.Errorf("DisableSecOpt Failed level incorrect")
+ }
+}
diff --git a/vendor/src/github.com/docker/libcontainer/mount/init.go b/vendor/src/github.com/docker/libcontainer/mount/init.go
index ea2b732737..a2c3d52026 100644
--- a/vendor/src/github.com/docker/libcontainer/mount/init.go
+++ b/vendor/src/github.com/docker/libcontainer/mount/init.go
@@ -97,7 +97,7 @@ func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountCon
return nil
}
-// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
+// mountSystem sets up linux specific system mounts like mqueue, sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, sysReadonly bool, mountConfig *MountConfig) error {
for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, sysReadonly) {
@@ -168,6 +168,7 @@ func newSystemMounts(rootfs, mountLabel string, sysReadonly bool) []mount {
{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
{source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)},
{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1777,size=65536k", mountLabel)},
+ {source: "mqueue", path: filepath.Join(rootfs, "dev", "mqueue"), device: "mqueue", flags: defaultMountFlags},
{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
}
diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/exec.go b/vendor/src/github.com/docker/libcontainer/namespaces/exec.go
index 4440ccd0d5..bd3a4a3f9e 100644
--- a/vendor/src/github.com/docker/libcontainer/namespaces/exec.go
+++ b/vendor/src/github.com/docker/libcontainer/namespaces/exec.go
@@ -3,6 +3,7 @@
package namespaces
import (
+ "encoding/json"
"io"
"os"
"os/exec"
@@ -13,7 +14,6 @@ import (
"github.com/docker/libcontainer/cgroups/fs"
"github.com/docker/libcontainer/cgroups/systemd"
"github.com/docker/libcontainer/network"
- "github.com/docker/libcontainer/syncpipe"
"github.com/docker/libcontainer/system"
)
@@ -22,19 +22,17 @@ import (
// Exec performs setup outside of a namespace so that a container can be
// executed. Exec is a high level function for working with container namespaces.
func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
- var (
- err error
- )
+ var err error
// create a pipe so that we can syncronize with the namespaced process and
- // pass the veth name to the child
- syncPipe, err := syncpipe.NewSyncPipe()
+ // pass the state and configuration to the child process
+ parent, child, err := newInitPipe()
if err != nil {
return -1, err
}
- defer syncPipe.Close()
+ defer parent.Close()
- command := createCommand(container, console, dataPath, os.Args[0], syncPipe.Child(), args)
+ command := createCommand(container, console, dataPath, os.Args[0], child, args)
// Note: these are only used in non-tty mode
// if there is a tty for the container it will be opened within the namespace and the
// fds will be duped to stdin, stdiout, and stderr
@@ -43,39 +41,47 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
command.Stderr = stderr
if err := command.Start(); err != nil {
+ child.Close()
return -1, err
}
+ child.Close()
- // Now we passed the pipe to the child, close our side
- syncPipe.CloseChild()
+ terminate := func(terr error) (int, error) {
+ // TODO: log the errors for kill and wait
+ command.Process.Kill()
+ command.Wait()
+ return -1, terr
+ }
started, err := system.GetProcessStartTime(command.Process.Pid)
if err != nil {
- return -1, err
+ return terminate(err)
}
// Do this before syncing with child so that no children
// can escape the cgroup
cgroupRef, err := SetupCgroups(container, command.Process.Pid)
if err != nil {
- command.Process.Kill()
- command.Wait()
- return -1, err
+ return terminate(err)
}
defer cgroupRef.Cleanup()
cgroupPaths, err := cgroupRef.Paths()
if err != nil {
- command.Process.Kill()
- command.Wait()
- return -1, err
+ return terminate(err)
}
var networkState network.NetworkState
- if err := InitializeNetworking(container, command.Process.Pid, syncPipe, &networkState); err != nil {
- command.Process.Kill()
- command.Wait()
- return -1, err
+ if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil {
+ return terminate(err)
+ }
+ // send the state to the container's init process then shutdown writes for the parent
+ if err := json.NewEncoder(parent).Encode(networkState); err != nil {
+ return terminate(err)
+ }
+ // shutdown writes for the parent side of the pipe
+ if err := syscall.Shutdown(int(parent.Fd()), syscall.SHUT_WR); err != nil {
+ return terminate(err)
}
state := &libcontainer.State{
@@ -86,17 +92,18 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
}
if err := libcontainer.SaveState(dataPath, state); err != nil {
- command.Process.Kill()
- command.Wait()
- return -1, err
+ return terminate(err)
}
defer libcontainer.DeleteState(dataPath)
- // Sync with child
- if err := syncPipe.ReadFromChild(); err != nil {
- command.Process.Kill()
- command.Wait()
- return -1, err
+ // wait for the child process to fully complete and receive an error message
+ // if one was encoutered
+ var ierr *initError
+ if err := json.NewDecoder(parent).Decode(&ierr); err != nil && err != io.EOF {
+ return terminate(err)
+ }
+ if ierr != nil {
+ return terminate(ierr)
}
if startCallback != nil {
@@ -108,7 +115,6 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
return -1, err
}
}
-
return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
}
@@ -129,16 +135,6 @@ func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, ini
"data_path=" + dataPath,
}
- /*
- TODO: move user and wd into env
- if user != "" {
- env = append(env, "user="+user)
- }
- if workingDir != "" {
- env = append(env, "wd="+workingDir)
- }
- */
-
command := exec.Command(init, append([]string{"init", "--"}, args...)...)
// make sure the process is executed inside the context of the rootfs
command.Dir = container.RootFs
@@ -173,7 +169,7 @@ func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgro
// InitializeNetworking creates the container's network stack outside of the namespace and moves
// interfaces into the container's net namespaces if necessary
-func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *syncpipe.SyncPipe, networkState *network.NetworkState) error {
+func InitializeNetworking(container *libcontainer.Config, nspid int, networkState *network.NetworkState) error {
for _, config := range container.Networks {
strategy, err := network.GetStrategy(config.Type)
if err != nil {
@@ -183,18 +179,5 @@ func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *syncp
return err
}
}
- return pipe.SendToChild(networkState)
-}
-
-// GetNamespaceFlags parses the container's Namespaces options to set the correct
-// flags on clone, unshare, and setns
-func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
- for key, enabled := range namespaces {
- if enabled {
- if ns := GetNamespace(key); ns != nil {
- flag |= ns.Value
- }
- }
- }
- return flag
+ return nil
}
diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/execin.go b/vendor/src/github.com/docker/libcontainer/namespaces/execin.go
index 53e676ac7e..7dea918735 100644
--- a/vendor/src/github.com/docker/libcontainer/namespaces/execin.go
+++ b/vendor/src/github.com/docker/libcontainer/namespaces/execin.go
@@ -3,6 +3,7 @@
package namespaces
import (
+ "encoding/json"
"fmt"
"io"
"os"
@@ -15,7 +16,6 @@ import (
"github.com/docker/libcontainer/apparmor"
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/label"
- "github.com/docker/libcontainer/syncpipe"
"github.com/docker/libcontainer/system"
)
@@ -41,11 +41,11 @@ func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs
}
}
- pipe, err := syncpipe.NewSyncPipe()
+ parent, child, err := newInitPipe()
if err != nil {
return -1, err
}
- defer pipe.Close()
+ defer parent.Close()
// Note: these are only used in non-tty mode
// if there is a tty for the container it will be opened within the namespace and the
@@ -53,23 +53,28 @@ func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
-
- cmd.ExtraFiles = []*os.File{pipe.Child()}
+ cmd.ExtraFiles = []*os.File{child}
if err := cmd.Start(); err != nil {
+ child.Close()
return -1, err
}
- pipe.CloseChild()
+ child.Close()
+
+ terminate := func(terr error) (int, error) {
+ // TODO: log the errors for kill and wait
+ cmd.Process.Kill()
+ cmd.Wait()
+ return -1, terr
+ }
// Enter cgroups.
if err := EnterCgroups(state, cmd.Process.Pid); err != nil {
- return -1, err
+ return terminate(err)
}
- if err := pipe.SendToChild(container); err != nil {
- cmd.Process.Kill()
- cmd.Wait()
- return -1, err
+ if err := json.NewEncoder(parent).Encode(container); err != nil {
+ return terminate(err)
}
if startCallback != nil {
@@ -81,7 +86,6 @@ func ExecIn(container *libcontainer.Config, state *libcontainer.State, userArgs
return -1, err
}
}
-
return cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
}
diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/init.go b/vendor/src/github.com/docker/libcontainer/namespaces/init.go
index 879ac21e0d..482ba0f399 100644
--- a/vendor/src/github.com/docker/libcontainer/namespaces/init.go
+++ b/vendor/src/github.com/docker/libcontainer/namespaces/init.go
@@ -3,7 +3,9 @@
package namespaces
import (
+ "encoding/json"
"fmt"
+ "io/ioutil"
"os"
"strings"
"syscall"
@@ -18,7 +20,6 @@ import (
"github.com/docker/libcontainer/network"
"github.com/docker/libcontainer/security/capabilities"
"github.com/docker/libcontainer/security/restrict"
- "github.com/docker/libcontainer/syncpipe"
"github.com/docker/libcontainer/system"
"github.com/docker/libcontainer/user"
"github.com/docker/libcontainer/utils"
@@ -30,11 +31,22 @@ import (
// and other options required for the new container.
// The caller of Init function has to ensure that the go runtime is locked to an OS thread
// (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended.
-func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *syncpipe.SyncPipe, args []string) (err error) {
+func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) {
defer func() {
+ // if we have an error during the initialization of the container's init then send it back to the
+ // parent process in the form of an initError.
if err != nil {
- syncPipe.ReportChildError(err)
+ // ensure that any data sent from the parent is consumed so it doesn't
+ // receive ECONNRESET when the child writes to the pipe.
+ ioutil.ReadAll(pipe)
+ if err := json.NewEncoder(pipe).Encode(initError{
+ Message: err.Error(),
+ }); err != nil {
+ panic(err)
+ }
}
+ // ensure that this pipe is always closed
+ pipe.Close()
}()
rootfs, err := utils.ResolveRootfs(uncleanRootfs)
@@ -50,7 +62,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
// We always read this as it is a way to sync with the parent as well
var networkState *network.NetworkState
- if err := syncPipe.ReadFromParent(&networkState); err != nil {
+ if err := json.NewDecoder(pipe).Decode(&networkState); err != nil {
return err
}
@@ -164,11 +176,11 @@ func SetupUser(u string) error {
return fmt.Errorf("setgroups %s", err)
}
- if err := syscall.Setgid(gid); err != nil {
+ if err := system.Setgid(gid); err != nil {
return fmt.Errorf("setgid %s", err)
}
- if err := syscall.Setuid(uid); err != nil {
+ if err := system.Setuid(uid); err != nil {
return fmt.Errorf("setuid %s", err)
}
diff --git a/vendor/src/github.com/docker/libcontainer/namespaces/utils.go b/vendor/src/github.com/docker/libcontainer/namespaces/utils.go
new file mode 100644
index 0000000000..bf60cd8f0e
--- /dev/null
+++ b/vendor/src/github.com/docker/libcontainer/namespaces/utils.go
@@ -0,0 +1,38 @@
+// +build linux
+
+package namespaces
+
+import (
+ "os"
+ "syscall"
+)
+
+type initError struct {
+ Message string `json:"message,omitempty"`
+}
+
+func (i initError) Error() string {
+ return i.Message
+}
+
+// New returns a newly initialized Pipe for communication between processes
+func newInitPipe() (parent *os.File, child *os.File, err error) {
+ fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
+ if err != nil {
+ return nil, nil, err
+ }
+ return os.NewFile(uintptr(fds[1]), "parent"), os.NewFile(uintptr(fds[0]), "child"), nil
+}
+
+// GetNamespaceFlags parses the container's Namespaces options to set the correct
+// flags on clone, unshare, and setns
+func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
+ for key, enabled := range namespaces {
+ if enabled {
+ if ns := GetNamespace(key); ns != nil {
+ flag |= ns.Value
+ }
+ }
+ }
+ return flag
+}
diff --git a/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go b/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go
index c858b1129e..93ebade5c0 100644
--- a/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go
+++ b/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go
@@ -7,6 +7,7 @@ import (
"math/rand"
"net"
"os"
+ "path/filepath"
"sync/atomic"
"syscall"
"unsafe"
@@ -1204,6 +1205,28 @@ func SetMacAddress(name, addr string) error {
return nil
}
+func SetHairpinMode(iface *net.Interface, enabled bool) error {
+ sysPath := filepath.Join("/sys/class/net", iface.Name, "brport/hairpin_mode")
+
+ sysFile, err := os.OpenFile(sysPath, os.O_WRONLY, 0)
+ if err != nil {
+ return err
+ }
+ defer sysFile.Close()
+
+ var writeVal []byte
+ if enabled {
+ writeVal = []byte("1")
+ } else {
+ writeVal = []byte("0")
+ }
+ if _, err := sysFile.Write(writeVal); err != nil {
+ return err
+ }
+
+ return nil
+}
+
func ChangeName(iface *net.Interface, newName string) error {
if len(newName) >= IFNAMSIZ {
return fmt.Errorf("Interface name %s too long", newName)
@@ -1224,5 +1247,6 @@ func ChangeName(iface *net.Interface, newName string) error {
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&data[0]))); errno != 0 {
return errno
}
+
return nil
}
diff --git a/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go b/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go
index 0320c47221..be896a14a4 100644
--- a/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go
+++ b/vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go
@@ -116,7 +116,7 @@ func TestNetworkSetMacAddress(t *testing.T) {
ifcBeforeSet := readLink(t, tl.name)
if err := NetworkSetMacAddress(ifcBeforeSet, macaddr); err != nil {
- t.Fatalf("Could not set %s MAC address on %#v interface: err", macaddr, tl, err)
+ t.Fatalf("Could not set %s MAC address on %#v interface: %s", macaddr, tl, err)
}
ifcAfterSet := readLink(t, tl.name)
@@ -140,7 +140,7 @@ func TestNetworkSetMTU(t *testing.T) {
ifcBeforeSet := readLink(t, tl.name)
if err := NetworkSetMTU(ifcBeforeSet, mtu); err != nil {
- t.Fatalf("Could not set %d MTU on %#v interface: err", mtu, tl, err)
+ t.Fatalf("Could not set %d MTU on %#v interface: %s", mtu, tl, err)
}
ifcAfterSet := readLink(t, tl.name)
diff --git a/vendor/src/github.com/docker/libcontainer/network/network.go b/vendor/src/github.com/docker/libcontainer/network/network.go
index 2c3499b6d6..ba8f6f74e7 100644
--- a/vendor/src/github.com/docker/libcontainer/network/network.go
+++ b/vendor/src/github.com/docker/libcontainer/network/network.go
@@ -95,3 +95,11 @@ func SetMtu(name string, mtu int) error {
}
return netlink.NetworkSetMTU(iface, mtu)
}
+
+func SetHairpinMode(name string, enabled bool) error {
+ iface, err := net.InterfaceByName(name)
+ if err != nil {
+ return err
+ }
+ return netlink.SetHairpinMode(iface, enabled)
+}
diff --git a/vendor/src/github.com/docker/libcontainer/network/veth.go b/vendor/src/github.com/docker/libcontainer/network/veth.go
index 3d7dc8729e..240da57986 100644
--- a/vendor/src/github.com/docker/libcontainer/network/veth.go
+++ b/vendor/src/github.com/docker/libcontainer/network/veth.go
@@ -39,6 +39,9 @@ func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
if err := SetMtu(name1, n.Mtu); err != nil {
return err
}
+ if err := SetHairpinMode(name1, true); err != nil {
+ return err
+ }
if err := InterfaceUp(name1); err != nil {
return err
}
diff --git a/vendor/src/github.com/docker/libcontainer/nsinit/init.go b/vendor/src/github.com/docker/libcontainer/nsinit/init.go
index c091ee1099..6df9b1d894 100644
--- a/vendor/src/github.com/docker/libcontainer/nsinit/init.go
+++ b/vendor/src/github.com/docker/libcontainer/nsinit/init.go
@@ -8,7 +8,6 @@ import (
"github.com/codegangsta/cli"
"github.com/docker/libcontainer/namespaces"
- "github.com/docker/libcontainer/syncpipe"
)
var (
@@ -41,12 +40,8 @@ func initAction(context *cli.Context) {
log.Fatal(err)
}
- syncPipe, err := syncpipe.NewSyncPipeFromFd(0, uintptr(pipeFd))
- if err != nil {
- log.Fatalf("unable to create sync pipe: %s", err)
- }
-
- if err := namespaces.Init(container, rootfs, console, syncPipe, []string(context.Args())); err != nil {
+ pipe := os.NewFile(uintptr(pipeFd), "pipe")
+ if err := namespaces.Init(container, rootfs, console, pipe, []string(context.Args())); err != nil {
log.Fatalf("unable to initialize for container: %s", err)
}
}
diff --git a/vendor/src/github.com/docker/libcontainer/nsinit/utils.go b/vendor/src/github.com/docker/libcontainer/nsinit/utils.go
index 7f5155942c..6a8aafbf17 100644
--- a/vendor/src/github.com/docker/libcontainer/nsinit/utils.go
+++ b/vendor/src/github.com/docker/libcontainer/nsinit/utils.go
@@ -8,7 +8,6 @@ import (
"github.com/codegangsta/cli"
"github.com/docker/libcontainer"
- "github.com/docker/libcontainer/syncpipe"
)
// rFunc is a function registration for calling after an execin
@@ -59,16 +58,13 @@ func findUserArgs() []string {
// loadConfigFromFd loads a container's config from the sync pipe that is provided by
// fd 3 when running a process
func loadConfigFromFd() (*libcontainer.Config, error) {
- syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3)
- if err != nil {
- return nil, err
- }
+ pipe := os.NewFile(3, "pipe")
+ defer pipe.Close()
var config *libcontainer.Config
- if err := syncPipe.ReadFromParent(&config); err != nil {
+ if err := json.NewDecoder(pipe).Decode(&config); err != nil {
return nil, err
}
-
return config, nil
}
diff --git a/vendor/src/github.com/docker/libcontainer/selinux/selinux.go b/vendor/src/github.com/docker/libcontainer/selinux/selinux.go
index e0c90ee551..e5bd820980 100644
--- a/vendor/src/github.com/docker/libcontainer/selinux/selinux.go
+++ b/vendor/src/github.com/docker/libcontainer/selinux/selinux.go
@@ -434,3 +434,28 @@ func Chcon(fpath string, scon string, recurse bool) error {
return Setfilecon(fpath, scon)
}
+
+// DupSecOpt takes an SELinux process label and returns security options that
+// can will set the SELinux Type and Level for future container processes
+func DupSecOpt(src string) []string {
+ if src == "" {
+ return nil
+ }
+ con := NewContext(src)
+ if con["user"] == "" ||
+ con["role"] == "" ||
+ con["type"] == "" ||
+ con["level"] == "" {
+ return nil
+ }
+ return []string{"label:user:" + con["user"],
+ "label:role:" + con["role"],
+ "label:type:" + con["type"],
+ "label:level:" + con["level"]}
+}
+
+// DisableSecOpt returns a security opt that can be used to disabling SELinux
+// labeling support for future container processes
+func DisableSecOpt() []string {
+ return []string{"label:disable"}
+}
diff --git a/vendor/src/github.com/docker/libcontainer/selinux/selinux_test.go b/vendor/src/github.com/docker/libcontainer/selinux/selinux_test.go
index 34c3497441..228ad8361c 100644
--- a/vendor/src/github.com/docker/libcontainer/selinux/selinux_test.go
+++ b/vendor/src/github.com/docker/libcontainer/selinux/selinux_test.go
@@ -42,7 +42,7 @@ func TestSELinux(t *testing.T) {
t.Log("getenforce ", selinux.SelinuxGetEnforce())
t.Log("getenforcemode ", selinux.SelinuxGetEnforceMode())
pid := os.Getpid()
- t.Log("PID:%d MCS:%s\n", pid, selinux.IntToMcs(pid, 1023))
+ t.Logf("PID:%d MCS:%s\n", pid, selinux.IntToMcs(pid, 1023))
err = selinux.Setfscreatecon("unconfined_u:unconfined_r:unconfined_t:s0")
if err == nil {
t.Log(selinux.Getfscreatecon())
diff --git a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe.go b/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe.go
deleted file mode 100644
index f73c354dbf..0000000000
--- a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package syncpipe
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "syscall"
-)
-
-// SyncPipe allows communication to and from the child processes
-// to it's parent and allows the two independent processes to
-// syncronize their state.
-type SyncPipe struct {
- parent, child *os.File
-}
-
-func NewSyncPipeFromFd(parentFd, childFd uintptr) (*SyncPipe, error) {
- s := &SyncPipe{}
-
- if parentFd > 0 {
- s.parent = os.NewFile(parentFd, "parentPipe")
- } else if childFd > 0 {
- s.child = os.NewFile(childFd, "childPipe")
- } else {
- return nil, fmt.Errorf("no valid sync pipe fd specified")
- }
-
- return s, nil
-}
-
-func (s *SyncPipe) Child() *os.File {
- return s.child
-}
-
-func (s *SyncPipe) Parent() *os.File {
- return s.parent
-}
-
-func (s *SyncPipe) SendToChild(v interface{}) error {
- data, err := json.Marshal(v)
- if err != nil {
- return err
- }
-
- s.parent.Write(data)
-
- return syscall.Shutdown(int(s.parent.Fd()), syscall.SHUT_WR)
-}
-
-func (s *SyncPipe) ReadFromChild() error {
- data, err := ioutil.ReadAll(s.parent)
- if err != nil {
- return err
- }
-
- if len(data) > 0 {
- return fmt.Errorf("%s", data)
- }
-
- return nil
-}
-
-func (s *SyncPipe) ReadFromParent(v interface{}) error {
- data, err := ioutil.ReadAll(s.child)
- if err != nil {
- return fmt.Errorf("error reading from sync pipe %s", err)
- }
-
- if len(data) > 0 {
- if err := json.Unmarshal(data, v); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (s *SyncPipe) ReportChildError(err error) {
- // ensure that any data sent from the parent is consumed so it doesn't
- // receive ECONNRESET when the child writes to the pipe.
- ioutil.ReadAll(s.child)
-
- s.child.Write([]byte(err.Error()))
- s.CloseChild()
-}
-
-func (s *SyncPipe) Close() error {
- if s.parent != nil {
- s.parent.Close()
- }
-
- if s.child != nil {
- s.child.Close()
- }
-
- return nil
-}
-
-func (s *SyncPipe) CloseChild() {
- if s.child != nil {
- s.child.Close()
- s.child = nil
- }
-}
diff --git a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_linux.go b/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_linux.go
deleted file mode 100644
index bea4b52f9e..0000000000
--- a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_linux.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package syncpipe
-
-import (
- "os"
- "syscall"
-)
-
-func NewSyncPipe() (s *SyncPipe, err error) {
- s = &SyncPipe{}
-
- fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
- if err != nil {
- return nil, err
- }
-
- s.child = os.NewFile(uintptr(fds[0]), "child syncpipe")
- s.parent = os.NewFile(uintptr(fds[1]), "parent syncpipe")
-
- return s, nil
-}
diff --git a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_test.go b/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_test.go
deleted file mode 100644
index 906e6ed24d..0000000000
--- a/vendor/src/github.com/docker/libcontainer/syncpipe/sync_pipe_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package syncpipe
-
-import (
- "fmt"
- "syscall"
- "testing"
-)
-
-type testStruct struct {
- Name string
-}
-
-func TestSendErrorFromChild(t *testing.T) {
- pipe, err := NewSyncPipe()
- if err != nil {
- t.Fatal(err)
- }
- defer func() {
- if err := pipe.Close(); err != nil {
- t.Fatal(err)
- }
- }()
-
- childfd, err := syscall.Dup(int(pipe.Child().Fd()))
- if err != nil {
- t.Fatal(err)
- }
- childPipe, _ := NewSyncPipeFromFd(0, uintptr(childfd))
-
- pipe.CloseChild()
- pipe.SendToChild(nil)
-
- expected := "something bad happened"
- childPipe.ReportChildError(fmt.Errorf(expected))
-
- childError := pipe.ReadFromChild()
- if childError == nil {
- t.Fatal("expected an error to be returned but did not receive anything")
- }
-
- if childError.Error() != expected {
- t.Fatalf("expected %q but received error message %q", expected, childError.Error())
- }
-}
-
-func TestSendPayloadToChild(t *testing.T) {
- pipe, err := NewSyncPipe()
- if err != nil {
- t.Fatal(err)
- }
-
- defer func() {
- if err := pipe.Close(); err != nil {
- t.Fatal(err)
- }
- }()
-
- expected := "libcontainer"
-
- if err := pipe.SendToChild(testStruct{Name: expected}); err != nil {
- t.Fatal(err)
- }
-
- var s *testStruct
- if err := pipe.ReadFromParent(&s); err != nil {
- t.Fatal(err)
- }
-
- if s.Name != expected {
- t.Fatalf("expected name %q but received %q", expected, s.Name)
- }
-}
diff --git a/vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go b/vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go
index 0a346c3b9c..516c17e921 100644
--- a/vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go
+++ b/vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go
@@ -1,4 +1,5 @@
// +build linux,amd64
+
package system
import (