Browse Source

Update libcontainer to 5589d4d879f1d7e31967a927d3e

Signed-off-by: Michael Crosby <michael@docker.com>
Michael Crosby 11 years ago
parent
commit
6215422286
100 changed files with 9648 additions and 346 deletions
  1. 1 1
      hack/vendor.sh
  2. 5 3
      vendor/src/github.com/docker/libcontainer/.travis.yml
  3. 5 3
      vendor/src/github.com/docker/libcontainer/Dockerfile
  4. 1 0
      vendor/src/github.com/docker/libcontainer/MAINTAINERS
  5. 16 2
      vendor/src/github.com/docker/libcontainer/Makefile
  6. 12 12
      vendor/src/github.com/docker/libcontainer/cgroups/cgutil/cgutil.go
  7. 6 40
      vendor/src/github.com/docker/libcontainer/namespaces/execin.go
  8. 235 0
      vendor/src/github.com/docker/libcontainer/namespaces/nsenter.c
  9. 0 206
      vendor/src/github.com/docker/libcontainer/namespaces/nsenter.go
  10. 47 14
      vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go
  11. 26 1
      vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go
  12. 4 0
      vendor/src/github.com/docker/libcontainer/netlink/netlink_unsupported.go
  13. 4 1
      vendor/src/github.com/docker/libcontainer/nsinit/cli.go
  14. 1 54
      vendor/src/github.com/docker/libcontainer/nsinit/exec.go
  15. 5 9
      vendor/src/github.com/docker/libcontainer/nsinit/nsenter.go
  16. 48 0
      vendor/src/github.com/docker/libcontainer/update-vendor.sh
  17. 6 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml
  18. 21 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE
  19. 257 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md
  20. 248 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go
  21. 399 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go
  22. 13 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
  23. 19 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go
  24. 88 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go
  25. 141 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go
  26. 48 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go
  27. 280 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go
  28. 68 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go
  29. 280 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go
  30. 194 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go
  31. 213 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go
  32. 19 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go
  33. 8 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml
  34. 191 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE
  35. 44 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md
  36. 56 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go
  37. 84 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go
  38. 38 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go
  39. 88 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go
  40. 104 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go
  41. 41 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go
  42. 396 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go
  43. 332 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go
  44. 220 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go
  45. 33 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go
  46. 39 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go
  47. 251 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go
  48. 32 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go
  49. 66 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go
  50. 91 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go
  51. 44 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go
  52. 19 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
  53. 11 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
  54. 5 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
  55. 26 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
  56. 50 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go
  57. 5 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service
  58. 5 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service
  59. 5 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service
  60. 5 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service
  61. 168 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go
  62. 81 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go
  63. 30 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go
  64. 3 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test
  65. 25 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/LICENSE
  66. 38 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/README.markdown
  67. 30 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/eavesdrop.go
  68. 21 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/introspect.go
  69. 27 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/list-names.go
  70. 17 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/notification.go
  71. 68 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/prop.go
  72. 45 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/server.go
  73. 24 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/signal.go
  74. 253 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth.go
  75. 26 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_external.go
  76. 102 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_sha1.go
  77. 147 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/call.go
  78. 601 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn.go
  79. 21 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_darwin.go
  80. 27 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_other.go
  81. 199 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_test.go
  82. 258 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/dbus.go
  83. 228 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/decoder.go
  84. 63 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/doc.go
  85. 179 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/encoder.go
  86. 50 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/examples_test.go
  87. 302 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/export.go
  88. 28 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir.go
  89. 15 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_dynamic.go
  90. 45 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_static.go
  91. 27 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/call.go
  92. 80 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspect.go
  93. 74 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspectable.go
  94. 346 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/message.go
  95. 264 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/prop/prop.go
  96. 369 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/proto_test.go
  97. 257 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig.go
  98. 70 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig_test.go
  99. 6 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_darwin.go
  100. 35 0
      vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_generic.go

+ 1 - 1
hack/vendor.sh

@@ -63,4 +63,4 @@ mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
 
 clone git github.com/godbus/dbus v1
 clone git github.com/coreos/go-systemd v2
-clone git github.com/docker/libcontainer 68ea1234a0b046803aacb2562df0da12eec2b2f9
+clone git github.com/docker/libcontainer 5589d4d879f1d7e31967a927d3e8b98144fbe06b

+ 5 - 3
vendor/src/github.com/docker/libcontainer/.travis.yml

@@ -13,13 +13,15 @@ env:
     - _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 ./...
+    - 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";
@@ -30,5 +32,5 @@ install:
 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 go build -v ./...; fi
-    - if [ -z "$TRAVIS_GLOBAL_WTF" -a "$GOARCH" != 'arm' ]; then go test -test.short -v ./...; 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

+ 5 - 3
vendor/src/github.com/docker/libcontainer/Dockerfile

@@ -1,6 +1,6 @@
 FROM crosbymichael/golang
 
-RUN apt-get update && apt-get install -y gcc
+RUN apt-get update && apt-get install -y gcc make
 RUN go get code.google.com/p/go.tools/cmd/cover
 
 # setup a playground for us to spawn containers in
@@ -14,8 +14,10 @@ COPY . /go/src/github.com/docker/libcontainer
 WORKDIR /go/src/github.com/docker/libcontainer
 RUN cp sample_configs/minimal.json /busybox/container.json
 
+ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
+
 RUN go get -d -v ./...
-RUN go install -v ./...
+RUN make direct-install
 
 ENTRYPOINT ["/dind"]
-CMD ["go", "test", "-cover", "./..."]
+CMD ["make", "direct-test"]

+ 1 - 0
vendor/src/github.com/docker/libcontainer/MAINTAINERS

@@ -2,3 +2,4 @@ Michael Crosby <michael@docker.com> (@crosbymichael)
 Rohit Jnagal <jnagal@google.com> (@rjnagal)
 Victor Marmol <vmarmol@google.com> (@vmarmol)
 .travis.yml: Tianon Gravi <admwiggin@gmail.com> (@tianon)
+update-vendor.sh: Tianon Gravi <admwiggin@gmail.com> (@tianon)

+ 16 - 2
vendor/src/github.com/docker/libcontainer/Makefile

@@ -4,7 +4,21 @@ all:
 
 test:
 	# we need NET_ADMIN for the netlink tests and SYS_ADMIN for mounting
-	docker run --rm --cap-add NET_ADMIN --cap-add SYS_ADMIN docker/libcontainer
+	docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN docker/libcontainer
 
 sh:
-	docker run --rm -ti -w /busybox --rm --cap-add NET_ADMIN --cap-add SYS_ADMIN docker/libcontainer nsinit exec sh
+	docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN -w /busybox docker/libcontainer nsinit exec sh
+
+GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u)
+
+direct-test:
+	go test -cover -v $(GO_PACKAGES)
+
+direct-test-short:
+	go test -cover -test.short -v $(GO_PACKAGES)
+
+direct-build:
+	go build -v $(GO_PACKAGES)
+
+direct-install:
+	go install -v $(GO_PACKAGES)

+ 12 - 12
vendor/src/github.com/docker/libcontainer/cgroups/cgutil/cgutil.go

@@ -18,8 +18,8 @@ var createCommand = cli.Command{
 	Name:  "create",
 	Usage: "Create a cgroup container using the supplied configuration and initial process.",
 	Flags: []cli.Flag{
-		cli.StringFlag{"config, c", "cgroup.json", "path to container configuration (cgroups.Cgroup object)"},
-		cli.IntFlag{"pid, p", 0, "pid of the initial process in the container"},
+		cli.StringFlag{Name: "config, c", Value: "cgroup.json", Usage: "path to container configuration (cgroups.Cgroup object)"},
+		cli.IntFlag{Name: "pid, p", Value: 0, Usage: "pid of the initial process in the container"},
 	},
 	Action: createAction,
 }
@@ -28,8 +28,8 @@ var destroyCommand = cli.Command{
 	Name:  "destroy",
 	Usage: "Destroy an existing cgroup container.",
 	Flags: []cli.Flag{
-		cli.StringFlag{"name, n", "", "container name"},
-		cli.StringFlag{"parent, p", "", "container parent"},
+		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
+		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
 	},
 	Action: destroyAction,
 }
@@ -38,8 +38,8 @@ var statsCommand = cli.Command{
 	Name:  "stats",
 	Usage: "Get stats for cgroup",
 	Flags: []cli.Flag{
-		cli.StringFlag{"name, n", "", "container name"},
-		cli.StringFlag{"parent, p", "", "container parent"},
+		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
+		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
 	},
 	Action: statsAction,
 }
@@ -48,8 +48,8 @@ var pauseCommand = cli.Command{
 	Name:  "pause",
 	Usage: "Pause cgroup",
 	Flags: []cli.Flag{
-		cli.StringFlag{"name, n", "", "container name"},
-		cli.StringFlag{"parent, p", "", "container parent"},
+		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
+		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
 	},
 	Action: pauseAction,
 }
@@ -58,8 +58,8 @@ var resumeCommand = cli.Command{
 	Name:  "resume",
 	Usage: "Resume a paused cgroup",
 	Flags: []cli.Flag{
-		cli.StringFlag{"name, n", "", "container name"},
-		cli.StringFlag{"parent, p", "", "container parent"},
+		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
+		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
 	},
 	Action: resumeAction,
 }
@@ -68,8 +68,8 @@ var psCommand = cli.Command{
 	Name:  "ps",
 	Usage: "Get list of pids for a cgroup",
 	Flags: []cli.Flag{
-		cli.StringFlag{"name, n", "", "container name"},
-		cli.StringFlag{"parent, p", "", "container parent"},
+		cli.StringFlag{Name: "name, n", Value: "", Usage: "container name"},
+		cli.StringFlag{Name: "parent, p", Value: "", Usage: "container parent"},
 	},
 	Action: psAction,
 }

+ 6 - 40
vendor/src/github.com/docker/libcontainer/namespaces/execin.go

@@ -4,52 +4,18 @@ package namespaces
 
 import (
 	"encoding/json"
+	"os"
+	"strconv"
+
 	"github.com/docker/libcontainer"
 	"github.com/docker/libcontainer/label"
 	"github.com/docker/libcontainer/system"
-	"io"
-	"os"
-	"os/exec"
-	"strconv"
-	"syscall"
 )
 
-// Runs the command under 'args' inside an existing container referred to by 'container'.
-// Returns the exitcode of the command upon success and appropriate error on failure.
-func RunIn(container *libcontainer.Config, state *libcontainer.State, args []string, nsinitPath string, stdin io.Reader, stdout, stderr io.Writer, console string, startCallback func(*exec.Cmd)) (int, error) {
-	initArgs, err := getNsEnterCommand(strconv.Itoa(state.InitPid), container, console, args)
-	if err != nil {
-		return -1, err
-	}
-
-	cmd := exec.Command(nsinitPath, initArgs...)
-	// 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
-	cmd.Stdin = stdin
-	cmd.Stdout = stdout
-	cmd.Stderr = stderr
-
-	if err := cmd.Start(); err != nil {
-		return -1, err
-	}
-	if startCallback != nil {
-		startCallback(cmd)
-	}
-
-	if err := cmd.Wait(); err != nil {
-		if _, ok := err.(*exec.ExitError); !ok {
-			return -1, err
-		}
-	}
-
-	return cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
-}
-
 // ExecIn uses an existing pid and joins the pid's namespaces with the new command.
 func ExecIn(container *libcontainer.Config, state *libcontainer.State, args []string) error {
 	// Enter the namespace and then finish setup
-	args, err := getNsEnterCommand(strconv.Itoa(state.InitPid), container, "", args)
+	args, err := GetNsEnterCommand(strconv.Itoa(state.InitPid), container, "", args)
 	if err != nil {
 		return err
 	}
@@ -73,14 +39,13 @@ func getContainerJson(container *libcontainer.Config) (string, error) {
 	return string(containerJson), nil
 }
 
-func getNsEnterCommand(initPid string, container *libcontainer.Config, console string, args []string) ([]string, error) {
+func GetNsEnterCommand(initPid string, container *libcontainer.Config, console string, args []string) ([]string, error) {
 	containerJson, err := getContainerJson(container)
 	if err != nil {
 		return nil, err
 	}
 
 	out := []string{
-		"nsenter",
 		"--nspid", initPid,
 		"--containerjson", containerJson,
 	}
@@ -88,6 +53,7 @@ func getNsEnterCommand(initPid string, container *libcontainer.Config, console s
 	if console != "" {
 		out = append(out, "--console", console)
 	}
+	out = append(out, "nsenter")
 	out = append(out, "--")
 	out = append(out, args...)
 

+ 235 - 0
vendor/src/github.com/docker/libcontainer/namespaces/nsenter.c

@@ -0,0 +1,235 @@
+// +build cgo
+//
+// formated with indent -linux nsenter.c
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <linux/sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <getopt.h>
+
+static const kBufSize = 256;
+static const char *kNsEnter = "nsenter";
+
+void get_args(int *argc, char ***argv)
+{
+	// Read argv
+	int fd = open("/proc/self/cmdline", O_RDONLY);
+
+	// Read the whole commandline.
+	ssize_t contents_size = 0;
+	ssize_t contents_offset = 0;
+	char *contents = NULL;
+	ssize_t bytes_read = 0;
+	do {
+		contents_size += kBufSize;
+		contents = (char *)realloc(contents, contents_size);
+		bytes_read =
+		    read(fd, contents + contents_offset,
+			 contents_size - contents_offset);
+		contents_offset += bytes_read;
+	}
+	while (bytes_read > 0);
+	close(fd);
+
+	// Parse the commandline into an argv. /proc/self/cmdline has \0 delimited args.
+	ssize_t i;
+	*argc = 0;
+	for (i = 0; i < contents_offset; i++) {
+		if (contents[i] == '\0') {
+			(*argc)++;
+		}
+	}
+	*argv = (char **)malloc(sizeof(char *) * ((*argc) + 1));
+	int idx;
+	for (idx = 0; idx < (*argc); idx++) {
+		(*argv)[idx] = contents;
+		contents += strlen(contents) + 1;
+	}
+	(*argv)[*argc] = NULL;
+}
+
+// Use raw setns syscall for versions of glibc that don't include it (namely glibc-2.12)
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 14
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+#ifdef SYS_setns
+int setns(int fd, int nstype)
+{
+	return syscall(SYS_setns, fd, nstype);
+}
+#endif
+#endif
+
+void print_usage()
+{
+	fprintf(stderr,
+		"<binary> nsenter --nspid <pid> --containerjson <container_json> -- cmd1 arg1 arg2...\n");
+}
+
+void nsenter()
+{
+	int argc, c;
+	char **argv;
+	get_args(&argc, &argv);
+
+	// Ignore if this is not for us.
+	if (argc < 6) {
+		return;
+	}
+	int found_nsenter = 0;
+	for (c = 0; c < argc; ++c) {
+		if (strcmp(argv[c], kNsEnter) == 0) {
+			found_nsenter = 1;
+			break;
+		}
+	}
+	if (!found_nsenter) {
+		return;
+	}
+	static const struct option longopts[] = {
+		{"nspid", required_argument, NULL, 'n'},
+		{"containerjson", required_argument, NULL, 'c'},
+		{"console", optional_argument, NULL, 't'},
+		{NULL, 0, NULL, 0}
+	};
+
+	pid_t init_pid = -1;
+	char *init_pid_str = NULL;
+	char *container_json = NULL;
+	char *console = NULL;
+	opterr = 0;
+	while ((c =
+		getopt_long_only(argc, argv, "-n:s:c:", longopts,
+				 NULL)) != -1) {
+		switch (c) {
+		case 'n':
+			init_pid_str = optarg;
+			break;
+		case 'c':
+			container_json = optarg;
+			break;
+		case 't':
+			console = optarg;
+			break;
+		}
+	}
+
+	if (strcmp(argv[optind - 2], kNsEnter) != 0) {
+		return;
+	}
+
+	if (container_json == NULL || init_pid_str == NULL) {
+		print_usage();
+		exit(1);
+	}
+
+	init_pid = strtol(init_pid_str, NULL, 10);
+	if ((init_pid == 0 && errno == EINVAL) || errno == ERANGE) {
+		fprintf(stderr,
+			"nsenter: Failed to parse PID from \"%s\" with output \"%d\" and error: \"%s\"\n",
+			init_pid_str, init_pid, strerror(errno));
+		print_usage();
+		exit(1);
+	}
+
+	argc -= 3;
+	argv += 3;
+
+	if (setsid() == -1) {
+		fprintf(stderr, "setsid failed. Error: %s\n", strerror(errno));
+		exit(1);
+	}
+	// before we setns we need to dup the console
+	int consolefd = -1;
+	if (console != NULL) {
+		consolefd = open(console, O_RDWR);
+		if (consolefd < 0) {
+			fprintf(stderr,
+				"nsenter: failed to open console %s %s\n",
+				console, strerror(errno));
+			exit(1);
+		}
+	}
+	// Setns on all supported namespaces.
+	char ns_dir[PATH_MAX];
+	memset(ns_dir, 0, PATH_MAX);
+	snprintf(ns_dir, PATH_MAX - 1, "/proc/%d/ns/", init_pid);
+
+	char *namespaces[] = { "ipc", "uts", "net", "pid", "mnt" };
+	const int num = sizeof(namespaces) / sizeof(char *);
+	int i;
+	for (i = 0; i < num; i++) {
+		char buf[PATH_MAX];
+		memset(buf, 0, PATH_MAX);
+		snprintf(buf, PATH_MAX - 1, "%s%s", ns_dir, namespaces[i]);
+		int fd = open(buf, O_RDONLY);
+		if (fd == -1) {
+			// Ignore nonexistent namespaces.
+			if (errno == ENOENT)
+				continue;
+
+			fprintf(stderr,
+				"nsenter: Failed to open ns file \"%s\" for ns \"%s\" with error: \"%s\"\n",
+				buf, namespaces[i], strerror(errno));
+			exit(1);
+		}
+		// Set the namespace.
+		if (setns(fd, 0) == -1) {
+			fprintf(stderr,
+				"nsenter: Failed to setns for \"%s\" with error: \"%s\"\n",
+				namespaces[i], strerror(errno));
+			exit(1);
+		}
+		close(fd);
+	}
+
+	// We must fork to actually enter the PID namespace.
+	int child = fork();
+	if (child == 0) {
+		if (consolefd != -1) {
+			if (dup2(consolefd, STDIN_FILENO) != 0) {
+				fprintf(stderr, "nsenter: failed to dup 0 %s\n",
+					strerror(errno));
+				exit(1);
+			}
+			if (dup2(consolefd, STDOUT_FILENO) != STDOUT_FILENO) {
+				fprintf(stderr, "nsenter: failed to dup 1 %s\n",
+					strerror(errno));
+				exit(1);
+			}
+			if (dup2(consolefd, STDERR_FILENO) != STDERR_FILENO) {
+				fprintf(stderr, "nsenter: failed to dup 2 %s\n",
+					strerror(errno));
+				exit(1);
+			}
+		}
+		// Finish executing, let the Go runtime take over.
+		return;
+	} else {
+		// Parent, wait for the child.
+		int status = 0;
+		if (waitpid(child, &status, 0) == -1) {
+			fprintf(stderr,
+				"nsenter: Failed to waitpid with error: \"%s\"\n",
+				strerror(errno));
+			exit(1);
+		}
+		// Forward the child's exit code or re-send its death signal.
+		if (WIFEXITED(status)) {
+			exit(WEXITSTATUS(status));
+		} else if (WIFSIGNALED(status)) {
+			kill(getpid(), WTERMSIG(status));
+		}
+		exit(1);
+	}
+
+	return;
+}

+ 0 - 206
vendor/src/github.com/docker/libcontainer/namespaces/nsenter.go

@@ -3,212 +3,6 @@
 package namespaces
 
 /*
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/limits.h>
-#include <linux/sched.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <getopt.h>
-
-static const kBufSize = 256;
-
-void get_args(int *argc, char ***argv) {
-	// Read argv
-	int fd = open("/proc/self/cmdline", O_RDONLY);
-
-	// Read the whole commandline.
-	ssize_t contents_size = 0;
-	ssize_t contents_offset = 0;
-	char *contents = NULL;
-	ssize_t bytes_read = 0;
-	do {
-		contents_size += kBufSize;
-		contents = (char *) realloc(contents, contents_size);
-		bytes_read = read(fd, contents + contents_offset, contents_size - contents_offset);
-		contents_offset += bytes_read;
-	} while (bytes_read > 0);
-	close(fd);
-
-	// Parse the commandline into an argv. /proc/self/cmdline has \0 delimited args.
-	ssize_t i;
-	*argc = 0;
-	for (i = 0; i < contents_offset; i++) {
-		if (contents[i] == '\0') {
-			(*argc)++;
-		}
-	}
-	*argv = (char **) malloc(sizeof(char *) * ((*argc) + 1));
-	int idx;
-	for (idx = 0; idx < (*argc); idx++) {
-		(*argv)[idx] = contents;
-		contents += strlen(contents) + 1;
-	}
-	(*argv)[*argc] = NULL;
-}
-
-// Use raw setns syscall for versions of glibc that don't include it (namely glibc-2.12)
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 14
-#define _GNU_SOURCE
-#include <sched.h>
-#include "syscall.h"
-#ifdef SYS_setns
-int setns(int fd, int nstype) {
-  return syscall(SYS_setns, fd, nstype);
-}
-#endif
-#endif
-
-void print_usage() {
-	fprintf(stderr, "<binary> nsenter --nspid <pid> --containerjson <container_json> -- cmd1 arg1 arg2...\n");
-}
-
-void nsenter() {
-	int argc;
-	char **argv;
-	get_args(&argc, &argv);
-
-	// Ignore if this is not for us.
-	if (argc < 2 || strcmp(argv[1], "nsenter") != 0) {
-		return;
-	}
-
-	// USAGE: <binary> nsenter <PID> <process label> <container JSON> <argv>...
-	if (argc < 6) {
-		fprintf(stderr, "nsenter: Incorrect usage, not enough arguments\n");
-		exit(1);
-	}
-
-	static const struct option longopts[] = {
-		{ "nspid",         required_argument, NULL, 'n' },
-		{ "containerjson", required_argument, NULL, 'c' },
-                { "console",       required_argument, NULL, 't' },
-		{ NULL,            0,                 NULL,  0  }
-	};
-
-	int c;
-	pid_t init_pid = -1;
-	char *init_pid_str = NULL;
-	char *container_json = NULL;
-        char *console = NULL;
-	while ((c = getopt_long_only(argc, argv, "n:s:c:", longopts, NULL)) != -1) {
-		switch (c) {
-		case 'n':
-			init_pid_str = optarg;
-			break;
-		case 'c':
-			container_json = optarg;
-			break;
-		case 't':
-			console = optarg;
-			break;
-		}
-	}
-
-	if (container_json == NULL || init_pid_str == NULL) {
-		print_usage();
-		exit(1);
-	}
-
-	init_pid = strtol(init_pid_str, NULL, 10);
-	if (errno != 0 || init_pid <= 0) {
-		fprintf(stderr, "nsenter: Failed to parse PID from \"%s\" with error: \"%s\"\n", init_pid_str, strerror(errno));
-		print_usage();
-		exit(1);
-	}
-
-	argc -= 3;
-	argv += 3;
-
-        if (setsid() == -1) {
-               fprintf(stderr, "setsid failed. Error: %s\n", strerror(errno));
-               exit(1);
-        }
-
-        // before we setns we need to dup the console
-        int consolefd = -1;
-        if (console != NULL) {
-               consolefd = open(console, O_RDWR);
-               if (consolefd < 0) {
-                    fprintf(stderr, "nsenter: failed to open console %s %s\n", console, strerror(errno));
-                    exit(1);
-              }
-        }
-
-	// Setns on all supported namespaces.
-	char ns_dir[PATH_MAX];
-	memset(ns_dir, 0, PATH_MAX);
-	snprintf(ns_dir, PATH_MAX - 1, "/proc/%d/ns/", init_pid);
-
-	char* namespaces[] = {"ipc", "uts", "net", "pid", "mnt"};
-	const int num = sizeof(namespaces) / sizeof(char*);
-	int i;
-	for (i = 0; i < num; i++) {
-		char buf[PATH_MAX];
-		memset(buf, 0, PATH_MAX);
-		snprintf(buf, PATH_MAX - 1, "%s%s", ns_dir, namespaces[i]);
-		int fd = open(buf, O_RDONLY);
-		if (fd == -1) {
-			// Ignore nonexistent namespaces.
-			if (errno == ENOENT)
-				continue;
-
-			fprintf(stderr, "nsenter: Failed to open ns file \"%s\" for ns \"%s\" with error: \"%s\"\n", buf, namespaces[i], strerror(errno));
-			exit(1);
-		}
-
-		// Set the namespace.
-		if (setns(fd, 0) == -1) {
-			fprintf(stderr, "nsenter: Failed to setns for \"%s\" with error: \"%s\"\n", namespaces[i], strerror(errno));
-			exit(1);
-		}
-		close(fd);
-	}
-
-	// We must fork to actually enter the PID namespace.
-	int child = fork();
-	if (child == 0) {
-       if (consolefd != -1) {
-        if (dup2(consolefd, STDIN_FILENO) != 0) {
-            fprintf(stderr, "nsenter: failed to dup 0 %s\n",  strerror(errno));
-            exit(1);
-        }
-        if (dup2(consolefd, STDOUT_FILENO) != STDOUT_FILENO) {
-            fprintf(stderr, "nsenter: failed to dup 1 %s\n",  strerror(errno));
-            exit(1);
-        }
-        if (dup2(consolefd, STDERR_FILENO) != STDERR_FILENO) {
-            fprintf(stderr, "nsenter: failed to dup 2 %s\n",  strerror(errno));
-            exit(1);
-        }
-}
-
-		// Finish executing, let the Go runtime take over.
-		return;
-	} else {
-		// Parent, wait for the child.
-		int status = 0;
-		if (waitpid(child, &status, 0) == -1) {
-			fprintf(stderr, "nsenter: Failed to waitpid with error: \"%s\"\n", strerror(errno));
-			exit(1);
-		}
-
-		// Forward the child's exit code or re-send its death signal.
-		if (WIFEXITED(status)) {
-			exit(WEXITSTATUS(status));
-		} else if (WIFSIGNALED(status)) {
-			kill(getpid(), WTERMSIG(status));
-		}
-		exit(1);
-	}
-
-	return;
-}
-
 __attribute__((constructor)) init() {
 	nsenter();
 }

+ 47 - 14
vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go

@@ -189,13 +189,15 @@ func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
 }
 
 func (a *RtAttr) Len() int {
+	if len(a.children) == 0 {
+		return (syscall.SizeofRtAttr + len(a.Data))
+	}
+
 	l := 0
 	for _, child := range a.children {
-		l += child.Len() + syscall.SizeofRtAttr
-	}
-	if l == 0 {
-		l++
+		l += child.Len()
 	}
+	l += syscall.SizeofRtAttr
 	return rtaAlignOf(l + len(a.Data))
 }
 
@@ -203,7 +205,7 @@ func (a *RtAttr) ToWireFormat() []byte {
 	native := nativeEndian()
 
 	length := a.Len()
-	buf := make([]byte, rtaAlignOf(length+syscall.SizeofRtAttr))
+	buf := make([]byte, rtaAlignOf(length))
 
 	if a.Data != nil {
 		copy(buf[4:], a.Data)
@@ -216,11 +218,10 @@ func (a *RtAttr) ToWireFormat() []byte {
 		}
 	}
 
-	if l := uint16(rtaAlignOf(length)); l != 0 {
-		native.PutUint16(buf[0:2], l+1)
+	if l := uint16(length); l != 0 {
+		native.PutUint16(buf[0:2], l)
 	}
 	native.PutUint16(buf[2:4], a.Type)
-
 	return buf
 }
 
@@ -700,6 +701,10 @@ func nonZeroTerminated(s string) []byte {
 // Add a new network link of a specified type. This is identical to
 // running: ip add link $name type $linkType
 func NetworkLinkAdd(name string, linkType string) error {
+	if name == "" || linkType == "" {
+		return fmt.Errorf("Neither link name nor link type can be empty!")
+	}
+
 	s, err := getNetlinkSocket()
 	if err != nil {
 		return err
@@ -711,15 +716,43 @@ func NetworkLinkAdd(name string, linkType string) error {
 	msg := newIfInfomsg(syscall.AF_UNSPEC)
 	wb.AddData(msg)
 
-	if name != "" {
-		nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
-		wb.AddData(nameData)
+	linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
+	newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
+	wb.AddData(linkInfo)
+
+	nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
+	wb.AddData(nameData)
+
+	if err := s.Send(wb); err != nil {
+		return err
 	}
 
-	kindData := newRtAttr(IFLA_INFO_KIND, nonZeroTerminated(linkType))
+	return s.HandleAck(wb.Seq)
+}
+
+// Delete a network link. This is identical to
+// running: ip link del $name
+func NetworkLinkDel(name string) error {
+	if name == "" {
+		return fmt.Errorf("Network link name can not be empty!")
+	}
 
-	infoData := newRtAttr(syscall.IFLA_LINKINFO, kindData.ToWireFormat())
-	wb.AddData(infoData)
+	s, err := getNetlinkSocket()
+	if err != nil {
+		return err
+	}
+	defer s.Close()
+
+	iface, err := net.InterfaceByName(name)
+	if err != nil {
+		return err
+	}
+
+	wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
+
+	msg := newIfInfomsg(syscall.AF_UNSPEC)
+	msg.Index = int32(iface.Index)
+	wb.AddData(msg)
 
 	if err := s.Send(wb); err != nil {
 		return err

+ 26 - 1
vendor/src/github.com/docker/libcontainer/netlink/netlink_linux_test.go

@@ -27,10 +27,35 @@ func TestCreateBridgeWithMac(t *testing.T) {
 	}
 
 	if _, err := net.InterfaceByName(name); err == nil {
-		t.Fatal("expected error getting interface because bridge was deleted")
+		t.Fatalf("expected error getting interface because %s bridge was deleted", name)
 	}
 }
 
+func TestCreateBridgeLink(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	name := "mybrlink"
+
+	if err := NetworkLinkAdd(name, "bridge"); err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := net.InterfaceByName(name); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := NetworkLinkDel(name); err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := net.InterfaceByName(name); err == nil {
+		t.Fatalf("expected error getting interface because %s bridge was deleted", name)
+	}
+
+}
+
 func TestCreateVethPair(t *testing.T) {
 	if testing.Short() {
 		return

+ 4 - 0
vendor/src/github.com/docker/libcontainer/netlink/netlink_unsupported.go

@@ -19,6 +19,10 @@ func NetworkLinkAdd(name string, linkType string) error {
 	return ErrNotImplemented
 }
 
+func NetworkLinkDel(name string) error {
+	return ErrNotImplemented
+}
+
 func NetworkLinkUp(iface *net.Interface) error {
 	return ErrNotImplemented
 }

+ 4 - 1
vendor/src/github.com/docker/libcontainer/nsinit/cli.go

@@ -24,7 +24,10 @@ func NsInit() {
 	app.Name = "nsinit"
 	app.Version = "0.1"
 	app.Author = "libcontainer maintainers"
-
+	app.Flags = []cli.Flag{
+		cli.StringFlag{Name: "nspid"},
+		cli.StringFlag{Name: "containerjson"},
+		cli.StringFlag{Name: "console"}}
 	app.Before = preload
 	app.Commands = []cli.Command{
 		execCommand,

+ 1 - 54
vendor/src/github.com/docker/libcontainer/nsinit/exec.go

@@ -36,7 +36,7 @@ func execAction(context *cli.Context) {
 	}
 
 	if state != nil {
-		exitCode, err = runIn(container, state, []string(context.Args()))
+		err = namespaces.ExecIn(container, state, []string(context.Args()))
 	} else {
 		exitCode, err = startContainer(container, dataPath, []string(context.Args()))
 	}
@@ -48,59 +48,6 @@ func execAction(context *cli.Context) {
 	os.Exit(exitCode)
 }
 
-func runIn(container *libcontainer.Config, state *libcontainer.State, args []string) (int, error) {
-	var (
-		master  *os.File
-		console string
-		err     error
-
-		stdin  = os.Stdin
-		stdout = os.Stdout
-		stderr = os.Stderr
-		sigc   = make(chan os.Signal, 10)
-	)
-
-	signal.Notify(sigc)
-
-	if container.Tty {
-		stdin = nil
-		stdout = nil
-		stderr = nil
-
-		master, console, err = consolepkg.CreateMasterAndConsole()
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		go io.Copy(master, os.Stdin)
-		go io.Copy(os.Stdout, master)
-
-		state, err := term.SetRawTerminal(os.Stdin.Fd())
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		defer term.RestoreTerminal(os.Stdin.Fd(), state)
-	}
-
-	startCallback := func(cmd *exec.Cmd) {
-		go func() {
-			resizeTty(master)
-
-			for sig := range sigc {
-				switch sig {
-				case syscall.SIGWINCH:
-					resizeTty(master)
-				default:
-					cmd.Process.Signal(sig)
-				}
-			}
-		}()
-	}
-
-	return namespaces.RunIn(container, state, args, os.Args[0], stdin, stdout, stderr, console, startCallback)
-}
-
 // startContainer starts the container. Returns the exit status or -1 and an
 // error.
 //

+ 5 - 9
vendor/src/github.com/docker/libcontainer/nsinit/nsenter.go

@@ -2,6 +2,7 @@ package nsinit
 
 import (
 	"log"
+	"strconv"
 
 	"github.com/codegangsta/cli"
 	"github.com/docker/libcontainer/namespaces"
@@ -11,11 +12,6 @@ var nsenterCommand = cli.Command{
 	Name:   "nsenter",
 	Usage:  "init process for entering an existing namespace",
 	Action: nsenterAction,
-	Flags: []cli.Flag{
-		cli.IntFlag{Name: "nspid"},
-		cli.StringFlag{Name: "containerjson"},
-		cli.StringFlag{Name: "console"},
-	},
 }
 
 func nsenterAction(context *cli.Context) {
@@ -25,14 +21,14 @@ func nsenterAction(context *cli.Context) {
 		args = []string{"/bin/bash"}
 	}
 
-	container, err := loadContainerFromJson(context.String("containerjson"))
+	container, err := loadContainerFromJson(context.GlobalString("containerjson"))
 	if err != nil {
 		log.Fatalf("unable to load container: %s", err)
 	}
 
-	nspid := context.Int("nspid")
-	if nspid <= 0 {
-		log.Fatalf("cannot enter into namespaces without valid pid: %q", nspid)
+	nspid, err := strconv.Atoi(context.GlobalString("nspid"))
+	if nspid <= 0 || err != nil {
+		log.Fatalf("cannot enter into namespaces without valid pid: %q - %s", nspid, err)
 	}
 
 	if err := namespaces.NsEnter(container, args); err != nil {

+ 48 - 0
vendor/src/github.com/docker/libcontainer/update-vendor.sh

@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+set -e
+
+cd "$(dirname "$BASH_SOURCE")"
+
+# Downloads dependencies into vendor/ directory
+mkdir -p vendor
+cd vendor
+
+clone() {
+	vcs=$1
+	pkg=$2
+	rev=$3
+	
+	pkg_url=https://$pkg
+	target_dir=src/$pkg
+	
+	echo -n "$pkg @ $rev: "
+	
+	if [ -d $target_dir ]; then
+		echo -n 'rm old, '
+		rm -fr $target_dir
+	fi
+	
+	echo -n 'clone, '
+	case $vcs in
+		git)
+			git clone --quiet --no-checkout $pkg_url $target_dir
+			( cd $target_dir && git reset --quiet --hard $rev )
+			;;
+		hg)
+			hg clone --quiet --updaterev $rev $pkg_url $target_dir
+			;;
+	esac
+	
+	echo -n 'rm VCS, '
+	( cd $target_dir && rm -rf .{git,hg} )
+	
+	echo done
+}
+
+# the following lines are in sorted order, FYI
+clone git github.com/codegangsta/cli 1.1.0
+clone git github.com/coreos/go-systemd v2
+clone git github.com/godbus/dbus v1
+clone git github.com/syndtr/gocapability 3c85049eae
+
+# intentionally not vendoring Docker itself...  that'd be a circle :)

+ 6 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/.travis.yml

@@ -0,0 +1,6 @@
+language: go
+go: 1.1
+
+script:
+- go vet ./...
+- go test -v ./...

+ 21 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/LICENSE

@@ -0,0 +1,21 @@
+Copyright (C) 2013 Jeremy Saenz
+All Rights Reserved.
+
+MIT LICENSE
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 257 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/README.md

@@ -0,0 +1,257 @@
+[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli)
+
+# cli.go
+cli.go is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
+
+You can view the API docs here:
+http://godoc.org/github.com/codegangsta/cli
+
+## Overview
+Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
+
+This is where cli.go comes into play. cli.go makes command line programming fun, organized, and expressive!
+
+## Installation
+Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html).
+
+To install cli.go, simply run:
+```
+$ go get github.com/codegangsta/cli
+```
+
+Make sure your PATH includes to the `$GOPATH/bin` directory so your commands can be easily used:
+```
+export PATH=$PATH:$GOPATH/bin
+```
+
+## Getting Started
+One of the philosophies behind cli.go is that an API should be playful and full of discovery. So a cli.go app can be as little as one line of code in `main()`. 
+
+``` go
+package main
+
+import (
+  "os"
+  "github.com/codegangsta/cli"
+)
+
+func main() {
+  cli.NewApp().Run(os.Args)
+}
+```
+
+This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation:
+
+``` go
+package main
+
+import (
+  "os"
+  "github.com/codegangsta/cli"
+)
+
+func main() {
+  app := cli.NewApp()
+  app.Name = "boom"
+  app.Usage = "make an explosive entrance"
+  app.Action = func(c *cli.Context) {
+    println("boom! I say!")
+  }
+  
+  app.Run(os.Args)
+}
+```
+
+Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below.
+
+## Example
+
+Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness!
+
+``` go
+/* greet.go */
+package main
+
+import (
+  "os"
+  "github.com/codegangsta/cli"
+)
+
+func main() {
+  app := cli.NewApp()
+  app.Name = "greet"
+  app.Usage = "fight the loneliness!"
+  app.Action = func(c *cli.Context) {
+    println("Hello friend!")
+  }
+  
+  app.Run(os.Args)
+}
+```
+
+Install our command to the `$GOPATH/bin` directory:
+
+```
+$ go install
+```
+
+Finally run our new command:
+
+```
+$ greet
+Hello friend!
+```
+
+cli.go also generates some bitchass help text:
+```
+$ greet help
+NAME:
+    greet - fight the loneliness!
+
+USAGE:
+    greet [global options] command [command options] [arguments...]
+
+VERSION:
+    0.0.0
+
+COMMANDS:
+    help, h  Shows a list of commands or help for one command
+
+GLOBAL OPTIONS
+    --version	Shows version information
+```
+
+### Arguments
+You can lookup arguments by calling the `Args` function on cli.Context.
+
+``` go
+...
+app.Action = func(c *cli.Context) {
+  println("Hello", c.Args()[0])
+}
+...
+```
+
+### Flags
+Setting and querying flags is simple.
+``` go
+...
+app.Flags = []cli.Flag {
+  cli.StringFlag{Name: "lang", Value: "english", Usage: "language for the greeting"},
+}
+app.Action = func(c *cli.Context) {
+  name := "someone"
+  if len(c.Args()) > 0 {
+    name = c.Args()[0]
+  }
+  if c.String("lang") == "spanish" {
+    println("Hola", name)
+  } else {
+    println("Hello", name)
+  }
+}
+...
+```
+
+#### Alternate Names
+
+You can set alternate (or short) names for flags by providing a comma-delimited list for the Name. e.g.
+
+``` go
+app.Flags = []cli.Flag {
+  cli.StringFlag{Name: "lang, l", Value: "english", Usage: "language for the greeting"},
+}
+```
+
+That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error.
+
+### Subcommands
+
+Subcommands can be defined for a more git-like command line app.
+```go
+...
+app.Commands = []cli.Command{
+  {
+    Name:      "add",
+    ShortName: "a",
+    Usage:     "add a task to the list",
+    Action: func(c *cli.Context) {
+      println("added task: ", c.Args().First())
+    },
+  },
+  {
+    Name:      "complete",
+    ShortName: "c",
+    Usage:     "complete a task on the list",
+    Action: func(c *cli.Context) {
+      println("completed task: ", c.Args().First())
+    },
+  },
+  {
+    Name:      "template",
+    ShortName: "r",
+    Usage:     "options for task templates",
+    Subcommands: []cli.Command{
+      {
+        Name:  "add",
+        Usage: "add a new template",
+        Action: func(c *cli.Context) {
+            println("new task template: ", c.Args().First())
+        },
+      },
+      {
+        Name:  "remove",
+        Usage: "remove an existing template",
+        Action: func(c *cli.Context) {
+          println("removed task template: ", c.Args().First())
+        },
+      },
+    },
+  },     
+}
+...
+```
+
+### Bash Completion
+
+You can enable completion commands by setting the EnableBashCompletion
+flag on the App object.  By default, this setting will only auto-complete to
+show an app's subcommands, but you can write your own completion methods for
+the App or its subcommands.
+```go
+...
+var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
+app := cli.NewApp()
+app.EnableBashCompletion = true
+app.Commands = []cli.Command{
+  {
+    Name: "complete",
+    ShortName: "c",
+    Usage: "complete a task on the list",
+    Action: func(c *cli.Context) {
+       println("completed task: ", c.Args().First())
+    },
+    BashComplete: func(c *cli.Context) {
+      // This will complete if no args are passed
+      if len(c.Args()) > 0 {
+        return
+      }
+      for _, t := range tasks {
+        println(t)
+      }
+    },
+  }
+}
+...
+```
+
+#### To Enable
+
+Source the autocomplete/bash_autocomplete file in your .bashrc file while
+setting the PROG variable to the name of your program:
+
+`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`
+
+
+## About
+cli.go is written by none other than the [Code Gangsta](http://codegangsta.io)

+ 248 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app.go

@@ -0,0 +1,248 @@
+package cli
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"time"
+)
+
+// App is the main structure of a cli application. It is recomended that
+// and app be created with the cli.NewApp() function
+type App struct {
+	// The name of the program. Defaults to os.Args[0]
+	Name string
+	// Description of the program.
+	Usage string
+	// Version of the program
+	Version string
+	// List of commands to execute
+	Commands []Command
+	// List of flags to parse
+	Flags []Flag
+	// Boolean to enable bash completion commands
+	EnableBashCompletion bool
+	// Boolean to hide built-in help command
+	HideHelp bool
+	// An action to execute when the bash-completion flag is set
+	BashComplete func(context *Context)
+	// An action to execute before any subcommands are run, but after the context is ready
+	// If a non-nil error is returned, no subcommands are run
+	Before func(context *Context) error
+	// The action to execute when no subcommands are specified
+	Action func(context *Context)
+	// Execute this function if the proper command cannot be found
+	CommandNotFound func(context *Context, command string)
+	// Compilation date
+	Compiled time.Time
+	// Author
+	Author string
+	// Author e-mail
+	Email string
+}
+
+// Tries to find out when this binary was compiled.
+// Returns the current time if it fails to find it.
+func compileTime() time.Time {
+	info, err := os.Stat(os.Args[0])
+	if err != nil {
+		return time.Now()
+	}
+	return info.ModTime()
+}
+
+// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
+func NewApp() *App {
+	return &App{
+		Name:         os.Args[0],
+		Usage:        "A new cli application",
+		Version:      "0.0.0",
+		BashComplete: DefaultAppComplete,
+		Action:       helpCommand.Action,
+		Compiled:     compileTime(),
+		Author:       "Author",
+		Email:        "unknown@email",
+	}
+}
+
+// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
+func (a *App) Run(arguments []string) error {
+	// append help to commands
+	if a.Command(helpCommand.Name) == nil && !a.HideHelp {
+		a.Commands = append(a.Commands, helpCommand)
+		a.appendFlag(HelpFlag)
+	}
+
+	//append version/help flags
+	if a.EnableBashCompletion {
+		a.appendFlag(BashCompletionFlag)
+	}
+	a.appendFlag(VersionFlag)
+
+	// parse flags
+	set := flagSet(a.Name, a.Flags)
+	set.SetOutput(ioutil.Discard)
+	err := set.Parse(arguments[1:])
+	nerr := normalizeFlags(a.Flags, set)
+	if nerr != nil {
+		fmt.Println(nerr)
+		context := NewContext(a, set, set)
+		ShowAppHelp(context)
+		fmt.Println("")
+		return nerr
+	}
+	context := NewContext(a, set, set)
+
+	if err != nil {
+		fmt.Printf("Incorrect Usage.\n\n")
+		ShowAppHelp(context)
+		fmt.Println("")
+		return err
+	}
+
+	if checkCompletions(context) {
+		return nil
+	}
+
+	if checkHelp(context) {
+		return nil
+	}
+
+	if checkVersion(context) {
+		return nil
+	}
+
+	if a.Before != nil {
+		err := a.Before(context)
+		if err != nil {
+			return err
+		}
+	}
+
+	args := context.Args()
+	if args.Present() {
+		name := args.First()
+		c := a.Command(name)
+		if c != nil {
+			return c.Run(context)
+		}
+	}
+
+	// Run default Action
+	a.Action(context)
+	return nil
+}
+
+// Another entry point to the cli app, takes care of passing arguments and error handling
+func (a *App) RunAndExitOnError() {
+	if err := a.Run(os.Args); err != nil {
+		os.Stderr.WriteString(fmt.Sprintln(err))
+		os.Exit(1)
+	}
+}
+
+// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
+func (a *App) RunAsSubcommand(ctx *Context) error {
+	// append help to commands
+	if len(a.Commands) > 0 {
+		if a.Command(helpCommand.Name) == nil && !a.HideHelp {
+			a.Commands = append(a.Commands, helpCommand)
+			a.appendFlag(HelpFlag)
+		}
+	}
+
+	// append flags
+	if a.EnableBashCompletion {
+		a.appendFlag(BashCompletionFlag)
+	}
+
+	// parse flags
+	set := flagSet(a.Name, a.Flags)
+	set.SetOutput(ioutil.Discard)
+	err := set.Parse(ctx.Args().Tail())
+	nerr := normalizeFlags(a.Flags, set)
+	context := NewContext(a, set, ctx.globalSet)
+
+	if nerr != nil {
+		fmt.Println(nerr)
+		if len(a.Commands) > 0 {
+			ShowSubcommandHelp(context)
+		} else {
+			ShowCommandHelp(ctx, context.Args().First())
+		}
+		fmt.Println("")
+		return nerr
+	}
+
+	if err != nil {
+		fmt.Printf("Incorrect Usage.\n\n")
+		ShowSubcommandHelp(context)
+		return err
+	}
+
+	if checkCompletions(context) {
+		return nil
+	}
+
+	if len(a.Commands) > 0 {
+		if checkSubcommandHelp(context) {
+			return nil
+		}
+	} else {
+		if checkCommandHelp(ctx, context.Args().First()) {
+			return nil
+		}
+	}
+
+	if a.Before != nil {
+		err := a.Before(context)
+		if err != nil {
+			return err
+		}
+	}
+
+	args := context.Args()
+	if args.Present() {
+		name := args.First()
+		c := a.Command(name)
+		if c != nil {
+			return c.Run(context)
+		}
+	}
+
+	// Run default Action
+	if len(a.Commands) > 0 {
+		a.Action(context)
+	} else {
+		a.Action(ctx)
+	}
+
+	return nil
+}
+
+// Returns the named command on App. Returns nil if the command does not exist
+func (a *App) Command(name string) *Command {
+	for _, c := range a.Commands {
+		if c.HasName(name) {
+			return &c
+		}
+	}
+
+	return nil
+}
+
+func (a *App) hasFlag(flag Flag) bool {
+	for _, f := range a.Flags {
+		if flag == f {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (a *App) appendFlag(flag Flag) {
+	if !a.hasFlag(flag) {
+		a.Flags = append(a.Flags, flag)
+	}
+}

+ 399 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/app_test.go

@@ -0,0 +1,399 @@
+package cli_test
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/codegangsta/cli"
+)
+
+func ExampleApp() {
+	// set args for examples sake
+	os.Args = []string{"greet", "--name", "Jeremy"}
+
+	app := cli.NewApp()
+	app.Name = "greet"
+	app.Flags = []cli.Flag{
+		cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
+	}
+	app.Action = func(c *cli.Context) {
+		fmt.Printf("Hello %v\n", c.String("name"))
+	}
+	app.Run(os.Args)
+	// Output:
+	// Hello Jeremy
+}
+
+func ExampleAppSubcommand() {
+	// set args for examples sake
+	os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
+	app := cli.NewApp()
+	app.Name = "say"
+	app.Commands = []cli.Command{
+		{
+			Name:        "hello",
+			ShortName:   "hi",
+			Usage:       "use it to see a description",
+			Description: "This is how we describe hello the function",
+			Subcommands: []cli.Command{
+				{
+					Name:        "english",
+					ShortName:   "en",
+					Usage:       "sends a greeting in english",
+					Description: "greets someone in english",
+					Flags: []cli.Flag{
+						cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"},
+					},
+					Action: func(c *cli.Context) {
+						fmt.Println("Hello,", c.String("name"))
+					},
+				},
+			},
+		},
+	}
+
+	app.Run(os.Args)
+	// Output:
+	// Hello, Jeremy
+}
+
+func ExampleAppHelp() {
+	// set args for examples sake
+	os.Args = []string{"greet", "h", "describeit"}
+
+	app := cli.NewApp()
+	app.Name = "greet"
+	app.Flags = []cli.Flag{
+		cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
+	}
+	app.Commands = []cli.Command{
+		{
+			Name:        "describeit",
+			ShortName:   "d",
+			Usage:       "use it to see a description",
+			Description: "This is how we describe describeit the function",
+			Action: func(c *cli.Context) {
+				fmt.Printf("i like to describe things")
+			},
+		},
+	}
+	app.Run(os.Args)
+	// Output:
+	// NAME:
+	//    describeit - use it to see a description
+	//
+	// USAGE:
+	//    command describeit [arguments...]
+	//
+	// DESCRIPTION:
+	//    This is how we describe describeit the function
+}
+
+func ExampleAppBashComplete() {
+	// set args for examples sake
+	os.Args = []string{"greet", "--generate-bash-completion"}
+
+	app := cli.NewApp()
+	app.Name = "greet"
+	app.EnableBashCompletion = true
+	app.Commands = []cli.Command{
+		{
+			Name:        "describeit",
+			ShortName:   "d",
+			Usage:       "use it to see a description",
+			Description: "This is how we describe describeit the function",
+			Action: func(c *cli.Context) {
+				fmt.Printf("i like to describe things")
+			},
+		}, {
+			Name:        "next",
+			Usage:       "next example",
+			Description: "more stuff to see when generating bash completion",
+			Action: func(c *cli.Context) {
+				fmt.Printf("the next example")
+			},
+		},
+	}
+
+	app.Run(os.Args)
+	// Output:
+	// describeit
+	// d
+	// next
+	// help
+	// h
+}
+
+func TestApp_Run(t *testing.T) {
+	s := ""
+
+	app := cli.NewApp()
+	app.Action = func(c *cli.Context) {
+		s = s + c.Args().First()
+	}
+
+	err := app.Run([]string{"command", "foo"})
+	expect(t, err, nil)
+	err = app.Run([]string{"command", "bar"})
+	expect(t, err, nil)
+	expect(t, s, "foobar")
+}
+
+var commandAppTests = []struct {
+	name     string
+	expected bool
+}{
+	{"foobar", true},
+	{"batbaz", true},
+	{"b", true},
+	{"f", true},
+	{"bat", false},
+	{"nothing", false},
+}
+
+func TestApp_Command(t *testing.T) {
+	app := cli.NewApp()
+	fooCommand := cli.Command{Name: "foobar", ShortName: "f"}
+	batCommand := cli.Command{Name: "batbaz", ShortName: "b"}
+	app.Commands = []cli.Command{
+		fooCommand,
+		batCommand,
+	}
+
+	for _, test := range commandAppTests {
+		expect(t, app.Command(test.name) != nil, test.expected)
+	}
+}
+
+func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
+	var parsedOption, firstArg string
+
+	app := cli.NewApp()
+	command := cli.Command{
+		Name: "cmd",
+		Flags: []cli.Flag{
+			cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
+		},
+		Action: func(c *cli.Context) {
+			parsedOption = c.String("option")
+			firstArg = c.Args().First()
+		},
+	}
+	app.Commands = []cli.Command{command}
+
+	app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
+
+	expect(t, parsedOption, "my-option")
+	expect(t, firstArg, "my-arg")
+}
+
+func TestApp_Float64Flag(t *testing.T) {
+	var meters float64
+
+	app := cli.NewApp()
+	app.Flags = []cli.Flag{
+		cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
+	}
+	app.Action = func(c *cli.Context) {
+		meters = c.Float64("height")
+	}
+
+	app.Run([]string{"", "--height", "1.93"})
+	expect(t, meters, 1.93)
+}
+
+func TestApp_ParseSliceFlags(t *testing.T) {
+	var parsedOption, firstArg string
+	var parsedIntSlice []int
+	var parsedStringSlice []string
+
+	app := cli.NewApp()
+	command := cli.Command{
+		Name: "cmd",
+		Flags: []cli.Flag{
+			cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
+			cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
+		},
+		Action: func(c *cli.Context) {
+			parsedIntSlice = c.IntSlice("p")
+			parsedStringSlice = c.StringSlice("ip")
+			parsedOption = c.String("option")
+			firstArg = c.Args().First()
+		},
+	}
+	app.Commands = []cli.Command{command}
+
+	app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
+
+	IntsEquals := func(a, b []int) bool {
+		if len(a) != len(b) {
+			return false
+		}
+		for i, v := range a {
+			if v != b[i] {
+				return false
+			}
+		}
+		return true
+	}
+
+	StrsEquals := func(a, b []string) bool {
+		if len(a) != len(b) {
+			return false
+		}
+		for i, v := range a {
+			if v != b[i] {
+				return false
+			}
+		}
+		return true
+	}
+	var expectedIntSlice = []int{22, 80}
+	var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
+
+	if !IntsEquals(parsedIntSlice, expectedIntSlice) {
+		t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
+	}
+
+	if !StrsEquals(parsedStringSlice, expectedStringSlice) {
+		t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
+	}
+}
+
+func TestApp_BeforeFunc(t *testing.T) {
+	beforeRun, subcommandRun := false, false
+	beforeError := fmt.Errorf("fail")
+	var err error
+
+	app := cli.NewApp()
+
+	app.Before = func(c *cli.Context) error {
+		beforeRun = true
+		s := c.String("opt")
+		if s == "fail" {
+			return beforeError
+		}
+
+		return nil
+	}
+
+	app.Commands = []cli.Command{
+		cli.Command{
+			Name: "sub",
+			Action: func(c *cli.Context) {
+				subcommandRun = true
+			},
+		},
+	}
+
+	app.Flags = []cli.Flag{
+		cli.StringFlag{Name: "opt"},
+	}
+
+	// run with the Before() func succeeding
+	err = app.Run([]string{"command", "--opt", "succeed", "sub"})
+
+	if err != nil {
+		t.Fatalf("Run error: %s", err)
+	}
+
+	if beforeRun == false {
+		t.Errorf("Before() not executed when expected")
+	}
+
+	if subcommandRun == false {
+		t.Errorf("Subcommand not executed when expected")
+	}
+
+	// reset
+	beforeRun, subcommandRun = false, false
+
+	// run with the Before() func failing
+	err = app.Run([]string{"command", "--opt", "fail", "sub"})
+
+	// should be the same error produced by the Before func
+	if err != beforeError {
+		t.Errorf("Run error expected, but not received")
+	}
+
+	if beforeRun == false {
+		t.Errorf("Before() not executed when expected")
+	}
+
+	if subcommandRun == true {
+		t.Errorf("Subcommand executed when NOT expected")
+	}
+
+}
+
+func TestAppHelpPrinter(t *testing.T) {
+	oldPrinter := cli.HelpPrinter
+	defer func() {
+		cli.HelpPrinter = oldPrinter
+	}()
+
+	var wasCalled = false
+	cli.HelpPrinter = func(template string, data interface{}) {
+		wasCalled = true
+	}
+
+	app := cli.NewApp()
+	app.Run([]string{"-h"})
+
+	if wasCalled == false {
+		t.Errorf("Help printer expected to be called, but was not")
+	}
+}
+
+func TestAppCommandNotFound(t *testing.T) {
+	beforeRun, subcommandRun := false, false
+	app := cli.NewApp()
+
+	app.CommandNotFound = func(c *cli.Context, command string) {
+		beforeRun = true
+	}
+
+	app.Commands = []cli.Command{
+		cli.Command{
+			Name: "bar",
+			Action: func(c *cli.Context) {
+				subcommandRun = true
+			},
+		},
+	}
+
+	app.Run([]string{"command", "foo"})
+
+	expect(t, beforeRun, true)
+	expect(t, subcommandRun, false)
+}
+
+func TestGlobalFlagsInSubcommands(t *testing.T) {
+	subcommandRun := false
+	app := cli.NewApp()
+
+	app.Flags = []cli.Flag{
+		cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
+	}
+
+	app.Commands = []cli.Command{
+		cli.Command{
+			Name: "foo",
+			Subcommands: []cli.Command{
+				{
+					Name: "bar",
+					Action: func(c *cli.Context) {
+						if c.GlobalBool("debug") {
+							subcommandRun = true
+						}
+					},
+				},
+			},
+		},
+	}
+
+	app.Run([]string{"command", "-d", "foo", "bar"})
+
+	expect(t, subcommandRun, true)
+}

+ 13 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete

@@ -0,0 +1,13 @@
+#! /bin/bash
+
+_cli_bash_autocomplete() {
+     local cur prev opts base
+     COMPREPLY=()
+     cur="${COMP_WORDS[COMP_CWORD]}"
+     prev="${COMP_WORDS[COMP_CWORD-1]}"
+     opts=$( ${COMP_WORDS[@]:0:COMP_CWORD} --generate-bash-completion )
+     COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+     return 0
+ }
+  
+ complete -F _cli_bash_autocomplete $PROG

+ 19 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli.go

@@ -0,0 +1,19 @@
+// Package cli provides a minimal framework for creating and organizing command line
+// Go applications. cli is designed to be easy to understand and write, the most simple
+// cli application can be written as follows:
+//   func main() {
+//     cli.NewApp().Run(os.Args)
+//   }
+//
+// Of course this application does not do much, so let's make this an actual application:
+//   func main() {
+//     app := cli.NewApp()
+//     app.Name = "greet"
+//     app.Usage = "say a greeting"
+//     app.Action = func(c *cli.Context) {
+//       println("Greetings")
+//     }
+//
+//     app.Run(os.Args)
+//   }
+package cli

+ 88 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/cli_test.go

@@ -0,0 +1,88 @@
+package cli_test
+
+import (
+	"os"
+
+	"github.com/codegangsta/cli"
+)
+
+func Example() {
+	app := cli.NewApp()
+	app.Name = "todo"
+	app.Usage = "task list on the command line"
+	app.Commands = []cli.Command{
+		{
+			Name:      "add",
+			ShortName: "a",
+			Usage:     "add a task to the list",
+			Action: func(c *cli.Context) {
+				println("added task: ", c.Args().First())
+			},
+		},
+		{
+			Name:      "complete",
+			ShortName: "c",
+			Usage:     "complete a task on the list",
+			Action: func(c *cli.Context) {
+				println("completed task: ", c.Args().First())
+			},
+		},
+	}
+
+	app.Run(os.Args)
+}
+
+func ExampleSubcommand() {
+	app := cli.NewApp()
+	app.Name = "say"
+	app.Commands = []cli.Command{
+		{
+			Name:        "hello",
+			ShortName:   "hi",
+			Usage:       "use it to see a description",
+			Description: "This is how we describe hello the function",
+			Subcommands: []cli.Command{
+				{
+					Name:        "english",
+					ShortName:   "en",
+					Usage:       "sends a greeting in english",
+					Description: "greets someone in english",
+					Flags: []cli.Flag{
+						cli.StringFlag{Name: "name", Value: "Bob", Usage: "Name of the person to greet"},
+					},
+					Action: func(c *cli.Context) {
+						println("Hello, ", c.String("name"))
+					},
+				}, {
+					Name:      "spanish",
+					ShortName: "sp",
+					Usage:     "sends a greeting in spanish",
+					Flags: []cli.Flag{
+						cli.StringFlag{Name: "surname", Value: "Jones", Usage: "Surname of the person to greet"},
+					},
+					Action: func(c *cli.Context) {
+						println("Hola, ", c.String("surname"))
+					},
+				}, {
+					Name:      "french",
+					ShortName: "fr",
+					Usage:     "sends a greeting in french",
+					Flags: []cli.Flag{
+						cli.StringFlag{Name: "nickname", Value: "Stevie", Usage: "Nickname of the person to greet"},
+					},
+					Action: func(c *cli.Context) {
+						println("Bonjour, ", c.String("nickname"))
+					},
+				},
+			},
+		}, {
+			Name:  "bye",
+			Usage: "says goodbye",
+			Action: func(c *cli.Context) {
+				println("bye")
+			},
+		},
+	}
+
+	app.Run(os.Args)
+}

+ 141 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command.go

@@ -0,0 +1,141 @@
+package cli
+
+import (
+	"fmt"
+	"io/ioutil"
+	"strings"
+)
+
+// Command is a subcommand for a cli.App.
+type Command struct {
+	// The name of the command
+	Name string
+	// short name of the command. Typically one character
+	ShortName string
+	// A short description of the usage of this command
+	Usage string
+	// A longer explanation of how the command works
+	Description string
+	// The function to call when checking for bash command completions
+	BashComplete func(context *Context)
+	// An action to execute before any sub-subcommands are run, but after the context is ready
+	// If a non-nil error is returned, no sub-subcommands are run
+	Before func(context *Context) error
+	// The function to call when this command is invoked
+	Action func(context *Context)
+	// List of child commands
+	Subcommands []Command
+	// List of flags to parse
+	Flags []Flag
+	// Treat all flags as normal arguments if true
+	SkipFlagParsing bool
+	// Boolean to hide built-in help command
+	HideHelp bool
+}
+
+// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
+func (c Command) Run(ctx *Context) error {
+
+	if len(c.Subcommands) > 0 || c.Before != nil {
+		return c.startApp(ctx)
+	}
+
+	if !c.HideHelp {
+		// append help to flags
+		c.Flags = append(
+			c.Flags,
+			HelpFlag,
+		)
+	}
+
+	if ctx.App.EnableBashCompletion {
+		c.Flags = append(c.Flags, BashCompletionFlag)
+	}
+
+	set := flagSet(c.Name, c.Flags)
+	set.SetOutput(ioutil.Discard)
+
+	firstFlagIndex := -1
+	for index, arg := range ctx.Args() {
+		if strings.HasPrefix(arg, "-") {
+			firstFlagIndex = index
+			break
+		}
+	}
+
+	var err error
+	if firstFlagIndex > -1 && !c.SkipFlagParsing {
+		args := ctx.Args()
+		regularArgs := args[1:firstFlagIndex]
+		flagArgs := args[firstFlagIndex:]
+		err = set.Parse(append(flagArgs, regularArgs...))
+	} else {
+		err = set.Parse(ctx.Args().Tail())
+	}
+
+	if err != nil {
+		fmt.Printf("Incorrect Usage.\n\n")
+		ShowCommandHelp(ctx, c.Name)
+		fmt.Println("")
+		return err
+	}
+
+	nerr := normalizeFlags(c.Flags, set)
+	if nerr != nil {
+		fmt.Println(nerr)
+		fmt.Println("")
+		ShowCommandHelp(ctx, c.Name)
+		fmt.Println("")
+		return nerr
+	}
+	context := NewContext(ctx.App, set, ctx.globalSet)
+
+	if checkCommandCompletions(context, c.Name) {
+		return nil
+	}
+
+	if checkCommandHelp(context, c.Name) {
+		return nil
+	}
+	context.Command = c
+	c.Action(context)
+	return nil
+}
+
+// Returns true if Command.Name or Command.ShortName matches given name
+func (c Command) HasName(name string) bool {
+	return c.Name == name || c.ShortName == name
+}
+
+func (c Command) startApp(ctx *Context) error {
+	app := NewApp()
+
+	// set the name and usage
+	app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
+	if c.Description != "" {
+		app.Usage = c.Description
+	} else {
+		app.Usage = c.Usage
+	}
+
+	// set the flags and commands
+	app.Commands = c.Subcommands
+	app.Flags = c.Flags
+	app.HideHelp = c.HideHelp
+
+	// bash completion
+	app.EnableBashCompletion = ctx.App.EnableBashCompletion
+	if c.BashComplete != nil {
+		app.BashComplete = c.BashComplete
+	}
+
+	// set the actions
+	app.Before = c.Before
+	if c.Action != nil {
+		app.Action = c.Action
+	} else {
+		app.Action = helpSubcommand.Action
+	}
+
+	return app.RunAsSubcommand(ctx)
+}

+ 48 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/command_test.go

@@ -0,0 +1,48 @@
+package cli_test
+
+import (
+	"flag"
+	"github.com/codegangsta/cli"
+	"testing"
+)
+
+func TestCommandDoNotIgnoreFlags(t *testing.T) {
+	app := cli.NewApp()
+	set := flag.NewFlagSet("test", 0)
+	test := []string{"blah", "blah", "-break"}
+	set.Parse(test)
+
+	c := cli.NewContext(app, set, set)
+
+	command := cli.Command {
+		Name: "test-cmd",
+		ShortName: "tc",
+		Usage: "this is for testing",
+		Description: "testing",
+		Action: func(_ *cli.Context) { },
+	}
+	err := command.Run(c)
+
+	expect(t, err.Error(), "flag provided but not defined: -break")
+}
+
+func TestCommandIgnoreFlags(t *testing.T) {
+	app := cli.NewApp()
+	set := flag.NewFlagSet("test", 0)
+	test := []string{"blah", "blah"}
+	set.Parse(test)
+
+	c := cli.NewContext(app, set, set)
+
+	command := cli.Command {
+		Name: "test-cmd",
+		ShortName: "tc",
+		Usage: "this is for testing",
+		Description: "testing",
+		Action: func(_ *cli.Context) { },
+		SkipFlagParsing: true,
+	}
+	err := command.Run(c)
+
+	expect(t, err, nil)
+}

+ 280 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context.go

@@ -0,0 +1,280 @@
+package cli
+
+import (
+	"errors"
+	"flag"
+	"strconv"
+	"strings"
+)
+
+// Context is a type that is passed through to
+// each Handler action in a cli application. Context
+// can be used to retrieve context-specific Args and
+// parsed command-line options.
+type Context struct {
+	App       *App
+	Command   Command
+	flagSet   *flag.FlagSet
+	globalSet *flag.FlagSet
+	setFlags  map[string]bool
+}
+
+// Creates a new context. For use in when invoking an App or Command action.
+func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context {
+	return &Context{App: app, flagSet: set, globalSet: globalSet}
+}
+
+// Looks up the value of a local int flag, returns 0 if no int flag exists
+func (c *Context) Int(name string) int {
+	return lookupInt(name, c.flagSet)
+}
+
+// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
+func (c *Context) Float64(name string) float64 {
+	return lookupFloat64(name, c.flagSet)
+}
+
+// Looks up the value of a local bool flag, returns false if no bool flag exists
+func (c *Context) Bool(name string) bool {
+	return lookupBool(name, c.flagSet)
+}
+
+// Looks up the value of a local boolT flag, returns false if no bool flag exists
+func (c *Context) BoolT(name string) bool {
+	return lookupBoolT(name, c.flagSet)
+}
+
+// Looks up the value of a local string flag, returns "" if no string flag exists
+func (c *Context) String(name string) string {
+	return lookupString(name, c.flagSet)
+}
+
+// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
+func (c *Context) StringSlice(name string) []string {
+	return lookupStringSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
+func (c *Context) IntSlice(name string) []int {
+	return lookupIntSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local generic flag, returns nil if no generic flag exists
+func (c *Context) Generic(name string) interface{} {
+	return lookupGeneric(name, c.flagSet)
+}
+
+// Looks up the value of a global int flag, returns 0 if no int flag exists
+func (c *Context) GlobalInt(name string) int {
+	return lookupInt(name, c.globalSet)
+}
+
+// Looks up the value of a global bool flag, returns false if no bool flag exists
+func (c *Context) GlobalBool(name string) bool {
+	return lookupBool(name, c.globalSet)
+}
+
+// Looks up the value of a global string flag, returns "" if no string flag exists
+func (c *Context) GlobalString(name string) string {
+	return lookupString(name, c.globalSet)
+}
+
+// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
+func (c *Context) GlobalStringSlice(name string) []string {
+	return lookupStringSlice(name, c.globalSet)
+}
+
+// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
+func (c *Context) GlobalIntSlice(name string) []int {
+	return lookupIntSlice(name, c.globalSet)
+}
+
+// Looks up the value of a global generic flag, returns nil if no generic flag exists
+func (c *Context) GlobalGeneric(name string) interface{} {
+	return lookupGeneric(name, c.globalSet)
+}
+
+// Determines if the flag was actually set exists
+func (c *Context) IsSet(name string) bool {
+	if c.setFlags == nil {
+		c.setFlags = make(map[string]bool)
+		c.flagSet.Visit(func(f *flag.Flag) {
+			c.setFlags[f.Name] = true
+		})
+	}
+	return c.setFlags[name] == true
+}
+
+type Args []string
+
+// Returns the command line arguments associated with the context.
+func (c *Context) Args() Args {
+	args := Args(c.flagSet.Args())
+	return args
+}
+
+// Returns the nth argument, or else a blank string
+func (a Args) Get(n int) string {
+	if len(a) > n {
+		return a[n]
+	}
+	return ""
+}
+
+// Returns the first argument, or else a blank string
+func (a Args) First() string {
+	return a.Get(0)
+}
+
+// Return the rest of the arguments (not the first one)
+// or else an empty string slice
+func (a Args) Tail() []string {
+	if len(a) >= 2 {
+		return []string(a)[1:]
+	}
+	return []string{}
+}
+
+// Checks if there are any arguments present
+func (a Args) Present() bool {
+	return len(a) != 0
+}
+
+// Swaps arguments at the given indexes
+func (a Args) Swap(from, to int) error {
+	if from >= len(a) || to >= len(a) {
+		return errors.New("index out of range")
+	}
+	a[from], a[to] = a[to], a[from]
+	return nil
+}
+
+func lookupInt(name string, set *flag.FlagSet) int {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.Atoi(f.Value.String())
+		if err != nil {
+			return 0
+		}
+		return val
+	}
+
+	return 0
+}
+
+func lookupFloat64(name string, set *flag.FlagSet) float64 {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseFloat(f.Value.String(), 64)
+		if err != nil {
+			return 0
+		}
+		return val
+	}
+
+	return 0
+}
+
+func lookupString(name string, set *flag.FlagSet) string {
+	f := set.Lookup(name)
+	if f != nil {
+		return f.Value.String()
+	}
+
+	return ""
+}
+
+func lookupStringSlice(name string, set *flag.FlagSet) []string {
+	f := set.Lookup(name)
+	if f != nil {
+		return (f.Value.(*StringSlice)).Value()
+
+	}
+
+	return nil
+}
+
+func lookupIntSlice(name string, set *flag.FlagSet) []int {
+	f := set.Lookup(name)
+	if f != nil {
+		return (f.Value.(*IntSlice)).Value()
+
+	}
+
+	return nil
+}
+
+func lookupGeneric(name string, set *flag.FlagSet) interface{} {
+	f := set.Lookup(name)
+	if f != nil {
+		return f.Value
+	}
+	return nil
+}
+
+func lookupBool(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return false
+		}
+		return val
+	}
+
+	return false
+}
+
+func lookupBoolT(name string, set *flag.FlagSet) bool {
+	f := set.Lookup(name)
+	if f != nil {
+		val, err := strconv.ParseBool(f.Value.String())
+		if err != nil {
+			return true
+		}
+		return val
+	}
+
+	return false
+}
+
+func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
+	switch ff.Value.(type) {
+	case *StringSlice:
+	default:
+		set.Set(name, ff.Value.String())
+	}
+}
+
+func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
+	visited := make(map[string]bool)
+	set.Visit(func(f *flag.Flag) {
+		visited[f.Name] = true
+	})
+	for _, f := range flags {
+		parts := strings.Split(f.getName(), ",")
+		if len(parts) == 1 {
+			continue
+		}
+		var ff *flag.Flag
+		for _, name := range parts {
+			name = strings.Trim(name, " ")
+			if visited[name] {
+				if ff != nil {
+					return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
+				}
+				ff = set.Lookup(name)
+			}
+		}
+		if ff == nil {
+			continue
+		}
+		for _, name := range parts {
+			name = strings.Trim(name, " ")
+			if !visited[name] {
+				copyFlag(name, ff, set)
+			}
+		}
+	}
+	return nil
+}

+ 68 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/context_test.go

@@ -0,0 +1,68 @@
+package cli_test
+
+import (
+	"flag"
+	"github.com/codegangsta/cli"
+	"testing"
+)
+
+func TestNewContext(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Int("myflag", 12, "doc")
+	globalSet := flag.NewFlagSet("test", 0)
+	globalSet.Int("myflag", 42, "doc")
+	command := cli.Command{Name: "mycommand"}
+	c := cli.NewContext(nil, set, globalSet)
+	c.Command = command
+	expect(t, c.Int("myflag"), 12)
+	expect(t, c.GlobalInt("myflag"), 42)
+	expect(t, c.Command.Name, "mycommand")
+}
+
+func TestContext_Int(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Int("myflag", 12, "doc")
+	c := cli.NewContext(nil, set, set)
+	expect(t, c.Int("myflag"), 12)
+}
+
+func TestContext_String(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.String("myflag", "hello world", "doc")
+	c := cli.NewContext(nil, set, set)
+	expect(t, c.String("myflag"), "hello world")
+}
+
+func TestContext_Bool(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	c := cli.NewContext(nil, set, set)
+	expect(t, c.Bool("myflag"), false)
+}
+
+func TestContext_BoolT(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", true, "doc")
+	c := cli.NewContext(nil, set, set)
+	expect(t, c.BoolT("myflag"), true)
+}
+
+func TestContext_Args(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	c := cli.NewContext(nil, set, set)
+	set.Parse([]string{"--myflag", "bat", "baz"})
+	expect(t, len(c.Args()), 2)
+	expect(t, c.Bool("myflag"), true)
+}
+
+func TestContext_IsSet(t *testing.T) {
+	set := flag.NewFlagSet("test", 0)
+	set.Bool("myflag", false, "doc")
+	set.String("otherflag", "hello world", "doc")
+	c := cli.NewContext(nil, set, set)
+	set.Parse([]string{"--myflag", "bat", "baz"})
+	expect(t, c.IsSet("myflag"), true)
+	expect(t, c.IsSet("otherflag"), false)
+	expect(t, c.IsSet("bogusflag"), false)
+}

+ 280 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag.go

@@ -0,0 +1,280 @@
+package cli
+
+import (
+	"flag"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// This flag enables bash-completion for all commands and subcommands
+var BashCompletionFlag = BoolFlag{"generate-bash-completion", ""}
+
+// This flag prints the version for the application
+var VersionFlag = BoolFlag{"version, v", "print the version"}
+
+// This flag prints the help for all commands and subcommands
+var HelpFlag = BoolFlag{"help, h", "show help"}
+
+// Flag is a common interface related to parsing flags in cli.
+// For more advanced flag parsing techniques, it is recomended that
+// this interface be implemented.
+type Flag interface {
+	fmt.Stringer
+	// Apply Flag settings to the given flag set
+	Apply(*flag.FlagSet)
+	getName() string
+}
+
+func flagSet(name string, flags []Flag) *flag.FlagSet {
+	set := flag.NewFlagSet(name, flag.ContinueOnError)
+
+	for _, f := range flags {
+		f.Apply(set)
+	}
+	return set
+}
+
+func eachName(longName string, fn func(string)) {
+	parts := strings.Split(longName, ",")
+	for _, name := range parts {
+		name = strings.Trim(name, " ")
+		fn(name)
+	}
+}
+
+// Generic is a generic parseable type identified by a specific flag
+type Generic interface {
+	Set(value string) error
+	String() string
+}
+
+// GenericFlag is the flag type for types implementing Generic
+type GenericFlag struct {
+	Name  string
+	Value Generic
+	Usage string
+}
+
+func (f GenericFlag) String() string {
+	return fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
+}
+
+func (f GenericFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f GenericFlag) getName() string {
+	return f.Name
+}
+
+type StringSlice []string
+
+func (f *StringSlice) Set(value string) error {
+	*f = append(*f, value)
+	return nil
+}
+
+func (f *StringSlice) String() string {
+	return fmt.Sprintf("%s", *f)
+}
+
+func (f *StringSlice) Value() []string {
+	return *f
+}
+
+type StringSliceFlag struct {
+	Name  string
+	Value *StringSlice
+	Usage string
+}
+
+func (f StringSliceFlag) String() string {
+	firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+	pref := prefixFor(firstName)
+	return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
+}
+
+func (f StringSliceFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f StringSliceFlag) getName() string {
+	return f.Name
+}
+
+type IntSlice []int
+
+func (f *IntSlice) Set(value string) error {
+
+	tmp, err := strconv.Atoi(value)
+	if err != nil {
+		return err
+	} else {
+		*f = append(*f, tmp)
+	}
+	return nil
+}
+
+func (f *IntSlice) String() string {
+	return fmt.Sprintf("%d", *f)
+}
+
+func (f *IntSlice) Value() []int {
+	return *f
+}
+
+type IntSliceFlag struct {
+	Name  string
+	Value *IntSlice
+	Usage string
+}
+
+func (f IntSliceFlag) String() string {
+	firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+	pref := prefixFor(firstName)
+	return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
+}
+
+func (f IntSliceFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Var(f.Value, name, f.Usage)
+	})
+}
+
+func (f IntSliceFlag) getName() string {
+	return f.Name
+}
+
+type BoolFlag struct {
+	Name  string
+	Usage string
+}
+
+func (f BoolFlag) String() string {
+	return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
+}
+
+func (f BoolFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Bool(name, false, f.Usage)
+	})
+}
+
+func (f BoolFlag) getName() string {
+	return f.Name
+}
+
+type BoolTFlag struct {
+	Name  string
+	Usage string
+}
+
+func (f BoolTFlag) String() string {
+	return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
+}
+
+func (f BoolTFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Bool(name, true, f.Usage)
+	})
+}
+
+func (f BoolTFlag) getName() string {
+	return f.Name
+}
+
+type StringFlag struct {
+	Name  string
+	Value string
+	Usage string
+}
+
+func (f StringFlag) String() string {
+	var fmtString string
+	fmtString = "%s %v\t%v"
+
+	if len(f.Value) > 0 {
+		fmtString = "%s '%v'\t%v"
+	} else {
+		fmtString = "%s %v\t%v"
+	}
+
+	return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f StringFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.String(name, f.Value, f.Usage)
+	})
+}
+
+func (f StringFlag) getName() string {
+	return f.Name
+}
+
+type IntFlag struct {
+	Name  string
+	Value int
+	Usage string
+}
+
+func (f IntFlag) String() string {
+	return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f IntFlag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Int(name, f.Value, f.Usage)
+	})
+}
+
+func (f IntFlag) getName() string {
+	return f.Name
+}
+
+type Float64Flag struct {
+	Name  string
+	Value float64
+	Usage string
+}
+
+func (f Float64Flag) String() string {
+	return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f Float64Flag) Apply(set *flag.FlagSet) {
+	eachName(f.Name, func(name string) {
+		set.Float64(name, f.Value, f.Usage)
+	})
+}
+
+func (f Float64Flag) getName() string {
+	return f.Name
+}
+
+func prefixFor(name string) (prefix string) {
+	if len(name) == 1 {
+		prefix = "-"
+	} else {
+		prefix = "--"
+	}
+
+	return
+}
+
+func prefixedNames(fullName string) (prefixed string) {
+	parts := strings.Split(fullName, ",")
+	for i, name := range parts {
+		name = strings.Trim(name, " ")
+		prefixed += prefixFor(name) + name
+		if i < len(parts)-1 {
+			prefixed += ", "
+		}
+	}
+	return
+}

+ 194 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/flag_test.go

@@ -0,0 +1,194 @@
+package cli_test
+
+import (
+	"github.com/codegangsta/cli"
+
+	"fmt"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var boolFlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help\t"},
+	{"h", "-h\t"},
+}
+
+func TestBoolFlagHelpOutput(t *testing.T) {
+
+	for _, test := range boolFlagTests {
+		flag := cli.BoolFlag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+var stringFlagTests = []struct {
+	name     string
+	value    string
+	expected string
+}{
+	{"help", "", "--help \t"},
+	{"h", "", "-h \t"},
+	{"h", "", "-h \t"},
+	{"test", "Something", "--test 'Something'\t"},
+}
+
+func TestStringFlagHelpOutput(t *testing.T) {
+
+	for _, test := range stringFlagTests {
+		flag := cli.StringFlag{Name: test.name, Value: test.value}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+var intFlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help '0'\t"},
+	{"h", "-h '0'\t"},
+}
+
+func TestIntFlagHelpOutput(t *testing.T) {
+
+	for _, test := range intFlagTests {
+		flag := cli.IntFlag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+var float64FlagTests = []struct {
+	name     string
+	expected string
+}{
+	{"help", "--help '0'\t"},
+	{"h", "-h '0'\t"},
+}
+
+func TestFloat64FlagHelpOutput(t *testing.T) {
+
+	for _, test := range float64FlagTests {
+		flag := cli.Float64Flag{Name: test.name}
+		output := flag.String()
+
+		if output != test.expected {
+			t.Errorf("%s does not match %s", output, test.expected)
+		}
+	}
+}
+
+func TestParseMultiString(t *testing.T) {
+	(&cli.App{
+		Flags: []cli.Flag{
+			cli.StringFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *cli.Context) {
+			if ctx.String("serve") != "10" {
+				t.Errorf("main name not set")
+			}
+			if ctx.String("s") != "10" {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run", "-s", "10"})
+}
+
+func TestParseMultiStringSlice(t *testing.T) {
+	(&cli.App{
+		Flags: []cli.Flag{
+			cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}},
+		},
+		Action: func(ctx *cli.Context) {
+			if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
+				t.Errorf("main name not set")
+			}
+			if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
+				t.Errorf("short name not set")
+			}
+		},
+	}).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiInt(t *testing.T) {
+	a := cli.App{
+		Flags: []cli.Flag{
+			cli.IntFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *cli.Context) {
+			if ctx.Int("serve") != 10 {
+				t.Errorf("main name not set")
+			}
+			if ctx.Int("s") != 10 {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "-s", "10"})
+}
+
+func TestParseMultiBool(t *testing.T) {
+	a := cli.App{
+		Flags: []cli.Flag{
+			cli.BoolFlag{Name: "serve, s"},
+		},
+		Action: func(ctx *cli.Context) {
+			if ctx.Bool("serve") != true {
+				t.Errorf("main name not set")
+			}
+			if ctx.Bool("s") != true {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "--serve"})
+}
+
+type Parser [2]string
+
+func (p *Parser) Set(value string) error {
+	parts := strings.Split(value, ",")
+	if len(parts) != 2 {
+		return fmt.Errorf("invalid format")
+	}
+
+	(*p)[0] = parts[0]
+	(*p)[1] = parts[1]
+
+	return nil
+}
+
+func (p *Parser) String() string {
+	return fmt.Sprintf("%s,%s", p[0], p[1])
+}
+
+func TestParseGeneric(t *testing.T) {
+	a := cli.App{
+		Flags: []cli.Flag{
+			cli.GenericFlag{Name: "serve, s", Value: &Parser{}},
+		},
+		Action: func(ctx *cli.Context) {
+			if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
+				t.Errorf("main name not set")
+			}
+			if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
+				t.Errorf("short name not set")
+			}
+		},
+	}
+	a.Run([]string{"run", "-s", "10,20"})
+}

+ 213 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/help.go

@@ -0,0 +1,213 @@
+package cli
+
+import (
+	"fmt"
+	"os"
+	"text/tabwriter"
+	"text/template"
+)
+
+// The text template for the Default help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var AppHelpTemplate = `NAME:
+   {{.Name}} - {{.Usage}}
+
+USAGE:
+   {{.Name}} {{ if .Flags }}[global options] {{ end }}command{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+VERSION:
+   {{.Version}}
+
+COMMANDS:
+   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+   {{end}}{{ if .Flags }}
+GLOBAL OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{ end }}
+`
+
+// The text template for the command help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var CommandHelpTemplate = `NAME:
+   {{.Name}} - {{.Usage}}
+
+USAGE:
+   command {{.Name}}{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+DESCRIPTION:
+   {{.Description}}{{ if .Flags }}
+
+OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{ end }}
+`
+
+// The text template for the subcommand help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var SubcommandHelpTemplate = `NAME:
+   {{.Name}} - {{.Usage}}
+
+USAGE:
+   {{.Name}} command{{ if .Flags }} [command options]{{ end }} [arguments...]
+
+COMMANDS:
+   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+   {{end}}{{ if .Flags }}
+OPTIONS:
+   {{range .Flags}}{{.}}
+   {{end}}{{ end }}
+`
+
+var helpCommand = Command{
+	Name:      "help",
+	ShortName: "h",
+	Usage:     "Shows a list of commands or help for one command",
+	Action: func(c *Context) {
+		args := c.Args()
+		if args.Present() {
+			ShowCommandHelp(c, args.First())
+		} else {
+			ShowAppHelp(c)
+		}
+	},
+}
+
+var helpSubcommand = Command{
+	Name:      "help",
+	ShortName: "h",
+	Usage:     "Shows a list of commands or help for one command",
+	Action: func(c *Context) {
+		args := c.Args()
+		if args.Present() {
+			ShowCommandHelp(c, args.First())
+		} else {
+			ShowSubcommandHelp(c)
+		}
+	},
+}
+
+// Prints help for the App
+var HelpPrinter = printHelp
+
+func ShowAppHelp(c *Context) {
+	HelpPrinter(AppHelpTemplate, c.App)
+}
+
+// Prints the list of subcommands as the default app completion method
+func DefaultAppComplete(c *Context) {
+	for _, command := range c.App.Commands {
+		fmt.Println(command.Name)
+		if command.ShortName != "" {
+			fmt.Println(command.ShortName)
+		}
+	}
+}
+
+// Prints help for the given command
+func ShowCommandHelp(c *Context, command string) {
+	for _, c := range c.App.Commands {
+		if c.HasName(command) {
+			HelpPrinter(CommandHelpTemplate, c)
+			return
+		}
+	}
+
+	if c.App.CommandNotFound != nil {
+		c.App.CommandNotFound(c, command)
+	} else {
+		fmt.Printf("No help topic for '%v'\n", command)
+	}
+}
+
+// Prints help for the given subcommand
+func ShowSubcommandHelp(c *Context) {
+	HelpPrinter(SubcommandHelpTemplate, c.App)
+}
+
+// Prints the version number of the App
+func ShowVersion(c *Context) {
+	fmt.Printf("%v version %v\n", c.App.Name, c.App.Version)
+}
+
+// Prints the lists of commands within a given context
+func ShowCompletions(c *Context) {
+	a := c.App
+	if a != nil && a.BashComplete != nil {
+		a.BashComplete(c)
+	}
+}
+
+// Prints the custom completions for a given command
+func ShowCommandCompletions(ctx *Context, command string) {
+	c := ctx.App.Command(command)
+	if c != nil && c.BashComplete != nil {
+		c.BashComplete(ctx)
+	}
+}
+
+func printHelp(templ string, data interface{}) {
+	w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
+	t := template.Must(template.New("help").Parse(templ))
+	err := t.Execute(w, data)
+	if err != nil {
+		panic(err)
+	}
+	w.Flush()
+}
+
+func checkVersion(c *Context) bool {
+	if c.GlobalBool("version") {
+		ShowVersion(c)
+		return true
+	}
+
+	return false
+}
+
+func checkHelp(c *Context) bool {
+	if c.GlobalBool("h") || c.GlobalBool("help") {
+		ShowAppHelp(c)
+		return true
+	}
+
+	return false
+}
+
+func checkCommandHelp(c *Context, name string) bool {
+	if c.Bool("h") || c.Bool("help") {
+		ShowCommandHelp(c, name)
+		return true
+	}
+
+	return false
+}
+
+func checkSubcommandHelp(c *Context) bool {
+	if c.GlobalBool("h") || c.GlobalBool("help") {
+		ShowSubcommandHelp(c)
+		return true
+	}
+
+	return false
+}
+
+func checkCompletions(c *Context) bool {
+	if c.GlobalBool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
+		ShowCompletions(c)
+		return true
+	}
+
+	return false
+}
+
+func checkCommandCompletions(c *Context, name string) bool {
+	if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
+		ShowCommandCompletions(c, name)
+		return true
+	}
+
+	return false
+}

+ 19 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/codegangsta/cli/helpers_test.go

@@ -0,0 +1,19 @@
+package cli_test
+
+import (
+	"reflect"
+	"testing"
+)
+
+/* Test Helpers */
+func expect(t *testing.T, a interface{}, b interface{}) {
+	if a != b {
+		t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+	}
+}
+
+func refute(t *testing.T, a interface{}, b interface{}) {
+	if a == b {
+		t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+	}
+}

+ 8 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/.travis.yml

@@ -0,0 +1,8 @@
+language: go
+go: 1.2
+
+install:
+ - echo "Skip install"
+
+script:
+ - ./test

+ 191 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/LICENSE

@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 44 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/README.md

@@ -0,0 +1,44 @@
+# go-systemd
+
+Go bindings to systemd. The project has three packages:
+
+- activation - for writing and using socket activation from Go
+- journal - for writing to systemd's logging service, journal
+- dbus - for starting/stopping/inspecting running services and units
+
+Go docs for the entire project are here:
+
+http://godoc.org/github.com/coreos/go-systemd
+
+## Socket Activation
+
+An example HTTP server using socket activation can be quickly setup by
+following this README on a Linux machine running systemd:
+
+https://github.com/coreos/go-systemd/tree/master/examples/activation/httpserver
+
+## Journal
+
+Using this package you can submit journal entries directly to systemd's journal taking advantage of features like indexed key/value pairs for each log entry.
+
+## D-Bus
+
+The D-Bus API lets you start, stop and introspect systemd units. The API docs are here:
+
+http://godoc.org/github.com/coreos/go-systemd/dbus
+
+### Debugging
+
+Create `/etc/dbus-1/system-local.conf` that looks like this:
+
+```
+<!DOCTYPE busconfig PUBLIC
+"-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+    <policy user="root">
+        <allow eavesdrop="true"/>
+        <allow eavesdrop="true" send_destination="*"/>
+    </policy>
+</busconfig>
+```

+ 56 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files.go

@@ -0,0 +1,56 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package activation implements primitives for systemd socket activation.
+package activation
+
+import (
+	"os"
+	"strconv"
+	"syscall"
+)
+
+// based on: https://gist.github.com/alberts/4640792
+const (
+	listenFdsStart = 3
+)
+
+func Files(unsetEnv bool) []*os.File {
+	if unsetEnv {
+		// there is no way to unset env in golang os package for now
+		// https://code.google.com/p/go/issues/detail?id=6423
+		defer os.Setenv("LISTEN_PID", "")
+		defer os.Setenv("LISTEN_FDS", "")
+	}
+
+	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 == 0 {
+		return nil
+	}
+
+	var files []*os.File
+	for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
+		syscall.CloseOnExec(fd)
+		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
+	}
+
+	return files
+}

+ 84 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/files_test.go

@@ -0,0 +1,84 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package activation
+
+import (
+	"bytes"
+	"io"
+	"os"
+	"os/exec"
+	"testing"
+)
+
+// correctStringWritten fails the text if the correct string wasn't written
+// to the other side of the pipe.
+func correctStringWritten(t *testing.T, r *os.File, expected string) bool {
+	bytes := make([]byte, len(expected))
+	io.ReadAtLeast(r, bytes, len(expected))
+
+	if string(bytes) != expected {
+		t.Fatalf("Unexpected string %s", string(bytes))
+	}
+
+	return true
+}
+
+// TestActivation forks out a copy of activation.go example and reads back two
+// strings from the pipes that are passed in.
+func TestActivation(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+
+	r1, w1, _ := os.Pipe()
+	r2, w2, _ := os.Pipe()
+	cmd.ExtraFiles = []*os.File{
+		w1,
+		w2,
+	}
+
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
+
+	err := cmd.Run()
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	correctStringWritten(t, r1, "Hello world")
+	correctStringWritten(t, r2, "Goodbye world")
+}
+
+func TestActivationNoFix(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=2")
+
+	out, _ := cmd.CombinedOutput()
+	if bytes.Contains(out, []byte("No files")) == false {
+		t.Fatalf("Child didn't error out as expected")
+	}
+}
+
+func TestActivationNoFiles(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1")
+
+	out, _ := cmd.CombinedOutput()
+	if bytes.Contains(out, []byte("No files")) == false {
+		t.Fatalf("Child didn't error out as expected")
+	}
+}

+ 38 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners.go

@@ -0,0 +1,38 @@
+/*
+Copyright 2014 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package activation
+
+import (
+	"fmt"
+	"net"
+)
+
+// Listeners returns net.Listeners for all socket activated fds passed to this process.
+func Listeners(unsetEnv bool) ([]net.Listener, error) {
+	files := Files(unsetEnv)
+	listeners := make([]net.Listener, len(files))
+
+	for i, f := range files {
+		var err error
+		listeners[i], err = net.FileListener(f)
+		if err != nil {
+			return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error())
+		}
+	}
+
+	return listeners, nil
+}

+ 88 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go

@@ -0,0 +1,88 @@
+/*
+Copyright 2014 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package activation
+
+import (
+	"io"
+	"net"
+	"os"
+	"os/exec"
+	"testing"
+)
+
+// correctStringWritten fails the text if the correct string wasn't written
+// to the other side of the pipe.
+func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool {
+	bytes := make([]byte, len(expected))
+	io.ReadAtLeast(r, bytes, len(expected))
+
+	if string(bytes) != expected {
+		t.Fatalf("Unexpected string %s", string(bytes))
+	}
+
+	return true
+}
+
+// TestActivation forks out a copy of activation.go example and reads back two
+// strings from the pipes that are passed in.
+func TestListeners(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/listen.go")
+
+	l1, err := net.Listen("tcp", ":9999")
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+	l2, err := net.Listen("tcp", ":1234")
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	t1 := l1.(*net.TCPListener)
+	t2 := l2.(*net.TCPListener)
+
+	f1, _ := t1.File()
+	f2, _  := t2.File()
+
+	cmd.ExtraFiles = []*os.File{
+		f1,
+		f2,
+	}
+
+	r1, err := net.Dial("tcp", "127.0.0.1:9999")
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+	r1.Write([]byte("Hi"))
+
+	r2, err := net.Dial("tcp", "127.0.0.1:1234")
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+	r2.Write([]byte("Hi"))
+
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
+
+	out, err := cmd.Output()
+	if err != nil {
+		println(string(out))
+		t.Fatalf(err.Error())
+	}
+
+	correctStringWrittenNet(t, r1, "Hello world")
+	correctStringWrittenNet(t, r2, "Goodbye world")
+}

+ 104 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus.go

@@ -0,0 +1,104 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Integration with the systemd D-Bus API.  See http://www.freedesktop.org/wiki/Software/systemd/dbus/
+package dbus
+
+import (
+	"os"
+	"strconv"
+	"strings"
+	"sync"
+
+	"github.com/godbus/dbus"
+)
+
+const signalBuffer = 100
+
+// ObjectPath creates a dbus.ObjectPath using the rules that systemd uses for
+// serializing special characters.
+func ObjectPath(path string) dbus.ObjectPath {
+	path = strings.Replace(path, ".", "_2e", -1)
+	path = strings.Replace(path, "-", "_2d", -1)
+	path = strings.Replace(path, "@", "_40", -1)
+
+	return dbus.ObjectPath(path)
+}
+
+// Conn is a connection to systemds dbus endpoint.
+type Conn struct {
+	sysconn     *dbus.Conn
+	sysobj      *dbus.Object
+	jobListener struct {
+		jobs map[dbus.ObjectPath]chan string
+		sync.Mutex
+	}
+	subscriber struct {
+		updateCh chan<- *SubStateUpdate
+		errCh    chan<- error
+		sync.Mutex
+		ignore      map[dbus.ObjectPath]int64
+		cleanIgnore int64
+	}
+	dispatch map[string]func(dbus.Signal)
+}
+
+// New() establishes a connection to the system bus and authenticates.
+func New() (*Conn, error) {
+	c := new(Conn)
+
+	if err := c.initConnection(); err != nil {
+		return nil, err
+	}
+
+	c.initJobs()
+	return c, nil
+}
+
+func (c *Conn) initConnection() error {
+	var err error
+	c.sysconn, err = dbus.SystemBusPrivate()
+	if err != nil {
+		return err
+	}
+
+	// Only use EXTERNAL method, and hardcode the uid (not username)
+	// to avoid a username lookup (which requires a dynamically linked
+	// libc)
+	methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
+
+	err = c.sysconn.Auth(methods)
+	if err != nil {
+		c.sysconn.Close()
+		return err
+	}
+
+	err = c.sysconn.Hello()
+	if err != nil {
+		c.sysconn.Close()
+		return err
+	}
+
+	c.sysobj = c.sysconn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1"))
+
+	// Setup the listeners on jobs so that we can get completions
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'")
+	c.initSubscription()
+	c.initDispatch()
+
+	return nil
+}

+ 41 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/dbus_test.go

@@ -0,0 +1,41 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package dbus
+
+import (
+	"testing"
+)
+
+// TestObjectPath ensures path encoding of the systemd rules works.
+func TestObjectPath(t *testing.T) {
+	input := "/silly-path/to@a/unit..service"
+	output := ObjectPath(input)
+	expected := "/silly_2dpath/to_40a/unit_2e_2eservice"
+
+	if string(output) != expected {
+		t.Fatalf("Output '%s' did not match expected '%s'", output, expected)
+	}
+}
+
+// TestNew ensures that New() works without errors.
+func TestNew(t *testing.T) {
+	_, err := New()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+}

+ 396 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods.go

@@ -0,0 +1,396 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package dbus
+
+import (
+	"errors"
+	"github.com/godbus/dbus"
+)
+
+func (c *Conn) initJobs() {
+	c.jobListener.jobs = make(map[dbus.ObjectPath]chan string)
+}
+
+func (c *Conn) jobComplete(signal *dbus.Signal) {
+	var id uint32
+	var job dbus.ObjectPath
+	var unit string
+	var result string
+	dbus.Store(signal.Body, &id, &job, &unit, &result)
+	c.jobListener.Lock()
+	out, ok := c.jobListener.jobs[job]
+	if ok {
+		out <- result
+		delete(c.jobListener.jobs, job)
+	}
+	c.jobListener.Unlock()
+}
+
+func (c *Conn) startJob(job string, args ...interface{}) (<-chan string, error) {
+	c.jobListener.Lock()
+	defer c.jobListener.Unlock()
+
+	ch := make(chan string, 1)
+	var path dbus.ObjectPath
+	err := c.sysobj.Call(job, 0, args...).Store(&path)
+	if err != nil {
+		return nil, err
+	}
+	c.jobListener.jobs[path] = ch
+	return ch, nil
+}
+
+func (c *Conn) runJob(job string, args ...interface{}) (string, error) {
+	respCh, err := c.startJob(job, args...)
+	if err != nil {
+		return "", err
+	}
+	return <-respCh, nil
+}
+
+// StartUnit enqeues a start job and depending jobs, if any (unless otherwise
+// specified by the mode string).
+//
+// Takes the unit to activate, plus a mode string. The mode needs to be one of
+// replace, fail, isolate, ignore-dependencies, ignore-requirements. If
+// "replace" the call will start the unit and its dependencies, possibly
+// replacing already queued jobs that conflict with this. If "fail" the call
+// will start the unit and its dependencies, but will fail if this would change
+// an already queued job. If "isolate" the call will start the unit in question
+// and terminate all units that aren't dependencies of it. If
+// "ignore-dependencies" it will start a unit but ignore all its dependencies.
+// If "ignore-requirements" it will start a unit but only ignore the
+// requirement dependencies. It is not recommended to make use of the latter
+// two options.
+//
+// Result string: one of done, canceled, timeout, failed, dependency, skipped.
+// done indicates successful execution of a job. canceled indicates that a job
+// has been canceled  before it finished execution. timeout indicates that the
+// job timeout was reached. failed indicates that the job failed. dependency
+// indicates that a job this job has been depending on failed and the job hence
+// has been removed too. skipped indicates that a job was skipped because it
+// didn't apply to the units current state.
+func (c *Conn) StartUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.StartUnit", name, mode)
+}
+
+// StopUnit is similar to StartUnit but stops the specified unit rather
+// than starting it.
+func (c *Conn) StopUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.StopUnit", name, mode)
+}
+
+// ReloadUnit reloads a unit.  Reloading is done only if the unit is already running and fails otherwise.
+func (c *Conn) ReloadUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
+}
+
+// RestartUnit restarts a service.  If a service is restarted that isn't
+// running it will be started.
+func (c *Conn) RestartUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
+}
+
+// TryRestartUnit is like RestartUnit, except that a service that isn't running
+// is not affected by the restart.
+func (c *Conn) TryRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
+}
+
+// ReloadOrRestart attempts a reload if the unit supports it and use a restart
+// otherwise.
+func (c *Conn) ReloadOrRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
+}
+
+// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try"
+// flavored restart otherwise.
+func (c *Conn) ReloadOrTryRestartUnit(name string, mode string) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
+}
+
+// StartTransientUnit() may be used to create and start a transient unit, which
+// will be released as soon as it is not running or referenced anymore or the
+// system is rebooted. name is the unit name including suffix, and must be
+// unique. mode is the same as in StartUnit(), properties contains properties
+// of the unit.
+func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) {
+	return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
+}
+
+// KillUnit takes the unit name and a UNIX signal number to send.  All of the unit's
+// processes are killed.
+func (c *Conn) KillUnit(name string, signal int32) {
+	c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store()
+}
+
+// getProperties takes the unit name and returns all of its dbus object properties, for the given dbus interface
+func (c *Conn) getProperties(unit string, dbusInterface string) (map[string]interface{}, error) {
+	var err error
+	var props map[string]dbus.Variant
+
+	path := ObjectPath("/org/freedesktop/systemd1/unit/" + unit)
+	if !path.IsValid() {
+		return nil, errors.New("invalid unit name: " + unit)
+	}
+
+	obj := c.sysconn.Object("org.freedesktop.systemd1", path)
+	err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
+	if err != nil {
+		return nil, err
+	}
+
+	out := make(map[string]interface{}, len(props))
+	for k, v := range props {
+		out[k] = v.Value()
+	}
+
+	return out, nil
+}
+
+// GetUnitProperties takes the unit name and returns all of its dbus object properties.
+func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) {
+	return c.getProperties(unit, "org.freedesktop.systemd1.Unit")
+}
+
+func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) {
+	var err error
+	var prop dbus.Variant
+
+	path := ObjectPath("/org/freedesktop/systemd1/unit/" + unit)
+	if !path.IsValid() {
+		return nil, errors.New("invalid unit name: " + unit)
+	}
+
+	obj := c.sysconn.Object("org.freedesktop.systemd1", path)
+	err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Property{Name: propertyName, Value: prop}, nil
+}
+
+func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) {
+	return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName)
+}
+
+// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type.
+// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope
+// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit
+func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) {
+	return c.getProperties(unit, "org.freedesktop.systemd1."+unitType)
+}
+
+// SetUnitProperties() may be used to modify certain unit properties at runtime.
+// Not all properties may be changed at runtime, but many resource management
+// settings (primarily those in systemd.cgroup(5)) may. The changes are applied
+// instantly, and stored on disk for future boots, unless runtime is true, in which
+// case the settings only apply until the next reboot. name is the name of the unit
+// to modify. properties are the settings to set, encoded as an array of property
+// name and value pairs.
+func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error {
+	return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
+}
+
+func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
+	return c.getProperty(unit, "org.freedesktop.systemd1." + unitType, propertyName)
+}
+
+// ListUnits returns an array with all currently loaded units. Note that
+// units may be known by multiple names at the same time, and hence there might
+// be more unit names loaded than actual units behind them.
+func (c *Conn) ListUnits() ([]UnitStatus, error) {
+	result := make([][]interface{}, 0)
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store(&result)
+	if err != nil {
+		return nil, err
+	}
+
+	resultInterface := make([]interface{}, len(result))
+	for i := range result {
+		resultInterface[i] = result[i]
+	}
+
+	status := make([]UnitStatus, len(result))
+	statusInterface := make([]interface{}, len(status))
+	for i := range status {
+		statusInterface[i] = &status[i]
+	}
+
+	err = dbus.Store(resultInterface, statusInterface...)
+	if err != nil {
+		return nil, err
+	}
+
+	return status, nil
+}
+
+type UnitStatus struct {
+	Name        string          // The primary unit name as string
+	Description string          // The human readable description string
+	LoadState   string          // The load state (i.e. whether the unit file has been loaded successfully)
+	ActiveState string          // The active state (i.e. whether the unit is currently started or not)
+	SubState    string          // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not)
+	Followed    string          // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string.
+	Path        dbus.ObjectPath // The unit object path
+	JobId       uint32          // If there is a job queued for the job unit the numeric job id, 0 otherwise
+	JobType     string          // The job type as string
+	JobPath     dbus.ObjectPath // The job object path
+}
+
+type LinkUnitFileChange EnableUnitFileChange
+
+// LinkUnitFiles() links unit files (that are located outside of the
+// usual unit search paths) into the unit search path.
+//
+// It takes a list of absolute paths to unit files to link and two
+// booleans. The first boolean controls whether the unit shall be
+// enabled for runtime only (true, /run), or persistently (false,
+// /etc).
+// The second controls whether symlinks pointing to other units shall
+// be replaced if necessary.
+//
+// This call returns a list of the changes made. The list consists of
+// structures with three strings: the type of the change (one of symlink
+// or unlink), the file name of the symlink and the destination of the
+// symlink.
+func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
+	result := make([][]interface{}, 0)
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
+	if err != nil {
+		return nil, err
+	}
+
+	resultInterface := make([]interface{}, len(result))
+	for i := range result {
+		resultInterface[i] = result[i]
+	}
+
+	changes := make([]LinkUnitFileChange, len(result))
+	changesInterface := make([]interface{}, len(changes))
+	for i := range changes {
+		changesInterface[i] = &changes[i]
+	}
+
+	err = dbus.Store(resultInterface, changesInterface...)
+	if err != nil {
+		return nil, err
+	}
+
+	return changes, nil
+}
+
+// EnableUnitFiles() may be used to enable one or more units in the system (by
+// creating symlinks to them in /etc or /run).
+//
+// It takes a list of unit files to enable (either just file names or full
+// absolute paths if the unit files are residing outside the usual unit
+// search paths), and two booleans: the first controls whether the unit shall
+// be enabled for runtime only (true, /run), or persistently (false, /etc).
+// The second one controls whether symlinks pointing to other units shall
+// be replaced if necessary.
+//
+// This call returns one boolean and an array with the changes made. The
+// boolean signals whether the unit files contained any enablement
+// information (i.e. an [Install]) section. The changes list consists of
+// structures with three strings: the type of the change (one of symlink
+// or unlink), the file name of the symlink and the destination of the
+// symlink.
+func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
+	var carries_install_info bool
+
+	result := make([][]interface{}, 0)
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resultInterface := make([]interface{}, len(result))
+	for i := range result {
+		resultInterface[i] = result[i]
+	}
+
+	changes := make([]EnableUnitFileChange, len(result))
+	changesInterface := make([]interface{}, len(changes))
+	for i := range changes {
+		changesInterface[i] = &changes[i]
+	}
+
+	err = dbus.Store(resultInterface, changesInterface...)
+	if err != nil {
+		return false, nil, err
+	}
+
+	return carries_install_info, changes, nil
+}
+
+type EnableUnitFileChange struct {
+	Type        string // Type of the change (one of symlink or unlink)
+	Filename    string // File name of the symlink
+	Destination string // Destination of the symlink
+}
+
+// DisableUnitFiles() may be used to disable one or more units in the system (by
+// removing symlinks to them from /etc or /run).
+//
+// It takes a list of unit files to disable (either just file names or full
+// absolute paths if the unit files are residing outside the usual unit
+// search paths), and one boolean: whether the unit was enabled for runtime
+// only (true, /run), or persistently (false, /etc).
+//
+// This call returns an array with the changes made. The changes list
+// consists of structures with three strings: the type of the change (one of
+// symlink or unlink), the file name of the symlink and the destination of the
+// symlink.
+func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) {
+	result := make([][]interface{}, 0)
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
+	if err != nil {
+		return nil, err
+	}
+
+	resultInterface := make([]interface{}, len(result))
+	for i := range result {
+		resultInterface[i] = result[i]
+	}
+
+	changes := make([]DisableUnitFileChange, len(result))
+	changesInterface := make([]interface{}, len(changes))
+	for i := range changes {
+		changesInterface[i] = &changes[i]
+	}
+
+	err = dbus.Store(resultInterface, changesInterface...)
+	if err != nil {
+		return nil, err
+	}
+
+	return changes, nil
+}
+
+type DisableUnitFileChange struct {
+	Type        string // Type of the change (one of symlink or unlink)
+	Filename    string // File name of the symlink
+	Destination string // Destination of the symlink
+}
+
+// Reload instructs systemd to scan for and reload unit files. This is
+// equivalent to a 'systemctl daemon-reload'.
+func (c *Conn) Reload() error {
+	return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store()
+}

+ 332 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/methods_test.go

@@ -0,0 +1,332 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package dbus
+
+import (
+	"fmt"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"reflect"
+	"testing"
+
+	"github.com/godbus/dbus"
+)
+
+func setupConn(t *testing.T) *Conn {
+	conn, err := New()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	return conn
+}
+
+func findFixture(target string, t *testing.T) string {
+	abs, err := filepath.Abs("../fixtures/" + target)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return abs
+}
+
+func setupUnit(target string, conn *Conn, t *testing.T) {
+	// Blindly stop the unit in case it is running
+	conn.StopUnit(target, "replace")
+
+	// Blindly remove the symlink in case it exists
+	targetRun := filepath.Join("/run/systemd/system/", target)
+	os.Remove(targetRun)
+}
+
+func linkUnit(target string, conn *Conn, t *testing.T) {
+	abs := findFixture(target, t)
+	fixture := []string{abs}
+
+	changes, err := conn.LinkUnitFiles(fixture, true, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(changes) < 1 {
+		t.Fatalf("Expected one change, got %v", changes)
+	}
+
+	runPath := filepath.Join("/run/systemd/system/", target)
+	if changes[0].Filename != runPath {
+		t.Fatal("Unexpected target filename")
+	}
+}
+
+// Ensure that basic unit starting and stopping works.
+func TestStartStopUnit(t *testing.T) {
+	target := "start-stop.service"
+	conn := setupConn(t)
+
+	setupUnit(target, conn, t)
+	linkUnit(target, conn, t)
+
+	// 2. Start the unit
+	job, err := conn.StartUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if job != "done" {
+		t.Fatal("Job is not done:", job)
+	}
+
+	units, err := conn.ListUnits()
+
+	var unit *UnitStatus
+	for _, u := range units {
+		if u.Name == target {
+			unit = &u
+		}
+	}
+
+	if unit == nil {
+		t.Fatalf("Test unit not found in list")
+	}
+
+	if unit.ActiveState != "active" {
+		t.Fatalf("Test unit not active")
+	}
+
+	// 3. Stop the unit
+	job, err = conn.StopUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	units, err = conn.ListUnits()
+
+	unit = nil
+	for _, u := range units {
+		if u.Name == target {
+			unit = &u
+		}
+	}
+
+	if unit != nil {
+		t.Fatalf("Test unit found in list, should be stopped")
+	}
+}
+
+// Enables a unit and then immediately tears it down
+func TestEnableDisableUnit(t *testing.T) {
+	target := "enable-disable.service"
+	conn := setupConn(t)
+
+	setupUnit(target, conn, t)
+	abs := findFixture(target, t)
+	runPath := filepath.Join("/run/systemd/system/", target)
+
+	// 1. Enable the unit
+	install, changes, err := conn.EnableUnitFiles([]string{abs}, true, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if install != false {
+		t.Fatal("Install was true")
+	}
+
+	if len(changes) < 1 {
+		t.Fatalf("Expected one change, got %v", changes)
+	}
+
+	if changes[0].Filename != runPath {
+		t.Fatal("Unexpected target filename")
+	}
+
+	// 2. Disable the unit
+	dChanges, err := conn.DisableUnitFiles([]string{abs}, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(dChanges) != 1 {
+		t.Fatalf("Changes should include the path, %v", dChanges)
+	}
+	if dChanges[0].Filename != runPath {
+		t.Fatalf("Change should include correct filename, %+v", dChanges[0])
+	}
+	if dChanges[0].Destination != "" {
+		t.Fatalf("Change destination should be empty, %+v", dChanges[0])
+	}
+}
+
+// TestGetUnitProperties reads the `-.mount` which should exist on all systemd
+// systems and ensures that one of its properties is valid.
+func TestGetUnitProperties(t *testing.T) {
+	conn := setupConn(t)
+
+	unit := "-.mount"
+
+	info, err := conn.GetUnitProperties(unit)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	names := info["Wants"].([]string)
+
+	if len(names) < 1 {
+		t.Fatal("/ is unwanted")
+	}
+
+	if names[0] != "system.slice" {
+		t.Fatal("unexpected wants for /")
+	}
+
+	prop, err := conn.GetUnitProperty(unit, "Wants")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if prop.Name != "Wants" {
+		t.Fatal("unexpected property name")
+	}
+
+	val := prop.Value.Value().([]string)
+	if !reflect.DeepEqual(val, names) {
+		t.Fatal("unexpected property value")
+	}
+}
+
+// TestGetUnitPropertiesRejectsInvalidName attempts to get the properties for a
+// unit with an invalid name. This test should be run with --test.timeout set,
+// as a fail will manifest as GetUnitProperties hanging indefinitely.
+func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) {
+	conn := setupConn(t)
+
+	unit := "//invalid#$^/"
+
+	_, err := conn.GetUnitProperties(unit)
+	if err == nil {
+		t.Fatal("Expected an error, got nil")
+	}
+
+	_, err = conn.GetUnitProperty(unit, "Wants")
+	if err == nil {
+		t.Fatal("Expected an error, got nil")
+	}
+}
+
+// TestSetUnitProperties changes a cgroup setting on the `tmp.mount`
+// which should exist on all systemd systems and ensures that the
+// property was set.
+func TestSetUnitProperties(t *testing.T) {
+	conn := setupConn(t)
+
+	unit := "tmp.mount"
+
+	if err := conn.SetUnitProperties(unit, true, Property{"CPUShares", dbus.MakeVariant(uint64(1023))}); err != nil {
+		t.Fatal(err)
+	}
+
+	info, err := conn.GetUnitTypeProperties(unit, "Mount")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	value := info["CPUShares"].(uint64)
+	if value != 1023 {
+		t.Fatal("CPUShares of unit is not 1023:", value)
+	}
+}
+
+// Ensure that basic transient unit starting and stopping works.
+func TestStartStopTransientUnit(t *testing.T) {
+	conn := setupConn(t)
+
+	props := []Property{
+		PropExecStart([]string{"/bin/sleep", "400"}, false),
+	}
+	target := fmt.Sprintf("testing-transient-%d.service", rand.Int())
+
+	// Start the unit
+	job, err := conn.StartTransientUnit(target, "replace", props...)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if job != "done" {
+		t.Fatal("Job is not done:", job)
+	}
+
+	units, err := conn.ListUnits()
+
+	var unit *UnitStatus
+	for _, u := range units {
+		if u.Name == target {
+			unit = &u
+		}
+	}
+
+	if unit == nil {
+		t.Fatalf("Test unit not found in list")
+	}
+
+	if unit.ActiveState != "active" {
+		t.Fatalf("Test unit not active")
+	}
+
+	// 3. Stop the unit
+	job, err = conn.StopUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	units, err = conn.ListUnits()
+
+	unit = nil
+	for _, u := range units {
+		if u.Name == target {
+			unit = &u
+		}
+	}
+
+	if unit != nil {
+		t.Fatalf("Test unit found in list, should be stopped")
+	}
+}
+
+func TestConnJobListener(t *testing.T) {
+	target := "start-stop.service"
+	conn := setupConn(t)
+
+	setupUnit(target, conn, t)
+	linkUnit(target, conn, t)
+
+	jobSize := len(conn.jobListener.jobs)
+
+	_, err := conn.StartUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	_, err = conn.StopUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	currentJobSize := len(conn.jobListener.jobs)
+	if jobSize != currentJobSize {
+		t.Fatal("JobListener jobs leaked")
+	}
+}

+ 220 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/properties.go

@@ -0,0 +1,220 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package dbus
+
+import (
+	"github.com/godbus/dbus"
+)
+
+// From the systemd docs:
+//
+// The properties array of StartTransientUnit() may take many of the settings
+// that may also be configured in unit files. Not all parameters are currently
+// accepted though, but we plan to cover more properties with future release.
+// Currently you may set the Description, Slice and all dependency types of
+// units, as well as RemainAfterExit, ExecStart for service units,
+// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares,
+// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth,
+// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit,
+// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map
+// directly to their counterparts in unit files and as normal D-Bus object
+// properties. The exception here is the PIDs field of scope units which is
+// used for construction of the scope only and specifies the initial PIDs to
+// add to the scope object.
+
+type Property struct {
+	Name  string
+	Value dbus.Variant
+}
+
+type PropertyCollection struct {
+	Name       string
+	Properties []Property
+}
+
+type execStart struct {
+	Path             string   // the binary path to execute
+	Args             []string // an array with all arguments to pass to the executed command, starting with argument 0
+	UncleanIsFailure bool     // a boolean whether it should be considered a failure if the process exits uncleanly
+}
+
+// PropExecStart sets the ExecStart service property.  The first argument is a
+// slice with the binary path to execute followed by the arguments to pass to
+// the executed command. See
+// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
+func PropExecStart(command []string, uncleanIsFailure bool) Property {
+	execStarts := []execStart{
+		execStart{
+			Path:             command[0],
+			Args:             command,
+			UncleanIsFailure: uncleanIsFailure,
+		},
+	}
+
+	return Property{
+		Name:  "ExecStart",
+		Value: dbus.MakeVariant(execStarts),
+	}
+}
+
+// PropRemainAfterExit sets the RemainAfterExit service property. See
+// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit=
+func PropRemainAfterExit(b bool) Property {
+	return Property{
+		Name:  "RemainAfterExit",
+		Value: dbus.MakeVariant(b),
+	}
+}
+
+// PropDescription sets the Description unit property. See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description=
+func PropDescription(desc string) Property {
+	return Property{
+		Name:  "Description",
+		Value: dbus.MakeVariant(desc),
+	}
+}
+
+func propDependency(name string, units []string) Property {
+	return Property{
+		Name:  name,
+		Value: dbus.MakeVariant(units),
+	}
+}
+
+// PropRequires sets the Requires unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires=
+func PropRequires(units ...string) Property {
+	return propDependency("Requires", units)
+}
+
+// PropRequiresOverridable sets the RequiresOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable=
+func PropRequiresOverridable(units ...string) Property {
+	return propDependency("RequiresOverridable", units)
+}
+
+// PropRequisite sets the Requisite unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite=
+func PropRequisite(units ...string) Property {
+	return propDependency("Requisite", units)
+}
+
+// PropRequisiteOverridable sets the RequisiteOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable=
+func PropRequisiteOverridable(units ...string) Property {
+	return propDependency("RequisiteOverridable", units)
+}
+
+// PropWants sets the Wants unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants=
+func PropWants(units ...string) Property {
+	return propDependency("Wants", units)
+}
+
+// PropBindsTo sets the BindsTo unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=
+func PropBindsTo(units ...string) Property {
+	return propDependency("BindsTo", units)
+}
+
+// PropRequiredBy sets the RequiredBy unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy=
+func PropRequiredBy(units ...string) Property {
+	return propDependency("RequiredBy", units)
+}
+
+// PropRequiredByOverridable sets the RequiredByOverridable unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable=
+func PropRequiredByOverridable(units ...string) Property {
+	return propDependency("RequiredByOverridable", units)
+}
+
+// PropWantedBy sets the WantedBy unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy=
+func PropWantedBy(units ...string) Property {
+	return propDependency("WantedBy", units)
+}
+
+// PropBoundBy sets the BoundBy unit property.  See
+// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy=
+func PropBoundBy(units ...string) Property {
+	return propDependency("BoundBy", units)
+}
+
+// PropConflicts sets the Conflicts unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts=
+func PropConflicts(units ...string) Property {
+	return propDependency("Conflicts", units)
+}
+
+// PropConflictedBy sets the ConflictedBy unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy=
+func PropConflictedBy(units ...string) Property {
+	return propDependency("ConflictedBy", units)
+}
+
+// PropBefore sets the Before unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before=
+func PropBefore(units ...string) Property {
+	return propDependency("Before", units)
+}
+
+// PropAfter sets the After unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After=
+func PropAfter(units ...string) Property {
+	return propDependency("After", units)
+}
+
+// PropOnFailure sets the OnFailure unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure=
+func PropOnFailure(units ...string) Property {
+	return propDependency("OnFailure", units)
+}
+
+// PropTriggers sets the Triggers unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers=
+func PropTriggers(units ...string) Property {
+	return propDependency("Triggers", units)
+}
+
+// PropTriggeredBy sets the TriggeredBy unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy=
+func PropTriggeredBy(units ...string) Property {
+	return propDependency("TriggeredBy", units)
+}
+
+// PropPropagatesReloadTo sets the PropagatesReloadTo unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo=
+func PropPropagatesReloadTo(units ...string) Property {
+	return propDependency("PropagatesReloadTo", units)
+}
+
+// PropRequiresMountsFor sets the RequiresMountsFor unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor=
+func PropRequiresMountsFor(units ...string) Property {
+	return propDependency("RequiresMountsFor", units)
+}
+
+// PropSlice sets the Slice unit property.  See
+// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice=
+func PropSlice(slice string) Property {
+	return Property{
+		Name:  "Slice",
+		Value: dbus.MakeVariant(slice),
+	}
+}

+ 33 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set.go

@@ -0,0 +1,33 @@
+package dbus
+
+type set struct {
+	data map[string]bool
+}
+
+func (s *set) Add(value string) {
+	s.data[value] = true
+}
+
+func (s *set) Remove(value string) {
+	delete(s.data, value)
+}
+
+func (s *set) Contains(value string) (exists bool) {
+	_, exists = s.data[value]
+	return
+}
+
+func (s *set) Length() (int) {
+	return len(s.data)
+}
+
+func (s *set) Values() (values []string) {
+	 for val, _ := range s.data {
+		values = append(values, val)
+	 }
+	 return
+}
+
+func newSet() (*set) {
+	return &set{make(map[string] bool)}
+}

+ 39 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/set_test.go

@@ -0,0 +1,39 @@
+package dbus
+
+import (
+	"testing"
+)
+
+// TestBasicSetActions asserts that Add & Remove behavior is correct
+func TestBasicSetActions(t *testing.T) {
+	s := newSet()
+
+	if s.Contains("foo") {
+		t.Fatal("set should not contain 'foo'")
+	}
+
+	s.Add("foo")
+
+	if !s.Contains("foo") {
+		t.Fatal("set should contain 'foo'")
+	}
+
+	v := s.Values()
+	if len(v) != 1 {
+		t.Fatal("set.Values did not report correct number of values")
+	}
+	if v[0] != "foo" {
+		t.Fatal("set.Values did not report value")
+	}
+
+	s.Remove("foo")
+
+	if s.Contains("foo") {
+		t.Fatal("set should not contain 'foo'")
+	}
+
+	v = s.Values()
+	if len(v) != 0 {
+		t.Fatal("set.Values did not report correct number of values")
+	}
+}

+ 251 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription.go

@@ -0,0 +1,251 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package dbus
+
+import (
+	"errors"
+	"time"
+
+	"github.com/godbus/dbus"
+)
+
+const (
+	cleanIgnoreInterval = int64(10 * time.Second)
+	ignoreInterval      = int64(30 * time.Millisecond)
+)
+
+// Subscribe sets up this connection to subscribe to all systemd dbus events.
+// This is required before calling SubscribeUnits. When the connection closes
+// systemd will automatically stop sending signals so there is no need to
+// explicitly call Unsubscribe().
+func (c *Conn) Subscribe() error {
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'")
+	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'")
+
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Unsubscribe this connection from systemd dbus events.
+func (c *Conn) Unsubscribe() error {
+	err := c.sysobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Conn) initSubscription() {
+	c.subscriber.ignore = make(map[dbus.ObjectPath]int64)
+}
+
+func (c *Conn) initDispatch() {
+	ch := make(chan *dbus.Signal, signalBuffer)
+
+	c.sysconn.Signal(ch)
+
+	go func() {
+		for {
+			signal, ok := <-ch
+			if !ok {
+				return
+			}
+
+			switch signal.Name {
+			case "org.freedesktop.systemd1.Manager.JobRemoved":
+				c.jobComplete(signal)
+
+				unitName := signal.Body[2].(string)
+				var unitPath dbus.ObjectPath
+				c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath)
+				if unitPath != dbus.ObjectPath("") {
+					c.sendSubStateUpdate(unitPath)
+				}
+			case "org.freedesktop.systemd1.Manager.UnitNew":
+				c.sendSubStateUpdate(signal.Body[1].(dbus.ObjectPath))
+			case "org.freedesktop.DBus.Properties.PropertiesChanged":
+				if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" {
+					// we only care about SubState updates, which are a Unit property
+					c.sendSubStateUpdate(signal.Path)
+				}
+			}
+		}
+	}()
+}
+
+// Returns two unbuffered channels which will receive all changed units every
+// interval.  Deleted units are sent as nil.
+func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) {
+	return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil)
+}
+
+// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer
+// size of the channels, the comparison function for detecting changes and a filter
+// function for cutting down on the noise that your channel receives.
+func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func (string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
+	old := make(map[string]*UnitStatus)
+	statusChan := make(chan map[string]*UnitStatus, buffer)
+	errChan := make(chan error, buffer)
+
+	go func() {
+		for {
+			timerChan := time.After(interval)
+
+			units, err := c.ListUnits()
+			if err == nil {
+				cur := make(map[string]*UnitStatus)
+				for i := range units {
+					if filterUnit != nil && filterUnit(units[i].Name) {
+						continue
+					}
+					cur[units[i].Name] = &units[i]
+				}
+
+				// add all new or changed units
+				changed := make(map[string]*UnitStatus)
+				for n, u := range cur {
+					if oldU, ok := old[n]; !ok || isChanged(oldU, u) {
+						changed[n] = u
+					}
+					delete(old, n)
+				}
+
+				// add all deleted units
+				for oldN := range old {
+					changed[oldN] = nil
+				}
+
+				old = cur
+
+				if len(changed) != 0 {
+					statusChan <- changed
+				}
+			} else {
+				errChan <- err
+			}
+
+			<-timerChan
+		}
+	}()
+
+	return statusChan, errChan
+}
+
+type SubStateUpdate struct {
+	UnitName string
+	SubState string
+}
+
+// SetSubStateSubscriber writes to updateCh when any unit's substate changes.
+// Although this writes to updateCh on every state change, the reported state
+// may be more recent than the change that generated it (due to an unavoidable
+// race in the systemd dbus interface).  That is, this method provides a good
+// way to keep a current view of all units' states, but is not guaranteed to
+// show every state transition they go through.  Furthermore, state changes
+// will only be written to the channel with non-blocking writes.  If updateCh
+// is full, it attempts to write an error to errCh; if errCh is full, the error
+// passes silently.
+func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) {
+	c.subscriber.Lock()
+	defer c.subscriber.Unlock()
+	c.subscriber.updateCh = updateCh
+	c.subscriber.errCh = errCh
+}
+
+func (c *Conn) sendSubStateUpdate(path dbus.ObjectPath) {
+	c.subscriber.Lock()
+	defer c.subscriber.Unlock()
+	if c.subscriber.updateCh == nil {
+		return
+	}
+
+	if c.shouldIgnore(path) {
+		return
+	}
+
+	info, err := c.GetUnitProperties(string(path))
+	if err != nil {
+		select {
+		case c.subscriber.errCh <- err:
+		default:
+		}
+	}
+
+	name := info["Id"].(string)
+	substate := info["SubState"].(string)
+
+	update := &SubStateUpdate{name, substate}
+	select {
+	case c.subscriber.updateCh <- update:
+	default:
+		select {
+		case c.subscriber.errCh <- errors.New("update channel full!"):
+		default:
+		}
+	}
+
+	c.updateIgnore(path, info)
+}
+
+// The ignore functions work around a wart in the systemd dbus interface.
+// Requesting the properties of an unloaded unit will cause systemd to send a
+// pair of UnitNew/UnitRemoved signals.  Because we need to get a unit's
+// properties on UnitNew (as that's the only indication of a new unit coming up
+// for the first time), we would enter an infinite loop if we did not attempt
+// to detect and ignore these spurious signals.  The signal themselves are
+// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an
+// unloaded unit's signals for a short time after requesting its properties.
+// This means that we will miss e.g. a transient unit being restarted
+// *immediately* upon failure and also a transient unit being started
+// immediately after requesting its status (with systemctl status, for example,
+// because this causes a UnitNew signal to be sent which then causes us to fetch
+// the properties).
+
+func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool {
+	t, ok := c.subscriber.ignore[path]
+	return ok && t >= time.Now().UnixNano()
+}
+
+func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) {
+	c.cleanIgnore()
+
+	// unit is unloaded - it will trigger bad systemd dbus behavior
+	if info["LoadState"].(string) == "not-found" {
+		c.subscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval
+	}
+}
+
+// without this, ignore would grow unboundedly over time
+func (c *Conn) cleanIgnore() {
+	now := time.Now().UnixNano()
+	if c.subscriber.cleanIgnore < now {
+		c.subscriber.cleanIgnore = now + cleanIgnoreInterval
+
+		for p, t := range c.subscriber.ignore {
+			if t < now {
+				delete(c.subscriber.ignore, p)
+			}
+		}
+	}
+}

+ 32 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set.go

@@ -0,0 +1,32 @@
+package dbus
+
+import (
+	"time"
+)
+
+// SubscriptionSet returns a subscription set which is like conn.Subscribe but
+// can filter to only return events for a set of units.
+type SubscriptionSet struct {
+	*set
+	conn *Conn
+}
+
+
+func (s *SubscriptionSet) filter(unit string) bool {
+	return !s.Contains(unit)
+}
+
+// Subscribe starts listening for dbus events for all of the units in the set.
+// Returns channels identical to conn.SubscribeUnits.
+func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) {
+	// TODO: Make fully evented by using systemd 209 with properties changed values
+	return s.conn.SubscribeUnitsCustom(time.Second, 0,
+		func(u1, u2 *UnitStatus) bool { return *u1 != *u2 },
+		func(unit string) bool { return s.filter(unit) },
+	)
+}
+
+// NewSubscriptionSet returns a new subscription set.
+func (conn *Conn) NewSubscriptionSet() (*SubscriptionSet) {
+	return &SubscriptionSet{newSet(), conn}
+}

+ 66 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_set_test.go

@@ -0,0 +1,66 @@
+package dbus
+
+import (
+	"testing"
+	"time"
+)
+
+// TestSubscribeUnit exercises the basics of subscription of a particular unit.
+func TestSubscriptionSetUnit(t *testing.T) {
+	target := "subscribe-events-set.service"
+
+	conn, err := New()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = conn.Subscribe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	subSet := conn.NewSubscriptionSet()
+	evChan, errChan := subSet.Subscribe()
+
+	subSet.Add(target)
+	setupUnit(target, conn, t)
+	linkUnit(target, conn, t)
+
+	job, err := conn.StartUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if job != "done" {
+		t.Fatal("Couldn't start", target)
+	}
+
+	timeout := make(chan bool, 1)
+	go func() {
+		time.Sleep(3 * time.Second)
+		close(timeout)
+	}()
+
+	for {
+		select {
+		case changes := <-evChan:
+			tCh, ok := changes[target]
+
+			if !ok {
+				t.Fatal("Unexpected event:", changes)
+			}
+
+			if tCh.ActiveState == "active" && tCh.Name == target {
+				goto success
+			}
+		case err = <-errChan:
+			t.Fatal(err)
+		case <-timeout:
+			t.Fatal("Reached timeout")
+		}
+	}
+
+success:
+	return
+}

+ 91 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/dbus/subscription_test.go

@@ -0,0 +1,91 @@
+package dbus
+
+import (
+	"testing"
+	"time"
+)
+
+// TestSubscribe exercises the basics of subscription
+func TestSubscribe(t *testing.T) {
+	conn, err := New()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = conn.Subscribe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = conn.Unsubscribe()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// TestSubscribeUnit exercises the basics of subscription of a particular unit.
+func TestSubscribeUnit(t *testing.T) {
+	target := "subscribe-events.service"
+
+	conn, err := New()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = conn.Subscribe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = conn.Unsubscribe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	evChan, errChan := conn.SubscribeUnits(time.Second)
+
+	setupUnit(target, conn, t)
+	linkUnit(target, conn, t)
+
+	job, err := conn.StartUnit(target, "replace")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if job != "done" {
+		t.Fatal("Couldn't start", target)
+	}
+
+	timeout := make(chan bool, 1)
+	go func() {
+		time.Sleep(3 * time.Second)
+		close(timeout)
+	}()
+
+	for {
+		select {
+		case changes := <-evChan:
+			tCh, ok := changes[target]
+
+			// Just continue until we see our event.
+			if !ok {
+				continue
+			}
+
+			if tCh.ActiveState == "active" && tCh.Name == target {
+				goto success
+			}
+		case err = <-errChan:
+			t.Fatal(err)
+		case <-timeout:
+			t.Fatal("Reached timeout")
+		}
+	}
+
+success:
+	return
+}
+
+

+ 44 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go

@@ -0,0 +1,44 @@
+// Activation example used by the activation unit tests.
+package main
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/coreos/go-systemd/activation"
+)
+
+func fixListenPid() {
+	if os.Getenv("FIX_LISTEN_PID") != "" {
+		// HACK: real systemd would set LISTEN_PID before exec'ing but
+		// this is too difficult in golang for the purpose of a test.
+		// Do not do this in real code.
+		os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
+	}
+}
+
+func main() {
+	fixListenPid()
+
+	files := activation.Files(false)
+
+	if len(files) == 0 {
+		panic("No files")
+	}
+
+	if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
+		panic("Should not unset envs")
+	}
+
+	files = activation.Files(true)
+
+	if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
+		panic("Can not unset envs")
+	}
+
+	// Write out the expected strings to the two pipes
+	files[0].Write([]byte("Hello world"))
+	files[1].Write([]byte("Goodbye world"))
+
+	return
+}

+ 19 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md

@@ -0,0 +1,19 @@
+## socket activated http server
+
+This is a simple example of using socket activation with systemd to serve a
+simple HTTP server on http://127.0.0.1:8076
+
+To try it out `go get` the httpserver and run it under the systemd-activate helper
+
+```
+export GOPATH=`pwd`
+go get github.com/coreos/go-systemd/examples/activation/httpserver
+sudo /usr/lib/systemd/systemd-activate -l 127.0.0.1:8076 ./bin/httpserver
+```
+
+Then curl the URL and you will notice that it starts up:
+
+```
+curl 127.0.0.1:8076
+hello socket activated world!
+```

+ 11 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service

@@ -0,0 +1,11 @@
+[Unit]
+Description=Hello World HTTP
+Requires=network.target
+After=multi-user.target
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/httpserver
+
+[Install]
+WantedBy=multi-user.target

+ 5 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket

@@ -0,0 +1,5 @@
+[Socket]
+ListenStream=127.0.0.1:8076
+
+[Install]
+WantedBy=sockets.target

+ 26 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go

@@ -0,0 +1,26 @@
+package main
+
+import (
+	"io"
+	"net/http"
+
+	"github.com/coreos/go-systemd/activation"
+)
+
+func HelloServer(w http.ResponseWriter, req *http.Request) {
+	io.WriteString(w, "hello socket activated world!\n")
+}
+
+func main() {
+	listeners, err := activation.Listeners(true)
+	if err != nil {
+		panic(err)
+	}
+
+	if len(listeners) != 1 {
+		panic("Unexpected number of socket activation fds")
+	}
+
+	http.HandleFunc("/", HelloServer)
+	http.Serve(listeners[0], nil)
+}

+ 50 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go

@@ -0,0 +1,50 @@
+// Activation example used by the activation unit tests.
+package main
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/coreos/go-systemd/activation"
+)
+
+func fixListenPid() {
+	if os.Getenv("FIX_LISTEN_PID") != "" {
+		// HACK: real systemd would set LISTEN_PID before exec'ing but
+		// this is too difficult in golang for the purpose of a test.
+		// Do not do this in real code.
+		os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
+	}
+}
+
+func main() {
+	fixListenPid()
+
+	listeners, _ := activation.Listeners(false)
+
+	if len(listeners) == 0 {
+		panic("No listeners")
+	}
+
+	if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
+		panic("Should not unset envs")
+	}
+
+	listeners, err := activation.Listeners(true)
+	if err != nil {
+		panic(err)
+	}
+
+	if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
+		panic("Can not unset envs")
+	}
+
+	c0, _ := listeners[0].Accept()
+	c1, _ := listeners[1].Accept()
+
+	// Write out the expected strings to the two pipes
+	c0.Write([]byte("Hello world"))
+	c1.Write([]byte("Goodbye world"))
+
+	return
+}

+ 5 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/enable-disable.service

@@ -0,0 +1,5 @@
+[Unit]
+Description=enable disable test
+
+[Service]
+ExecStart=/bin/sleep 400

+ 5 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/start-stop.service

@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400

+ 5 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events-set.service

@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400

+ 5 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/fixtures/subscribe-events.service

@@ -0,0 +1,5 @@
+[Unit]
+Description=start stop test
+
+[Service]
+ExecStart=/bin/sleep 400

+ 168 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/journal/send.go

@@ -0,0 +1,168 @@
+/*
+Copyright 2013 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package journal provides write bindings to the systemd journal
+package journal
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net"
+	"os"
+	"strconv"
+	"strings"
+	"syscall"
+)
+
+// Priority of a journal message
+type Priority int
+
+const (
+	PriEmerg Priority = iota
+	PriAlert
+	PriCrit
+	PriErr
+	PriWarning
+	PriNotice
+	PriInfo
+	PriDebug
+)
+
+var conn net.Conn
+
+func init() {
+	var err error
+	conn, err = net.Dial("unixgram", "/run/systemd/journal/socket")
+	if err != nil {
+		conn = nil
+	}
+}
+
+// Enabled returns true iff the systemd journal is available for logging
+func Enabled() bool {
+	return conn != nil
+}
+
+// Send a message to the systemd journal. vars is a map of journald fields to
+// values.  Fields must be composed of uppercase letters, numbers, and
+// underscores, but must not start with an underscore. Within these
+// restrictions, any arbitrary field name may be used.  Some names have special
+// significance: see the journalctl documentation
+// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
+// for more details.  vars may be nil.
+func Send(message string, priority Priority, vars map[string]string) error {
+	if conn == nil {
+		return journalError("could not connect to journald socket")
+	}
+
+	data := new(bytes.Buffer)
+	appendVariable(data, "PRIORITY", strconv.Itoa(int(priority)))
+	appendVariable(data, "MESSAGE", message)
+	for k, v := range vars {
+		appendVariable(data, k, v)
+	}
+
+	_, err := io.Copy(conn, data)
+	if err != nil && isSocketSpaceError(err) {
+		file, err := tempFd()
+		if err != nil {
+			return journalError(err.Error())
+		}
+		_, err = io.Copy(file, data)
+		if err != nil {
+			return journalError(err.Error())
+		}
+
+		rights := syscall.UnixRights(int(file.Fd()))
+
+		/* this connection should always be a UnixConn, but better safe than sorry */
+		unixConn, ok := conn.(*net.UnixConn)
+		if !ok {
+			return journalError("can't send file through non-Unix connection")
+		}
+		unixConn.WriteMsgUnix([]byte{}, rights, nil)
+	} else if err != nil {
+		return journalError(err.Error())
+	}
+	return nil
+}
+
+func appendVariable(w io.Writer, name, value string) {
+	if !validVarName(name) {
+		journalError("variable name contains invalid character, ignoring")
+	}
+	if strings.ContainsRune(value, '\n') {
+		/* When the value contains a newline, we write:
+		 * - the variable name, followed by a newline
+		 * - the size (in 64bit little endian format)
+		 * - the data, followed by a newline
+		 */
+		fmt.Fprintln(w, name)
+		binary.Write(w, binary.LittleEndian, uint64(len(value)))
+		fmt.Fprintln(w, value)
+	} else {
+		/* just write the variable and value all on one line */
+		fmt.Fprintf(w, "%s=%s\n", name, value)
+	}
+}
+
+func validVarName(name string) bool {
+	/* The variable name must be in uppercase and consist only of characters,
+	 * numbers and underscores, and may not begin with an underscore. (from the docs)
+	 */
+
+	valid := name[0] != '_'
+	for _, c := range name {
+		valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_'
+	}
+	return valid
+}
+
+func isSocketSpaceError(err error) bool {
+	opErr, ok := err.(*net.OpError)
+	if !ok {
+		return false
+	}
+
+	sysErr, ok := opErr.Err.(syscall.Errno)
+	if !ok {
+		return false
+	}
+
+	return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS
+}
+
+func tempFd() (*os.File, error) {
+	file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
+	if err != nil {
+		return nil, err
+	}
+	syscall.Unlink(file.Name())
+	if err != nil {
+		return nil, err
+	}
+	return file, nil
+}
+
+func journalError(s string) error {
+	s = "journal error: " + s
+	fmt.Fprintln(os.Stderr, s)
+	return errors.New(s)
+}

+ 81 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus.go

@@ -0,0 +1,81 @@
+/*
+Copyright 2014 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Integration with the systemd logind API.  See http://www.freedesktop.org/wiki/Software/systemd/logind/
+package login1
+
+import (
+	"os"
+	"strconv"
+
+	"github.com/godbus/dbus"
+)
+
+const (
+	dbusInterface = "org.freedesktop.login1.Manager"
+	dbusPath      = "/org/freedesktop/login1"
+)
+
+// Conn is a connection to systemds dbus endpoint.
+type Conn struct {
+	conn   *dbus.Conn
+	object *dbus.Object
+}
+
+// New() establishes a connection to the system bus and authenticates.
+func New() (*Conn, error) {
+	c := new(Conn)
+
+	if err := c.initConnection(); err != nil {
+		return nil, err
+	}
+
+	return c, nil
+}
+
+func (c *Conn) initConnection() error {
+	var err error
+	c.conn, err = dbus.SystemBusPrivate()
+	if err != nil {
+		return err
+	}
+
+	// Only use EXTERNAL method, and hardcode the uid (not username)
+	// to avoid a username lookup (which requires a dynamically linked
+	// libc)
+	methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
+
+	err = c.conn.Auth(methods)
+	if err != nil {
+		c.conn.Close()
+		return err
+	}
+
+	err = c.conn.Hello()
+	if err != nil {
+		c.conn.Close()
+		return err
+	}
+
+	c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath))
+
+	return nil
+}
+
+// Reboot asks logind for a reboot optionally asking for auth.
+func (c *Conn) Reboot(askForAuth bool) {
+	c.object.Call(dbusInterface+".Reboot", 0, askForAuth)
+}

+ 30 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/login1/dbus_test.go

@@ -0,0 +1,30 @@
+/*
+Copyright 2014 CoreOS Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package login1
+
+import (
+	"testing"
+)
+
+// TestNew ensures that New() works without errors.
+func TestNew(t *testing.T) {
+	_, err := New()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+}

+ 3 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/coreos/go-systemd/test

@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+go test -v ./...

+ 25 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/LICENSE

@@ -0,0 +1,25 @@
+Copyright (c) 2013, Georg Reinke (<guelfey at gmail dot com>)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 38 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/README.markdown

@@ -0,0 +1,38 @@
+dbus
+----
+
+dbus is a simple library that implements native Go client bindings for the
+D-Bus message bus system.
+
+### Features
+
+* Complete native implementation of the D-Bus message protocol
+* Go-like API (channels for signals / asynchronous method calls, Goroutine-safe connections)
+* Subpackages that help with the introspection / property interfaces
+
+### Installation
+
+This packages requires Go 1.1. If you installed it and set up your GOPATH, just run:
+
+```
+go get github.com/godbus/dbus
+```
+
+If you want to use the subpackages, you can install them the same way.
+
+### Usage
+
+The complete package documentation and some simple examples are available at
+[godoc.org](http://godoc.org/github.com/godbus/dbus). Also, the
+[_examples](https://github.com/godbus/dbus/tree/master/_examples) directory
+gives a short overview over the basic usage. 
+
+Please note that the API is considered unstable for now and may change without
+further notice.
+
+### License
+
+go.dbus is available under the Simplified BSD License; see LICENSE for the full
+text.
+
+Nearly all of the credit for this library goes to github.com/guelfey/go.dbus.

+ 30 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/eavesdrop.go

@@ -0,0 +1,30 @@
+package main
+
+import (
+	"fmt"
+	"github.com/godbus/dbus"
+	"os"
+)
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		fmt.Fprintln(os.Stderr, "Failed to connect to session bus:", err)
+		os.Exit(1)
+	}
+
+	for _, v := range []string{"method_call", "method_return", "error", "signal"} {
+		call := conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+			"eavesdrop='true',type='"+v+"'")
+		if call.Err != nil {
+			fmt.Fprintln(os.Stderr, "Failed to add match:", call.Err)
+			os.Exit(1)
+		}
+	}
+	c := make(chan *dbus.Message, 10)
+	conn.Eavesdrop(c)
+	fmt.Println("Listening for everything")
+	for v := range c {
+		fmt.Println(v)
+	}
+}

+ 21 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/introspect.go

@@ -0,0 +1,21 @@
+package main
+
+import (
+	"encoding/json"
+	"github.com/godbus/dbus"
+	"github.com/godbus/dbus/introspect"
+	"os"
+)
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		panic(err)
+	}
+	node, err := introspect.Call(conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus"))
+	if err != nil {
+		panic(err)
+	}
+	data, _ := json.MarshalIndent(node, "", "    ")
+	os.Stdout.Write(data)
+}

+ 27 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/list-names.go

@@ -0,0 +1,27 @@
+package main
+
+import (
+	"fmt"
+	"github.com/godbus/dbus"
+	"os"
+)
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		fmt.Fprintln(os.Stderr, "Failed to connect to session bus:", err)
+		os.Exit(1)
+	}
+
+	var s []string
+	err = conn.BusObject().Call("org.freedesktop.DBus.ListNames", 0).Store(&s)
+	if err != nil {
+		fmt.Fprintln(os.Stderr, "Failed to get list of owned names:", err)
+		os.Exit(1)
+	}
+
+	fmt.Println("Currently owned names on the session bus:")
+	for _, v := range s {
+		fmt.Println(v)
+	}
+}

+ 17 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/notification.go

@@ -0,0 +1,17 @@
+package main
+
+import "github.com/godbus/dbus"
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		panic(err)
+	}
+	obj := conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
+	call := obj.Call("org.freedesktop.Notifications.Notify", 0, "", uint32(0),
+		"", "Test", "This is a test of the DBus bindings for go.", []string{},
+		map[string]dbus.Variant{}, int32(5000))
+	if call.Err != nil {
+		panic(call.Err)
+	}
+}

+ 68 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/prop.go

@@ -0,0 +1,68 @@
+package main
+
+import (
+	"fmt"
+	"github.com/godbus/dbus"
+	"github.com/godbus/dbus/introspect"
+	"github.com/godbus/dbus/prop"
+	"os"
+)
+
+type foo string
+
+func (f foo) Foo() (string, *dbus.Error) {
+	fmt.Println(f)
+	return string(f), nil
+}
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		panic(err)
+	}
+	reply, err := conn.RequestName("com.github.guelfey.Demo",
+		dbus.NameFlagDoNotQueue)
+	if err != nil {
+		panic(err)
+	}
+	if reply != dbus.RequestNameReplyPrimaryOwner {
+		fmt.Fprintln(os.Stderr, "name already taken")
+		os.Exit(1)
+	}
+	propsSpec := map[string]map[string]*prop.Prop{
+		"com.github.guelfey.Demo": {
+			"SomeInt": {
+				int32(0),
+				true,
+				prop.EmitTrue,
+				func(c *prop.Change) *dbus.Error {
+					fmt.Println(c.Name, "changed to", c.Value)
+					return nil
+				},
+			},
+		},
+	}
+	f := foo("Bar")
+	conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
+	props := prop.New(conn, "/com/github/guelfey/Demo", propsSpec)
+	n := &introspect.Node{
+		Name: "/com/github/guelfey/Demo",
+		Interfaces: []introspect.Interface{
+			introspect.IntrospectData,
+			prop.IntrospectData,
+			{
+				Name:       "com.github.guelfey.Demo",
+				Methods:    introspect.Methods(f),
+				Properties: props.Introspection("com.github.guelfey.Demo"),
+			},
+		},
+	}
+	conn.Export(introspect.NewIntrospectable(n), "/com/github/guelfey/Demo",
+		"org.freedesktop.DBus.Introspectable")
+	fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
+
+	c := make(chan *dbus.Signal)
+	conn.Signal(c)
+	for _ = range c {
+	}
+}

+ 45 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/server.go

@@ -0,0 +1,45 @@
+package main
+
+import (
+	"fmt"
+	"github.com/godbus/dbus"
+	"github.com/godbus/dbus/introspect"
+	"os"
+)
+
+const intro = `
+<node>
+	<interface name="com.github.guelfey.Demo">
+		<method name="Foo">
+			<arg direction="out" type="s"/>
+		</method>
+	</interface>` + introspect.IntrospectDataString + `</node> `
+
+type foo string
+
+func (f foo) Foo() (string, *dbus.Error) {
+	fmt.Println(f)
+	return string(f), nil
+}
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		panic(err)
+	}
+	reply, err := conn.RequestName("com.github.guelfey.Demo",
+		dbus.NameFlagDoNotQueue)
+	if err != nil {
+		panic(err)
+	}
+	if reply != dbus.RequestNameReplyPrimaryOwner {
+		fmt.Fprintln(os.Stderr, "name already taken")
+		os.Exit(1)
+	}
+	f := foo("Bar!")
+	conn.Export(f, "/com/github/guelfey/Demo", "com.github.guelfey.Demo")
+	conn.Export(introspect.Introspectable(intro), "/com/github/guelfey/Demo",
+		"org.freedesktop.DBus.Introspectable")
+	fmt.Println("Listening on com.github.guelfey.Demo / /com/github/guelfey/Demo ...")
+	select {}
+}

+ 24 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/_examples/signal.go

@@ -0,0 +1,24 @@
+package main
+
+import (
+	"fmt"
+	"github.com/godbus/dbus"
+	"os"
+)
+
+func main() {
+	conn, err := dbus.SessionBus()
+	if err != nil {
+		fmt.Fprintln(os.Stderr, "Failed to connect to session bus:", err)
+		os.Exit(1)
+	}
+
+	conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
+		"type='signal',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',sender='org.freedesktop.DBus'")
+
+	c := make(chan *dbus.Signal, 10)
+	conn.Signal(c)
+	for v := range c {
+		fmt.Println(v)
+	}
+}

+ 253 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth.go

@@ -0,0 +1,253 @@
+package dbus
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"io"
+	"os"
+	"strconv"
+)
+
+// AuthStatus represents the Status of an authentication mechanism.
+type AuthStatus byte
+
+const (
+	// AuthOk signals that authentication is finished; the next command
+	// from the server should be an OK.
+	AuthOk AuthStatus = iota
+
+	// AuthContinue signals that additional data is needed; the next command
+	// from the server should be a DATA.
+	AuthContinue
+
+	// AuthError signals an error; the server sent invalid data or some
+	// other unexpected thing happened and the current authentication
+	// process should be aborted.
+	AuthError
+)
+
+type authState byte
+
+const (
+	waitingForData authState = iota
+	waitingForOk
+	waitingForReject
+)
+
+// Auth defines the behaviour of an authentication mechanism.
+type Auth interface {
+	// Return the name of the mechnism, the argument to the first AUTH command
+	// and the next status.
+	FirstData() (name, resp []byte, status AuthStatus)
+
+	// Process the given DATA command, and return the argument to the DATA
+	// command and the next status. If len(resp) == 0, no DATA command is sent.
+	HandleData(data []byte) (resp []byte, status AuthStatus)
+}
+
+// Auth authenticates the connection, trying the given list of authentication
+// mechanisms (in that order). If nil is passed, the EXTERNAL and
+// DBUS_COOKIE_SHA1 mechanisms are tried for the current user. For private
+// connections, this method must be called before sending any messages to the
+// bus. Auth must not be called on shared connections.
+func (conn *Conn) Auth(methods []Auth) error {
+	if methods == nil {
+		uid := strconv.Itoa(os.Getuid())
+		methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
+	}
+	in := bufio.NewReader(conn.transport)
+	err := conn.transport.SendNullByte()
+	if err != nil {
+		return err
+	}
+	err = authWriteLine(conn.transport, []byte("AUTH"))
+	if err != nil {
+		return err
+	}
+	s, err := authReadLine(in)
+	if err != nil {
+		return err
+	}
+	if len(s) < 2 || !bytes.Equal(s[0], []byte("REJECTED")) {
+		return errors.New("dbus: authentication protocol error")
+	}
+	s = s[1:]
+	for _, v := range s {
+		for _, m := range methods {
+			if name, data, status := m.FirstData(); bytes.Equal(v, name) {
+				var ok bool
+				err = authWriteLine(conn.transport, []byte("AUTH"), []byte(v), data)
+				if err != nil {
+					return err
+				}
+				switch status {
+				case AuthOk:
+					err, ok = conn.tryAuth(m, waitingForOk, in)
+				case AuthContinue:
+					err, ok = conn.tryAuth(m, waitingForData, in)
+				default:
+					panic("dbus: invalid authentication status")
+				}
+				if err != nil {
+					return err
+				}
+				if ok {
+					if conn.transport.SupportsUnixFDs() {
+						err = authWriteLine(conn, []byte("NEGOTIATE_UNIX_FD"))
+						if err != nil {
+							return err
+						}
+						line, err := authReadLine(in)
+						if err != nil {
+							return err
+						}
+						switch {
+						case bytes.Equal(line[0], []byte("AGREE_UNIX_FD")):
+							conn.EnableUnixFDs()
+							conn.unixFD = true
+						case bytes.Equal(line[0], []byte("ERROR")):
+						default:
+							return errors.New("dbus: authentication protocol error")
+						}
+					}
+					err = authWriteLine(conn.transport, []byte("BEGIN"))
+					if err != nil {
+						return err
+					}
+					go conn.inWorker()
+					go conn.outWorker()
+					return nil
+				}
+			}
+		}
+	}
+	return errors.New("dbus: authentication failed")
+}
+
+// tryAuth tries to authenticate with m as the mechanism, using state as the
+// initial authState and in for reading input. It returns (nil, true) on
+// success, (nil, false) on a REJECTED and (someErr, false) if some other
+// error occured.
+func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) {
+	for {
+		s, err := authReadLine(in)
+		if err != nil {
+			return err, false
+		}
+		switch {
+		case state == waitingForData && string(s[0]) == "DATA":
+			if len(s) != 2 {
+				err = authWriteLine(conn.transport, []byte("ERROR"))
+				if err != nil {
+					return err, false
+				}
+				continue
+			}
+			data, status := m.HandleData(s[1])
+			switch status {
+			case AuthOk, AuthContinue:
+				if len(data) != 0 {
+					err = authWriteLine(conn.transport, []byte("DATA"), data)
+					if err != nil {
+						return err, false
+					}
+				}
+				if status == AuthOk {
+					state = waitingForOk
+				}
+			case AuthError:
+				err = authWriteLine(conn.transport, []byte("ERROR"))
+				if err != nil {
+					return err, false
+				}
+			}
+		case state == waitingForData && string(s[0]) == "REJECTED":
+			return nil, false
+		case state == waitingForData && string(s[0]) == "ERROR":
+			err = authWriteLine(conn.transport, []byte("CANCEL"))
+			if err != nil {
+				return err, false
+			}
+			state = waitingForReject
+		case state == waitingForData && string(s[0]) == "OK":
+			if len(s) != 2 {
+				err = authWriteLine(conn.transport, []byte("CANCEL"))
+				if err != nil {
+					return err, false
+				}
+				state = waitingForReject
+			}
+			conn.uuid = string(s[1])
+			return nil, true
+		case state == waitingForData:
+			err = authWriteLine(conn.transport, []byte("ERROR"))
+			if err != nil {
+				return err, false
+			}
+		case state == waitingForOk && string(s[0]) == "OK":
+			if len(s) != 2 {
+				err = authWriteLine(conn.transport, []byte("CANCEL"))
+				if err != nil {
+					return err, false
+				}
+				state = waitingForReject
+			}
+			conn.uuid = string(s[1])
+			return nil, true
+		case state == waitingForOk && string(s[0]) == "REJECTED":
+			return nil, false
+		case state == waitingForOk && (string(s[0]) == "DATA" ||
+			string(s[0]) == "ERROR"):
+
+			err = authWriteLine(conn.transport, []byte("CANCEL"))
+			if err != nil {
+				return err, false
+			}
+			state = waitingForReject
+		case state == waitingForOk:
+			err = authWriteLine(conn.transport, []byte("ERROR"))
+			if err != nil {
+				return err, false
+			}
+		case state == waitingForReject && string(s[0]) == "REJECTED":
+			return nil, false
+		case state == waitingForReject:
+			return errors.New("dbus: authentication protocol error"), false
+		default:
+			panic("dbus: invalid auth state")
+		}
+	}
+}
+
+// authReadLine reads a line and separates it into its fields.
+func authReadLine(in *bufio.Reader) ([][]byte, error) {
+	data, err := in.ReadBytes('\n')
+	if err != nil {
+		return nil, err
+	}
+	data = bytes.TrimSuffix(data, []byte("\r\n"))
+	return bytes.Split(data, []byte{' '}), nil
+}
+
+// authWriteLine writes the given line in the authentication protocol format
+// (elements of data separated by a " " and terminated by "\r\n").
+func authWriteLine(out io.Writer, data ...[]byte) error {
+	buf := make([]byte, 0)
+	for i, v := range data {
+		buf = append(buf, v...)
+		if i != len(data)-1 {
+			buf = append(buf, ' ')
+		}
+	}
+	buf = append(buf, '\r')
+	buf = append(buf, '\n')
+	n, err := out.Write(buf)
+	if err != nil {
+		return err
+	}
+	if n != len(buf) {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}

+ 26 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_external.go

@@ -0,0 +1,26 @@
+package dbus
+
+import (
+	"encoding/hex"
+)
+
+// AuthExternal returns an Auth that authenticates as the given user with the
+// EXTERNAL mechanism.
+func AuthExternal(user string) Auth {
+	return authExternal{user}
+}
+
+// AuthExternal implements the EXTERNAL authentication mechanism.
+type authExternal struct {
+	user string
+}
+
+func (a authExternal) FirstData() ([]byte, []byte, AuthStatus) {
+	b := make([]byte, 2*len(a.user))
+	hex.Encode(b, []byte(a.user))
+	return []byte("EXTERNAL"), b, AuthOk
+}
+
+func (a authExternal) HandleData(b []byte) ([]byte, AuthStatus) {
+	return nil, AuthError
+}

+ 102 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/auth_sha1.go

@@ -0,0 +1,102 @@
+package dbus
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/rand"
+	"crypto/sha1"
+	"encoding/hex"
+	"os"
+)
+
+// AuthCookieSha1 returns an Auth that authenticates as the given user with the
+// DBUS_COOKIE_SHA1 mechanism. The home parameter should specify the home
+// directory of the user.
+func AuthCookieSha1(user, home string) Auth {
+	return authCookieSha1{user, home}
+}
+
+type authCookieSha1 struct {
+	user, home string
+}
+
+func (a authCookieSha1) FirstData() ([]byte, []byte, AuthStatus) {
+	b := make([]byte, 2*len(a.user))
+	hex.Encode(b, []byte(a.user))
+	return []byte("DBUS_COOKIE_SHA1"), b, AuthContinue
+}
+
+func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
+	challenge := make([]byte, len(data)/2)
+	_, err := hex.Decode(challenge, data)
+	if err != nil {
+		return nil, AuthError
+	}
+	b := bytes.Split(challenge, []byte{' '})
+	if len(b) != 3 {
+		return nil, AuthError
+	}
+	context := b[0]
+	id := b[1]
+	svchallenge := b[2]
+	cookie := a.getCookie(context, id)
+	if cookie == nil {
+		return nil, AuthError
+	}
+	clchallenge := a.generateChallenge()
+	if clchallenge == nil {
+		return nil, AuthError
+	}
+	hash := sha1.New()
+	hash.Write(bytes.Join([][]byte{svchallenge, clchallenge, cookie}, []byte{':'}))
+	hexhash := make([]byte, 2*hash.Size())
+	hex.Encode(hexhash, hash.Sum(nil))
+	data = append(clchallenge, ' ')
+	data = append(data, hexhash...)
+	resp := make([]byte, 2*len(data))
+	hex.Encode(resp, data)
+	return resp, AuthOk
+}
+
+// getCookie searches for the cookie identified by id in context and returns
+// the cookie content or nil. (Since HandleData can't return a specific error,
+// but only whether an error occured, this function also doesn't bother to
+// return an error.)
+func (a authCookieSha1) getCookie(context, id []byte) []byte {
+	file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))
+	if err != nil {
+		return nil
+	}
+	defer file.Close()
+	rd := bufio.NewReader(file)
+	for {
+		line, err := rd.ReadBytes('\n')
+		if err != nil {
+			return nil
+		}
+		line = line[:len(line)-1]
+		b := bytes.Split(line, []byte{' '})
+		if len(b) != 3 {
+			return nil
+		}
+		if bytes.Equal(b[0], id) {
+			return b[2]
+		}
+	}
+}
+
+// generateChallenge returns a random, hex-encoded challenge, or nil on error
+// (see above).
+func (a authCookieSha1) generateChallenge() []byte {
+	b := make([]byte, 16)
+	n, err := rand.Read(b)
+	if err != nil {
+		return nil
+	}
+	if n != 16 {
+		return nil
+	}
+	enc := make([]byte, 32)
+	hex.Encode(enc, b)
+	return enc
+}

+ 147 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/call.go

@@ -0,0 +1,147 @@
+package dbus
+
+import (
+	"errors"
+	"strings"
+)
+
+// Call represents a pending or completed method call.
+type Call struct {
+	Destination string
+	Path        ObjectPath
+	Method      string
+	Args        []interface{}
+
+	// Strobes when the call is complete.
+	Done chan *Call
+
+	// After completion, the error status. If this is non-nil, it may be an
+	// error message from the peer (with Error as its type) or some other error.
+	Err error
+
+	// Holds the response once the call is done.
+	Body []interface{}
+}
+
+var errSignature = errors.New("dbus: mismatched signature")
+
+// Store stores the body of the reply into the provided pointers. It returns
+// an error if the signatures of the body and retvalues don't match, or if
+// the error status is not nil.
+func (c *Call) Store(retvalues ...interface{}) error {
+	if c.Err != nil {
+		return c.Err
+	}
+
+	return Store(c.Body, retvalues...)
+}
+
+// Object represents a remote object on which methods can be invoked.
+type Object struct {
+	conn *Conn
+	dest string
+	path ObjectPath
+}
+
+// Call calls a method with (*Object).Go and waits for its reply.
+func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
+	return <-o.Go(method, flags, make(chan *Call, 1), args...).Done
+}
+
+// GetProperty calls org.freedesktop.DBus.Properties.GetProperty on the given
+// object. The property name must be given in interface.member notation.
+func (o *Object) GetProperty(p string) (Variant, error) {
+	idx := strings.LastIndex(p, ".")
+	if idx == -1 || idx+1 == len(p) {
+		return Variant{}, errors.New("dbus: invalid property " + p)
+	}
+
+	iface := p[:idx]
+	prop := p[idx+1:]
+
+	result := Variant{}
+	err := o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).Store(&result)
+
+	if err != nil {
+		return Variant{}, err
+	}
+
+	return result, nil
+}
+
+// Go calls a method with the given arguments asynchronously. It returns a
+// Call structure representing this method call. The passed channel will
+// return the same value once the call is done. If ch is nil, a new channel
+// will be allocated. Otherwise, ch has to be buffered or Go will panic.
+//
+// If the flags include FlagNoReplyExpected, ch is ignored and a Call structure
+// is returned of which only the Err member is valid.
+//
+// If the method parameter contains a dot ('.'), the part before the last dot
+// specifies the interface on which the method is called.
+func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+	iface := ""
+	i := strings.LastIndex(method, ".")
+	if i != -1 {
+		iface = method[:i]
+	}
+	method = method[i+1:]
+	msg := new(Message)
+	msg.Type = TypeMethodCall
+	msg.serial = o.conn.getSerial()
+	msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
+	msg.Headers = make(map[HeaderField]Variant)
+	msg.Headers[FieldPath] = MakeVariant(o.path)
+	msg.Headers[FieldDestination] = MakeVariant(o.dest)
+	msg.Headers[FieldMember] = MakeVariant(method)
+	if iface != "" {
+		msg.Headers[FieldInterface] = MakeVariant(iface)
+	}
+	msg.Body = args
+	if len(args) > 0 {
+		msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
+	}
+	if msg.Flags&FlagNoReplyExpected == 0 {
+		if ch == nil {
+			ch = make(chan *Call, 10)
+		} else if cap(ch) == 0 {
+			panic("dbus: unbuffered channel passed to (*Object).Go")
+		}
+		call := &Call{
+			Destination: o.dest,
+			Path:        o.path,
+			Method:      method,
+			Args:        args,
+			Done:        ch,
+		}
+		o.conn.callsLck.Lock()
+		o.conn.calls[msg.serial] = call
+		o.conn.callsLck.Unlock()
+		o.conn.outLck.RLock()
+		if o.conn.closed {
+			call.Err = ErrClosed
+			call.Done <- call
+		} else {
+			o.conn.out <- msg
+		}
+		o.conn.outLck.RUnlock()
+		return call
+	}
+	o.conn.outLck.RLock()
+	defer o.conn.outLck.RUnlock()
+	if o.conn.closed {
+		return &Call{Err: ErrClosed}
+	}
+	o.conn.out <- msg
+	return &Call{Err: nil}
+}
+
+// Destination returns the destination that calls on o are sent to.
+func (o *Object) Destination() string {
+	return o.dest
+}
+
+// Path returns the path that calls on o are sent to.
+func (o *Object) Path() ObjectPath {
+	return o.path
+}

+ 601 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn.go

@@ -0,0 +1,601 @@
+package dbus
+
+import (
+	"errors"
+	"io"
+	"os"
+	"reflect"
+	"strings"
+	"sync"
+)
+
+const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
+
+var (
+	systemBus     *Conn
+	systemBusLck  sync.Mutex
+	sessionBus    *Conn
+	sessionBusLck sync.Mutex
+)
+
+// ErrClosed is the error returned by calls on a closed connection.
+var ErrClosed = errors.New("dbus: connection closed by user")
+
+// Conn represents a connection to a message bus (usually, the system or
+// session bus).
+//
+// Connections are either shared or private. Shared connections
+// are shared between calls to the functions that return them. As a result,
+// the methods Close, Auth and Hello must not be called on them.
+//
+// Multiple goroutines may invoke methods on a connection simultaneously.
+type Conn struct {
+	transport
+
+	busObj *Object
+	unixFD bool
+	uuid   string
+
+	names    []string
+	namesLck sync.RWMutex
+
+	serialLck  sync.Mutex
+	nextSerial uint32
+	serialUsed map[uint32]bool
+
+	calls    map[uint32]*Call
+	callsLck sync.RWMutex
+
+	handlers    map[ObjectPath]map[string]interface{}
+	handlersLck sync.RWMutex
+
+	out    chan *Message
+	closed bool
+	outLck sync.RWMutex
+
+	signals    []chan<- *Signal
+	signalsLck sync.Mutex
+
+	eavesdropped    chan<- *Message
+	eavesdroppedLck sync.Mutex
+}
+
+// SessionBus returns a shared connection to the session bus, connecting to it
+// if not already done.
+func SessionBus() (conn *Conn, err error) {
+	sessionBusLck.Lock()
+	defer sessionBusLck.Unlock()
+	if sessionBus != nil {
+		return sessionBus, nil
+	}
+	defer func() {
+		if conn != nil {
+			sessionBus = conn
+		}
+	}()
+	conn, err = SessionBusPrivate()
+	if err != nil {
+		return
+	}
+	if err = conn.Auth(nil); err != nil {
+		conn.Close()
+		conn = nil
+		return
+	}
+	if err = conn.Hello(); err != nil {
+		conn.Close()
+		conn = nil
+	}
+	return
+}
+
+// SessionBusPrivate returns a new private connection to the session bus.
+func SessionBusPrivate() (*Conn, error) {
+	address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
+	if address != "" && address != "autolaunch:" {
+		return Dial(address)
+	}
+
+	return sessionBusPlatform()
+}
+
+// SystemBus returns a shared connection to the system bus, connecting to it if
+// not already done.
+func SystemBus() (conn *Conn, err error) {
+	systemBusLck.Lock()
+	defer systemBusLck.Unlock()
+	if systemBus != nil {
+		return systemBus, nil
+	}
+	defer func() {
+		if conn != nil {
+			systemBus = conn
+		}
+	}()
+	conn, err = SystemBusPrivate()
+	if err != nil {
+		return
+	}
+	if err = conn.Auth(nil); err != nil {
+		conn.Close()
+		conn = nil
+		return
+	}
+	if err = conn.Hello(); err != nil {
+		conn.Close()
+		conn = nil
+	}
+	return
+}
+
+// SystemBusPrivate returns a new private connection to the system bus.
+func SystemBusPrivate() (*Conn, error) {
+	address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
+	if address != "" {
+		return Dial(address)
+	}
+	return Dial(defaultSystemBusAddress)
+}
+
+// Dial establishes a new private connection to the message bus specified by address.
+func Dial(address string) (*Conn, error) {
+	tr, err := getTransport(address)
+	if err != nil {
+		return nil, err
+	}
+	return newConn(tr)
+}
+
+// NewConn creates a new private *Conn from an already established connection.
+func NewConn(conn io.ReadWriteCloser) (*Conn, error) {
+	return newConn(genericTransport{conn})
+}
+
+// newConn creates a new *Conn from a transport.
+func newConn(tr transport) (*Conn, error) {
+	conn := new(Conn)
+	conn.transport = tr
+	conn.calls = make(map[uint32]*Call)
+	conn.out = make(chan *Message, 10)
+	conn.handlers = make(map[ObjectPath]map[string]interface{})
+	conn.nextSerial = 1
+	conn.serialUsed = map[uint32]bool{0: true}
+	conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
+	return conn, nil
+}
+
+// BusObject returns the object owned by the bus daemon which handles
+// administrative requests.
+func (conn *Conn) BusObject() *Object {
+	return conn.busObj
+}
+
+// Close closes the connection. Any blocked operations will return with errors
+// and the channels passed to Eavesdrop and Signal are closed. This method must
+// not be called on shared connections.
+func (conn *Conn) Close() error {
+	conn.outLck.Lock()
+	close(conn.out)
+	conn.closed = true
+	conn.outLck.Unlock()
+	conn.signalsLck.Lock()
+	for _, ch := range conn.signals {
+		close(ch)
+	}
+	conn.signalsLck.Unlock()
+	conn.eavesdroppedLck.Lock()
+	if conn.eavesdropped != nil {
+		close(conn.eavesdropped)
+	}
+	conn.eavesdroppedLck.Unlock()
+	return conn.transport.Close()
+}
+
+// Eavesdrop causes conn to send all incoming messages to the given channel
+// without further processing. Method replies, errors and signals will not be
+// sent to the appropiate channels and method calls will not be handled. If nil
+// is passed, the normal behaviour is restored.
+//
+// The caller has to make sure that ch is sufficiently buffered;
+// if a message arrives when a write to ch is not possible, the message is
+// discarded.
+func (conn *Conn) Eavesdrop(ch chan<- *Message) {
+	conn.eavesdroppedLck.Lock()
+	conn.eavesdropped = ch
+	conn.eavesdroppedLck.Unlock()
+}
+
+// getSerial returns an unused serial.
+func (conn *Conn) getSerial() uint32 {
+	conn.serialLck.Lock()
+	defer conn.serialLck.Unlock()
+	n := conn.nextSerial
+	for conn.serialUsed[n] {
+		n++
+	}
+	conn.serialUsed[n] = true
+	conn.nextSerial = n + 1
+	return n
+}
+
+// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
+// called after authentication, but before sending any other messages to the
+// bus. Hello must not be called for shared connections.
+func (conn *Conn) Hello() error {
+	var s string
+	err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
+	if err != nil {
+		return err
+	}
+	conn.namesLck.Lock()
+	conn.names = make([]string, 1)
+	conn.names[0] = s
+	conn.namesLck.Unlock()
+	return nil
+}
+
+// inWorker runs in an own goroutine, reading incoming messages from the
+// transport and dispatching them appropiately.
+func (conn *Conn) inWorker() {
+	for {
+		msg, err := conn.ReadMessage()
+		if err == nil {
+			conn.eavesdroppedLck.Lock()
+			if conn.eavesdropped != nil {
+				select {
+				case conn.eavesdropped <- msg:
+				default:
+				}
+				conn.eavesdroppedLck.Unlock()
+				continue
+			}
+			conn.eavesdroppedLck.Unlock()
+			dest, _ := msg.Headers[FieldDestination].value.(string)
+			found := false
+			if dest == "" {
+				found = true
+			} else {
+				conn.namesLck.RLock()
+				if len(conn.names) == 0 {
+					found = true
+				}
+				for _, v := range conn.names {
+					if dest == v {
+						found = true
+						break
+					}
+				}
+				conn.namesLck.RUnlock()
+			}
+			if !found {
+				// Eavesdropped a message, but no channel for it is registered.
+				// Ignore it.
+				continue
+			}
+			switch msg.Type {
+			case TypeMethodReply, TypeError:
+				serial := msg.Headers[FieldReplySerial].value.(uint32)
+				conn.callsLck.Lock()
+				if c, ok := conn.calls[serial]; ok {
+					if msg.Type == TypeError {
+						name, _ := msg.Headers[FieldErrorName].value.(string)
+						c.Err = Error{name, msg.Body}
+					} else {
+						c.Body = msg.Body
+					}
+					c.Done <- c
+					conn.serialLck.Lock()
+					delete(conn.serialUsed, serial)
+					conn.serialLck.Unlock()
+					delete(conn.calls, serial)
+				}
+				conn.callsLck.Unlock()
+			case TypeSignal:
+				iface := msg.Headers[FieldInterface].value.(string)
+				member := msg.Headers[FieldMember].value.(string)
+				// as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
+				// sender is optional for signals.
+				sender, _ := msg.Headers[FieldSender].value.(string)
+				if iface == "org.freedesktop.DBus" && member == "NameLost" &&
+					sender == "org.freedesktop.DBus" {
+
+					name, _ := msg.Body[0].(string)
+					conn.namesLck.Lock()
+					for i, v := range conn.names {
+						if v == name {
+							copy(conn.names[i:], conn.names[i+1:])
+							conn.names = conn.names[:len(conn.names)-1]
+						}
+					}
+					conn.namesLck.Unlock()
+				}
+				signal := &Signal{
+					Sender: sender,
+					Path:   msg.Headers[FieldPath].value.(ObjectPath),
+					Name:   iface + "." + member,
+					Body:   msg.Body,
+				}
+				conn.signalsLck.Lock()
+				for _, ch := range conn.signals {
+					// don't block trying to send a signal
+					select {
+					case ch <- signal:
+					default:
+					}
+				}
+				conn.signalsLck.Unlock()
+			case TypeMethodCall:
+				go conn.handleCall(msg)
+			}
+		} else if _, ok := err.(InvalidMessageError); !ok {
+			// Some read error occured (usually EOF); we can't really do
+			// anything but to shut down all stuff and returns errors to all
+			// pending replies.
+			conn.Close()
+			conn.callsLck.RLock()
+			for _, v := range conn.calls {
+				v.Err = err
+				v.Done <- v
+			}
+			conn.callsLck.RUnlock()
+			return
+		}
+		// invalid messages are ignored
+	}
+}
+
+// Names returns the list of all names that are currently owned by this
+// connection. The slice is always at least one element long, the first element
+// being the unique name of the connection.
+func (conn *Conn) Names() []string {
+	conn.namesLck.RLock()
+	// copy the slice so it can't be modified
+	s := make([]string, len(conn.names))
+	copy(s, conn.names)
+	conn.namesLck.RUnlock()
+	return s
+}
+
+// Object returns the object identified by the given destination name and path.
+func (conn *Conn) Object(dest string, path ObjectPath) *Object {
+	return &Object{conn, dest, path}
+}
+
+// outWorker runs in an own goroutine, encoding and sending messages that are
+// sent to conn.out.
+func (conn *Conn) outWorker() {
+	for msg := range conn.out {
+		err := conn.SendMessage(msg)
+		conn.callsLck.RLock()
+		if err != nil {
+			if c := conn.calls[msg.serial]; c != nil {
+				c.Err = err
+				c.Done <- c
+			}
+			conn.serialLck.Lock()
+			delete(conn.serialUsed, msg.serial)
+			conn.serialLck.Unlock()
+		} else if msg.Type != TypeMethodCall {
+			conn.serialLck.Lock()
+			delete(conn.serialUsed, msg.serial)
+			conn.serialLck.Unlock()
+		}
+		conn.callsLck.RUnlock()
+	}
+}
+
+// Send sends the given message to the message bus. You usually don't need to
+// use this; use the higher-level equivalents (Call / Go, Emit and Export)
+// instead. If msg is a method call and NoReplyExpected is not set, a non-nil
+// call is returned and the same value is sent to ch (which must be buffered)
+// once the call is complete. Otherwise, ch is ignored and a Call structure is
+// returned of which only the Err member is valid.
+func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
+	var call *Call
+
+	msg.serial = conn.getSerial()
+	if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
+		if ch == nil {
+			ch = make(chan *Call, 5)
+		} else if cap(ch) == 0 {
+			panic("dbus: unbuffered channel passed to (*Conn).Send")
+		}
+		call = new(Call)
+		call.Destination, _ = msg.Headers[FieldDestination].value.(string)
+		call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
+		iface, _ := msg.Headers[FieldInterface].value.(string)
+		member, _ := msg.Headers[FieldMember].value.(string)
+		call.Method = iface + "." + member
+		call.Args = msg.Body
+		call.Done = ch
+		conn.callsLck.Lock()
+		conn.calls[msg.serial] = call
+		conn.callsLck.Unlock()
+		conn.outLck.RLock()
+		if conn.closed {
+			call.Err = ErrClosed
+			call.Done <- call
+		} else {
+			conn.out <- msg
+		}
+		conn.outLck.RUnlock()
+	} else {
+		conn.outLck.RLock()
+		if conn.closed {
+			call = &Call{Err: ErrClosed}
+		} else {
+			conn.out <- msg
+			call = &Call{Err: nil}
+		}
+		conn.outLck.RUnlock()
+	}
+	return call
+}
+
+// sendError creates an error message corresponding to the parameters and sends
+// it to conn.out.
+func (conn *Conn) sendError(e Error, dest string, serial uint32) {
+	msg := new(Message)
+	msg.Type = TypeError
+	msg.serial = conn.getSerial()
+	msg.Headers = make(map[HeaderField]Variant)
+	if dest != "" {
+		msg.Headers[FieldDestination] = MakeVariant(dest)
+	}
+	msg.Headers[FieldErrorName] = MakeVariant(e.Name)
+	msg.Headers[FieldReplySerial] = MakeVariant(serial)
+	msg.Body = e.Body
+	if len(e.Body) > 0 {
+		msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
+	}
+	conn.outLck.RLock()
+	if !conn.closed {
+		conn.out <- msg
+	}
+	conn.outLck.RUnlock()
+}
+
+// sendReply creates a method reply message corresponding to the parameters and
+// sends it to conn.out.
+func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
+	msg := new(Message)
+	msg.Type = TypeMethodReply
+	msg.serial = conn.getSerial()
+	msg.Headers = make(map[HeaderField]Variant)
+	if dest != "" {
+		msg.Headers[FieldDestination] = MakeVariant(dest)
+	}
+	msg.Headers[FieldReplySerial] = MakeVariant(serial)
+	msg.Body = values
+	if len(values) > 0 {
+		msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
+	}
+	conn.outLck.RLock()
+	if !conn.closed {
+		conn.out <- msg
+	}
+	conn.outLck.RUnlock()
+}
+
+// Signal registers the given channel to be passed all received signal messages.
+// The caller has to make sure that ch is sufficiently buffered; if a message
+// arrives when a write to c is not possible, it is discarded.
+//
+// Multiple of these channels can be registered at the same time. Passing a
+// channel that already is registered will remove it from the list of the
+// registered channels.
+//
+// These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
+// channel for eavesdropped messages, this channel receives all signals, and
+// none of the channels passed to Signal will receive any signals.
+func (conn *Conn) Signal(ch chan<- *Signal) {
+	conn.signalsLck.Lock()
+	conn.signals = append(conn.signals, ch)
+	conn.signalsLck.Unlock()
+}
+
+// SupportsUnixFDs returns whether the underlying transport supports passing of
+// unix file descriptors. If this is false, method calls containing unix file
+// descriptors will return an error and emitted signals containing them will
+// not be sent.
+func (conn *Conn) SupportsUnixFDs() bool {
+	return conn.unixFD
+}
+
+// Error represents a D-Bus message of type Error.
+type Error struct {
+	Name string
+	Body []interface{}
+}
+
+func (e Error) Error() string {
+	if len(e.Body) >= 1 {
+		s, ok := e.Body[0].(string)
+		if ok {
+			return s
+		}
+	}
+	return e.Name
+}
+
+// Signal represents a D-Bus message of type Signal. The name member is given in
+// "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
+type Signal struct {
+	Sender string
+	Path   ObjectPath
+	Name   string
+	Body   []interface{}
+}
+
+// transport is a D-Bus transport.
+type transport interface {
+	// Read and Write raw data (for example, for the authentication protocol).
+	io.ReadWriteCloser
+
+	// Send the initial null byte used for the EXTERNAL mechanism.
+	SendNullByte() error
+
+	// Returns whether this transport supports passing Unix FDs.
+	SupportsUnixFDs() bool
+
+	// Signal the transport that Unix FD passing is enabled for this connection.
+	EnableUnixFDs()
+
+	// Read / send a message, handling things like Unix FDs.
+	ReadMessage() (*Message, error)
+	SendMessage(*Message) error
+}
+
+func getTransport(address string) (transport, error) {
+	var err error
+	var t transport
+
+	m := map[string]func(string) (transport, error){
+		"unix": newUnixTransport,
+	}
+	addresses := strings.Split(address, ";")
+	for _, v := range addresses {
+		i := strings.IndexRune(v, ':')
+		if i == -1 {
+			err = errors.New("dbus: invalid bus address (no transport)")
+			continue
+		}
+		f := m[v[:i]]
+		if f == nil {
+			err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
+		}
+		t, err = f(v[i+1:])
+		if err == nil {
+			return t, nil
+		}
+	}
+	return nil, err
+}
+
+// dereferenceAll returns a slice that, assuming that vs is a slice of pointers
+// of arbitrary types, containes the values that are obtained from dereferencing
+// all elements in vs.
+func dereferenceAll(vs []interface{}) []interface{} {
+	for i := range vs {
+		v := reflect.ValueOf(vs[i])
+		v = v.Elem()
+		vs[i] = v.Interface()
+	}
+	return vs
+}
+
+// getKey gets a key from a the list of keys. Returns "" on error / not found...
+func getKey(s, key string) string {
+	i := strings.Index(s, key)
+	if i == -1 {
+		return ""
+	}
+	if i+len(key)+1 >= len(s) || s[i+len(key)] != '=' {
+		return ""
+	}
+	j := strings.Index(s, ",")
+	if j == -1 {
+		j = len(s)
+	}
+	return s[i+len(key)+1 : j]
+}

+ 21 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_darwin.go

@@ -0,0 +1,21 @@
+package dbus
+
+import (
+	"errors"
+	"os/exec"
+)
+
+func sessionBusPlatform() (*Conn, error) {
+	cmd := exec.Command("launchctl", "getenv", "DBUS_LAUNCHD_SESSION_BUS_SOCKET")
+	b, err := cmd.CombinedOutput()
+
+	if err != nil {
+		return nil, err
+	}
+
+	if len(b) == 0 {
+		return nil, errors.New("dbus: couldn't determine address of session bus")
+	}
+
+	return Dial("unix:path=" + string(b[:len(b)-1]))
+}

+ 27 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_other.go

@@ -0,0 +1,27 @@
+// +build !darwin
+
+package dbus
+
+import (
+	"bytes"
+	"errors"
+	"os/exec"
+)
+
+func sessionBusPlatform() (*Conn, error) {
+	cmd := exec.Command("dbus-launch")
+	b, err := cmd.CombinedOutput()
+
+	if err != nil {
+		return nil, err
+	}
+
+	i := bytes.IndexByte(b, '=')
+	j := bytes.IndexByte(b, '\n')
+
+	if i == -1 || j == -1 {
+		return nil, errors.New("dbus: couldn't determine address of session bus")
+	}
+
+	return Dial(string(b[i+1 : j]))
+}

+ 199 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/conn_test.go

@@ -0,0 +1,199 @@
+package dbus
+
+import "testing"
+
+func TestSessionBus(t *testing.T) {
+	_, err := SessionBus()
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestSystemBus(t *testing.T) {
+	_, err := SystemBus()
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestSend(t *testing.T) {
+	bus, err := SessionBus()
+	if err != nil {
+		t.Error(err)
+	}
+	ch := make(chan *Call, 1)
+	msg := &Message{
+		Type:  TypeMethodCall,
+		Flags: 0,
+		Headers: map[HeaderField]Variant{
+			FieldDestination: MakeVariant(bus.Names()[0]),
+			FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/DBus")),
+			FieldInterface:   MakeVariant("org.freedesktop.DBus.Peer"),
+			FieldMember:      MakeVariant("Ping"),
+		},
+	}
+	call := bus.Send(msg, ch)
+	<-ch
+	if call.Err != nil {
+		t.Error(call.Err)
+	}
+}
+
+type server struct{}
+
+func (server) Double(i int64) (int64, *Error) {
+	return 2 * i, nil
+}
+
+func BenchmarkCall(b *testing.B) {
+	b.StopTimer()
+	var s string
+	bus, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+	name := bus.Names()[0]
+	obj := bus.BusObject()
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		err := obj.Call("org.freedesktop.DBus.GetNameOwner", 0, name).Store(&s)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if s != name {
+			b.Errorf("got %s, wanted %s", s, name)
+		}
+	}
+}
+
+func BenchmarkCallAsync(b *testing.B) {
+	b.StopTimer()
+	bus, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+	name := bus.Names()[0]
+	obj := bus.BusObject()
+	c := make(chan *Call, 50)
+	done := make(chan struct{})
+	go func() {
+		for i := 0; i < b.N; i++ {
+			v := <-c
+			if v.Err != nil {
+				b.Error(v.Err)
+			}
+			s := v.Body[0].(string)
+			if s != name {
+				b.Errorf("got %s, wanted %s", s, name)
+			}
+		}
+		close(done)
+	}()
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		obj.Go("org.freedesktop.DBus.GetNameOwner", 0, c, name)
+	}
+	<-done
+}
+
+func BenchmarkServe(b *testing.B) {
+	b.StopTimer()
+	srv, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+	cli, err := SessionBusPrivate()
+	if err != nil {
+		b.Fatal(err)
+	}
+	if err = cli.Auth(nil); err != nil {
+		b.Fatal(err)
+	}
+	if err = cli.Hello(); err != nil {
+		b.Fatal(err)
+	}
+	benchmarkServe(b, srv, cli)
+}
+
+func BenchmarkServeAsync(b *testing.B) {
+	b.StopTimer()
+	srv, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+	cli, err := SessionBusPrivate()
+	if err != nil {
+		b.Fatal(err)
+	}
+	if err = cli.Auth(nil); err != nil {
+		b.Fatal(err)
+	}
+	if err = cli.Hello(); err != nil {
+		b.Fatal(err)
+	}
+	benchmarkServeAsync(b, srv, cli)
+}
+
+func BenchmarkServeSameConn(b *testing.B) {
+	b.StopTimer()
+	bus, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	benchmarkServe(b, bus, bus)
+}
+
+func BenchmarkServeSameConnAsync(b *testing.B) {
+	b.StopTimer()
+	bus, err := SessionBus()
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	benchmarkServeAsync(b, bus, bus)
+}
+
+func benchmarkServe(b *testing.B, srv, cli *Conn) {
+	var r int64
+	var err error
+	dest := srv.Names()[0]
+	srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
+	obj := cli.Object(dest, "/org/guelfey/DBus/Test")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		err = obj.Call("org.guelfey.DBus.Test.Double", 0, int64(i)).Store(&r)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if r != 2*int64(i) {
+			b.Errorf("got %d, wanted %d", r, 2*int64(i))
+		}
+	}
+}
+
+func benchmarkServeAsync(b *testing.B, srv, cli *Conn) {
+	dest := srv.Names()[0]
+	srv.Export(server{}, "/org/guelfey/DBus/Test", "org.guelfey.DBus.Test")
+	obj := cli.Object(dest, "/org/guelfey/DBus/Test")
+	c := make(chan *Call, 50)
+	done := make(chan struct{})
+	go func() {
+		for i := 0; i < b.N; i++ {
+			v := <-c
+			if v.Err != nil {
+				b.Fatal(v.Err)
+			}
+			i, r := v.Args[0].(int64), v.Body[0].(int64)
+			if 2*i != r {
+				b.Errorf("got %d, wanted %d", r, 2*i)
+			}
+		}
+		close(done)
+	}()
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		obj.Go("org.guelfey.DBus.Test.Double", 0, c, int64(i))
+	}
+	<-done
+}

+ 258 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/dbus.go

@@ -0,0 +1,258 @@
+package dbus
+
+import (
+	"errors"
+	"reflect"
+	"strings"
+)
+
+var (
+	byteType        = reflect.TypeOf(byte(0))
+	boolType        = reflect.TypeOf(false)
+	uint8Type       = reflect.TypeOf(uint8(0))
+	int16Type       = reflect.TypeOf(int16(0))
+	uint16Type      = reflect.TypeOf(uint16(0))
+	int32Type       = reflect.TypeOf(int32(0))
+	uint32Type      = reflect.TypeOf(uint32(0))
+	int64Type       = reflect.TypeOf(int64(0))
+	uint64Type      = reflect.TypeOf(uint64(0))
+	float64Type     = reflect.TypeOf(float64(0))
+	stringType      = reflect.TypeOf("")
+	signatureType   = reflect.TypeOf(Signature{""})
+	objectPathType  = reflect.TypeOf(ObjectPath(""))
+	variantType     = reflect.TypeOf(Variant{Signature{""}, nil})
+	interfacesType  = reflect.TypeOf([]interface{}{})
+	unixFDType      = reflect.TypeOf(UnixFD(0))
+	unixFDIndexType = reflect.TypeOf(UnixFDIndex(0))
+)
+
+// An InvalidTypeError signals that a value which cannot be represented in the
+// D-Bus wire format was passed to a function.
+type InvalidTypeError struct {
+	Type reflect.Type
+}
+
+func (e InvalidTypeError) Error() string {
+	return "dbus: invalid type " + e.Type.String()
+}
+
+// Store copies the values contained in src to dest, which must be a slice of
+// pointers. It converts slices of interfaces from src to corresponding structs
+// in dest. An error is returned if the lengths of src and dest or the types of
+// their elements don't match.
+func Store(src []interface{}, dest ...interface{}) error {
+	if len(src) != len(dest) {
+		return errors.New("dbus.Store: length mismatch")
+	}
+
+	for i := range src {
+		if err := store(src[i], dest[i]); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func store(src, dest interface{}) error {
+	if reflect.TypeOf(dest).Elem() == reflect.TypeOf(src) {
+		reflect.ValueOf(dest).Elem().Set(reflect.ValueOf(src))
+		return nil
+	} else if hasStruct(dest) {
+		rv := reflect.ValueOf(dest).Elem()
+		switch rv.Kind() {
+		case reflect.Struct:
+			vs, ok := src.([]interface{})
+			if !ok {
+				return errors.New("dbus.Store: type mismatch")
+			}
+			t := rv.Type()
+			ndest := make([]interface{}, 0, rv.NumField())
+			for i := 0; i < rv.NumField(); i++ {
+				field := t.Field(i)
+				if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
+					ndest = append(ndest, rv.Field(i).Addr().Interface())
+				}
+			}
+			if len(vs) != len(ndest) {
+				return errors.New("dbus.Store: type mismatch")
+			}
+			err := Store(vs, ndest...)
+			if err != nil {
+				return errors.New("dbus.Store: type mismatch")
+			}
+		case reflect.Slice:
+			sv := reflect.ValueOf(src)
+			if sv.Kind() != reflect.Slice {
+				return errors.New("dbus.Store: type mismatch")
+			}
+			rv.Set(reflect.MakeSlice(rv.Type(), sv.Len(), sv.Len()))
+			for i := 0; i < sv.Len(); i++ {
+				if err := store(sv.Index(i).Interface(), rv.Index(i).Addr().Interface()); err != nil {
+					return err
+				}
+			}
+		case reflect.Map:
+			sv := reflect.ValueOf(src)
+			if sv.Kind() != reflect.Map {
+				return errors.New("dbus.Store: type mismatch")
+			}
+			keys := sv.MapKeys()
+			rv.Set(reflect.MakeMap(sv.Type()))
+			for _, key := range keys {
+				v := reflect.New(sv.Type().Elem())
+				if err := store(v, sv.MapIndex(key).Interface()); err != nil {
+					return err
+				}
+				rv.SetMapIndex(key, v.Elem())
+			}
+		default:
+			return errors.New("dbus.Store: type mismatch")
+		}
+		return nil
+	} else {
+		return errors.New("dbus.Store: type mismatch")
+	}
+}
+
+func hasStruct(v interface{}) bool {
+	t := reflect.TypeOf(v)
+	for {
+		switch t.Kind() {
+		case reflect.Struct:
+			return true
+		case reflect.Slice, reflect.Ptr, reflect.Map:
+			t = t.Elem()
+		default:
+			return false
+		}
+	}
+}
+
+// An ObjectPath is an object path as defined by the D-Bus spec.
+type ObjectPath string
+
+// IsValid returns whether the object path is valid.
+func (o ObjectPath) IsValid() bool {
+	s := string(o)
+	if len(s) == 0 {
+		return false
+	}
+	if s[0] != '/' {
+		return false
+	}
+	if s[len(s)-1] == '/' && len(s) != 1 {
+		return false
+	}
+	// probably not used, but technically possible
+	if s == "/" {
+		return true
+	}
+	split := strings.Split(s[1:], "/")
+	for _, v := range split {
+		if len(v) == 0 {
+			return false
+		}
+		for _, c := range v {
+			if !isMemberChar(c) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// A UnixFD is a Unix file descriptor sent over the wire. See the package-level
+// documentation for more information about Unix file descriptor passsing.
+type UnixFD int32
+
+// A UnixFDIndex is the representation of a Unix file descriptor in a message.
+type UnixFDIndex uint32
+
+// alignment returns the alignment of values of type t.
+func alignment(t reflect.Type) int {
+	switch t {
+	case variantType:
+		return 1
+	case objectPathType:
+		return 4
+	case signatureType:
+		return 1
+	case interfacesType: // sometimes used for structs
+		return 8
+	}
+	switch t.Kind() {
+	case reflect.Uint8:
+		return 1
+	case reflect.Uint16, reflect.Int16:
+		return 2
+	case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map:
+		return 4
+	case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
+		return 8
+	case reflect.Ptr:
+		return alignment(t.Elem())
+	}
+	return 1
+}
+
+// isKeyType returns whether t is a valid type for a D-Bus dict.
+func isKeyType(t reflect.Type) bool {
+	switch t.Kind() {
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+		reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
+		reflect.String:
+
+		return true
+	}
+	return false
+}
+
+// isValidInterface returns whether s is a valid name for an interface.
+func isValidInterface(s string) bool {
+	if len(s) == 0 || len(s) > 255 || s[0] == '.' {
+		return false
+	}
+	elem := strings.Split(s, ".")
+	if len(elem) < 2 {
+		return false
+	}
+	for _, v := range elem {
+		if len(v) == 0 {
+			return false
+		}
+		if v[0] >= '0' && v[0] <= '9' {
+			return false
+		}
+		for _, c := range v {
+			if !isMemberChar(c) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// isValidMember returns whether s is a valid name for a member.
+func isValidMember(s string) bool {
+	if len(s) == 0 || len(s) > 255 {
+		return false
+	}
+	i := strings.Index(s, ".")
+	if i != -1 {
+		return false
+	}
+	if s[0] >= '0' && s[0] <= '9' {
+		return false
+	}
+	for _, c := range s {
+		if !isMemberChar(c) {
+			return false
+		}
+	}
+	return true
+}
+
+func isMemberChar(c rune) bool {
+	return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
+		(c >= 'a' && c <= 'z') || c == '_'
+}

+ 228 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/decoder.go

@@ -0,0 +1,228 @@
+package dbus
+
+import (
+	"encoding/binary"
+	"io"
+	"reflect"
+)
+
+type decoder struct {
+	in    io.Reader
+	order binary.ByteOrder
+	pos   int
+}
+
+// newDecoder returns a new decoder that reads values from in. The input is
+// expected to be in the given byte order.
+func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
+	dec := new(decoder)
+	dec.in = in
+	dec.order = order
+	return dec
+}
+
+// align aligns the input to the given boundary and panics on error.
+func (dec *decoder) align(n int) {
+	if dec.pos%n != 0 {
+		newpos := (dec.pos + n - 1) & ^(n - 1)
+		empty := make([]byte, newpos-dec.pos)
+		if _, err := io.ReadFull(dec.in, empty); err != nil {
+			panic(err)
+		}
+		dec.pos = newpos
+	}
+}
+
+// Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
+func (dec *decoder) binread(v interface{}) {
+	if err := binary.Read(dec.in, dec.order, v); err != nil {
+		panic(err)
+	}
+}
+
+func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
+	defer func() {
+		var ok bool
+		v := recover()
+		if err, ok = v.(error); ok {
+			if err == io.EOF || err == io.ErrUnexpectedEOF {
+				err = FormatError("unexpected EOF")
+			}
+		}
+	}()
+	vs = make([]interface{}, 0)
+	s := sig.str
+	for s != "" {
+		err, rem := validSingle(s, 0)
+		if err != nil {
+			return nil, err
+		}
+		v := dec.decode(s[:len(s)-len(rem)], 0)
+		vs = append(vs, v)
+		s = rem
+	}
+	return vs, nil
+}
+
+func (dec *decoder) decode(s string, depth int) interface{} {
+	dec.align(alignment(typeFor(s)))
+	switch s[0] {
+	case 'y':
+		var b [1]byte
+		if _, err := dec.in.Read(b[:]); err != nil {
+			panic(err)
+		}
+		dec.pos++
+		return b[0]
+	case 'b':
+		i := dec.decode("u", depth).(uint32)
+		switch {
+		case i == 0:
+			return false
+		case i == 1:
+			return true
+		default:
+			panic(FormatError("invalid value for boolean"))
+		}
+	case 'n':
+		var i int16
+		dec.binread(&i)
+		dec.pos += 2
+		return i
+	case 'i':
+		var i int32
+		dec.binread(&i)
+		dec.pos += 4
+		return i
+	case 'x':
+		var i int64
+		dec.binread(&i)
+		dec.pos += 8
+		return i
+	case 'q':
+		var i uint16
+		dec.binread(&i)
+		dec.pos += 2
+		return i
+	case 'u':
+		var i uint32
+		dec.binread(&i)
+		dec.pos += 4
+		return i
+	case 't':
+		var i uint64
+		dec.binread(&i)
+		dec.pos += 8
+		return i
+	case 'd':
+		var f float64
+		dec.binread(&f)
+		dec.pos += 8
+		return f
+	case 's':
+		length := dec.decode("u", depth).(uint32)
+		b := make([]byte, int(length)+1)
+		if _, err := io.ReadFull(dec.in, b); err != nil {
+			panic(err)
+		}
+		dec.pos += int(length) + 1
+		return string(b[:len(b)-1])
+	case 'o':
+		return ObjectPath(dec.decode("s", depth).(string))
+	case 'g':
+		length := dec.decode("y", depth).(byte)
+		b := make([]byte, int(length)+1)
+		if _, err := io.ReadFull(dec.in, b); err != nil {
+			panic(err)
+		}
+		dec.pos += int(length) + 1
+		sig, err := ParseSignature(string(b[:len(b)-1]))
+		if err != nil {
+			panic(err)
+		}
+		return sig
+	case 'v':
+		if depth >= 64 {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		var variant Variant
+		sig := dec.decode("g", depth).(Signature)
+		if len(sig.str) == 0 {
+			panic(FormatError("variant signature is empty"))
+		}
+		err, rem := validSingle(sig.str, 0)
+		if err != nil {
+			panic(err)
+		}
+		if rem != "" {
+			panic(FormatError("variant signature has multiple types"))
+		}
+		variant.sig = sig
+		variant.value = dec.decode(sig.str, depth+1)
+		return variant
+	case 'h':
+		return UnixFDIndex(dec.decode("u", depth).(uint32))
+	case 'a':
+		if len(s) > 1 && s[1] == '{' {
+			ksig := s[2:3]
+			vsig := s[3 : len(s)-1]
+			v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
+			if depth >= 63 {
+				panic(FormatError("input exceeds container depth limit"))
+			}
+			length := dec.decode("u", depth).(uint32)
+			// Even for empty maps, the correct padding must be included
+			dec.align(8)
+			spos := dec.pos
+			for dec.pos < spos+int(length) {
+				dec.align(8)
+				if !isKeyType(v.Type().Key()) {
+					panic(InvalidTypeError{v.Type()})
+				}
+				kv := dec.decode(ksig, depth+2)
+				vv := dec.decode(vsig, depth+2)
+				v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
+			}
+			return v.Interface()
+		}
+		if depth >= 64 {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		length := dec.decode("u", depth).(uint32)
+		v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length))
+		// Even for empty arrays, the correct padding must be included
+		dec.align(alignment(typeFor(s[1:])))
+		spos := dec.pos
+		for dec.pos < spos+int(length) {
+			ev := dec.decode(s[1:], depth+1)
+			v = reflect.Append(v, reflect.ValueOf(ev))
+		}
+		return v.Interface()
+	case '(':
+		if depth >= 64 {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		dec.align(8)
+		v := make([]interface{}, 0)
+		s = s[1 : len(s)-1]
+		for s != "" {
+			err, rem := validSingle(s, 0)
+			if err != nil {
+				panic(err)
+			}
+			ev := dec.decode(s[:len(s)-len(rem)], depth+1)
+			v = append(v, ev)
+			s = rem
+		}
+		return v
+	default:
+		panic(SignatureError{Sig: s})
+	}
+}
+
+// A FormatError is an error in the wire format.
+type FormatError string
+
+func (e FormatError) Error() string {
+	return "dbus: wire format error: " + string(e)
+}

+ 63 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/doc.go

@@ -0,0 +1,63 @@
+/*
+Package dbus implements bindings to the D-Bus message bus system.
+
+To use the message bus API, you first need to connect to a bus (usually the
+session or system bus). The acquired connection then can be used to call methods
+on remote objects and emit or receive signals. Using the Export method, you can
+arrange D-Bus methods calls to be directly translated to method calls on a Go
+value.
+
+Conversion Rules
+
+For outgoing messages, Go types are automatically converted to the
+corresponding D-Bus types. The following types are directly encoded as their
+respective D-Bus equivalents:
+
+     Go type     | D-Bus type
+     ------------+-----------
+     byte        | BYTE
+     bool        | BOOLEAN
+     int16       | INT16
+     uint16      | UINT16
+     int32       | INT32
+     uint32      | UINT32
+     int64       | INT64
+     uint64      | UINT64
+     float64     | DOUBLE
+     string      | STRING
+     ObjectPath  | OBJECT_PATH
+     Signature   | SIGNATURE
+     Variant     | VARIANT
+     UnixFDIndex | UNIX_FD
+
+Slices and arrays encode as ARRAYs of their element type.
+
+Maps encode as DICTs, provided that their key type can be used as a key for
+a DICT.
+
+Structs other than Variant and Signature encode as a STRUCT containing their
+exported fields. Fields whose tags contain `dbus:"-"` and unexported fields will
+be skipped.
+
+Pointers encode as the value they're pointed to.
+
+Trying to encode any other type or a slice, map or struct containing an
+unsupported type will result in an InvalidTypeError.
+
+For incoming messages, the inverse of these rules are used, with the exception
+of STRUCTs. Incoming STRUCTS are represented as a slice of empty interfaces
+containing the struct fields in the correct order. The Store function can be
+used to convert such values to Go structs.
+
+Unix FD passing
+
+Handling Unix file descriptors deserves special mention. To use them, you should
+first check that they are supported on a connection by calling SupportsUnixFDs.
+If it returns true, all method of Connection will translate messages containing
+UnixFD's to messages that are accompanied by the given file descriptors with the
+UnixFD values being substituted by the correct indices. Similarily, the indices
+of incoming messages are automatically resolved. It shouldn't be necessary to use
+UnixFDIndex.
+
+*/
+package dbus

+ 179 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/encoder.go

@@ -0,0 +1,179 @@
+package dbus
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io"
+	"reflect"
+)
+
+// An encoder encodes values to the D-Bus wire format.
+type encoder struct {
+	out   io.Writer
+	order binary.ByteOrder
+	pos   int
+}
+
+// NewEncoder returns a new encoder that writes to out in the given byte order.
+func newEncoder(out io.Writer, order binary.ByteOrder) *encoder {
+	enc := new(encoder)
+	enc.out = out
+	enc.order = order
+	return enc
+}
+
+// Aligns the next output to be on a multiple of n. Panics on write errors.
+func (enc *encoder) align(n int) {
+	if enc.pos%n != 0 {
+		newpos := (enc.pos + n - 1) & ^(n - 1)
+		empty := make([]byte, newpos-enc.pos)
+		if _, err := enc.out.Write(empty); err != nil {
+			panic(err)
+		}
+		enc.pos = newpos
+	}
+}
+
+// Calls binary.Write(enc.out, enc.order, v) and panics on write errors.
+func (enc *encoder) binwrite(v interface{}) {
+	if err := binary.Write(enc.out, enc.order, v); err != nil {
+		panic(err)
+	}
+}
+
+// Encode encodes the given values to the underyling reader. All written values
+// are aligned properly as required by the D-Bus spec.
+func (enc *encoder) Encode(vs ...interface{}) (err error) {
+	defer func() {
+		err, _ = recover().(error)
+	}()
+	for _, v := range vs {
+		enc.encode(reflect.ValueOf(v), 0)
+	}
+	return nil
+}
+
+// encode encodes the given value to the writer and panics on error. depth holds
+// the depth of the container nesting.
+func (enc *encoder) encode(v reflect.Value, depth int) {
+	enc.align(alignment(v.Type()))
+	switch v.Kind() {
+	case reflect.Uint8:
+		var b [1]byte
+		b[0] = byte(v.Uint())
+		if _, err := enc.out.Write(b[:]); err != nil {
+			panic(err)
+		}
+		enc.pos++
+	case reflect.Bool:
+		if v.Bool() {
+			enc.encode(reflect.ValueOf(uint32(1)), depth)
+		} else {
+			enc.encode(reflect.ValueOf(uint32(0)), depth)
+		}
+	case reflect.Int16:
+		enc.binwrite(int16(v.Int()))
+		enc.pos += 2
+	case reflect.Uint16:
+		enc.binwrite(uint16(v.Uint()))
+		enc.pos += 2
+	case reflect.Int32:
+		enc.binwrite(int32(v.Int()))
+		enc.pos += 4
+	case reflect.Uint32:
+		enc.binwrite(uint32(v.Uint()))
+		enc.pos += 4
+	case reflect.Int64:
+		enc.binwrite(v.Int())
+		enc.pos += 8
+	case reflect.Uint64:
+		enc.binwrite(v.Uint())
+		enc.pos += 8
+	case reflect.Float64:
+		enc.binwrite(v.Float())
+		enc.pos += 8
+	case reflect.String:
+		enc.encode(reflect.ValueOf(uint32(len(v.String()))), depth)
+		b := make([]byte, v.Len()+1)
+		copy(b, v.String())
+		b[len(b)-1] = 0
+		n, err := enc.out.Write(b)
+		if err != nil {
+			panic(err)
+		}
+		enc.pos += n
+	case reflect.Ptr:
+		enc.encode(v.Elem(), depth)
+	case reflect.Slice, reflect.Array:
+		if depth >= 64 {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		var buf bytes.Buffer
+		bufenc := newEncoder(&buf, enc.order)
+
+		for i := 0; i < v.Len(); i++ {
+			bufenc.encode(v.Index(i), depth+1)
+		}
+		enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
+		length := buf.Len()
+		enc.align(alignment(v.Type().Elem()))
+		if _, err := buf.WriteTo(enc.out); err != nil {
+			panic(err)
+		}
+		enc.pos += length
+	case reflect.Struct:
+		if depth >= 64 && v.Type() != signatureType {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		switch t := v.Type(); t {
+		case signatureType:
+			str := v.Field(0)
+			enc.encode(reflect.ValueOf(byte(str.Len())), depth+1)
+			b := make([]byte, str.Len()+1)
+			copy(b, str.String())
+			b[len(b)-1] = 0
+			n, err := enc.out.Write(b)
+			if err != nil {
+				panic(err)
+			}
+			enc.pos += n
+		case variantType:
+			variant := v.Interface().(Variant)
+			enc.encode(reflect.ValueOf(variant.sig), depth+1)
+			enc.encode(reflect.ValueOf(variant.value), depth+1)
+		default:
+			for i := 0; i < v.Type().NumField(); i++ {
+				field := t.Field(i)
+				if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
+					enc.encode(v.Field(i), depth+1)
+				}
+			}
+		}
+	case reflect.Map:
+		// Maps are arrays of structures, so they actually increase the depth by
+		// 2.
+		if depth >= 63 {
+			panic(FormatError("input exceeds container depth limit"))
+		}
+		if !isKeyType(v.Type().Key()) {
+			panic(InvalidTypeError{v.Type()})
+		}
+		keys := v.MapKeys()
+		var buf bytes.Buffer
+		bufenc := newEncoder(&buf, enc.order)
+		for _, k := range keys {
+			bufenc.align(8)
+			bufenc.encode(k, depth+2)
+			bufenc.encode(v.MapIndex(k), depth+2)
+		}
+		enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
+		length := buf.Len()
+		enc.align(8)
+		if _, err := buf.WriteTo(enc.out); err != nil {
+			panic(err)
+		}
+		enc.pos += length
+	default:
+		panic(InvalidTypeError{v.Type()})
+	}
+}

+ 50 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/examples_test.go

@@ -0,0 +1,50 @@
+package dbus
+
+import "fmt"
+
+func ExampleConn_Emit() {
+	conn, err := SessionBus()
+	if err != nil {
+		panic(err)
+	}
+
+	conn.Emit("/foo/bar", "foo.bar.Baz", uint32(0xDAEDBEEF))
+}
+
+func ExampleObject_Call() {
+	var list []string
+
+	conn, err := SessionBus()
+	if err != nil {
+		panic(err)
+	}
+
+	err = conn.BusObject().Call("org.freedesktop.DBus.ListNames", 0).Store(&list)
+	if err != nil {
+		panic(err)
+	}
+	for _, v := range list {
+		fmt.Println(v)
+	}
+}
+
+func ExampleObject_Go() {
+	conn, err := SessionBus()
+	if err != nil {
+		panic(err)
+	}
+
+	ch := make(chan *Call, 10)
+	conn.BusObject().Go("org.freedesktop.DBus.ListActivatableNames", 0, ch)
+	select {
+	case call := <-ch:
+		if call.Err != nil {
+			panic(err)
+		}
+		list := call.Body[0].([]string)
+		for _, v := range list {
+			fmt.Println(v)
+		}
+		// put some other cases here
+	}
+}

+ 302 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/export.go

@@ -0,0 +1,302 @@
+package dbus
+
+import (
+	"errors"
+	"reflect"
+	"strings"
+	"unicode"
+)
+
+var (
+	errmsgInvalidArg = Error{
+		"org.freedesktop.DBus.Error.InvalidArgs",
+		[]interface{}{"Invalid type / number of args"},
+	}
+	errmsgNoObject = Error{
+		"org.freedesktop.DBus.Error.NoSuchObject",
+		[]interface{}{"No such object"},
+	}
+	errmsgUnknownMethod = Error{
+		"org.freedesktop.DBus.Error.UnknownMethod",
+		[]interface{}{"Unknown / invalid method"},
+	}
+)
+
+// Sender is a type which can be used in exported methods to receive the message
+// sender.
+type Sender string
+
+func exportedMethod(v interface{}, name string) reflect.Value {
+	if v == nil {
+		return reflect.Value{}
+	}
+	m := reflect.ValueOf(v).MethodByName(name)
+	if !m.IsValid() {
+		return reflect.Value{}
+	}
+	t := m.Type()
+	if t.NumOut() == 0 ||
+		t.Out(t.NumOut()-1) != reflect.TypeOf(&errmsgInvalidArg) {
+
+		return reflect.Value{}
+	}
+	return m
+}
+
+// handleCall handles the given method call (i.e. looks if it's one of the
+// pre-implemented ones and searches for a corresponding handler if not).
+func (conn *Conn) handleCall(msg *Message) {
+	name := msg.Headers[FieldMember].value.(string)
+	path := msg.Headers[FieldPath].value.(ObjectPath)
+	ifaceName, hasIface := msg.Headers[FieldInterface].value.(string)
+	sender, hasSender := msg.Headers[FieldSender].value.(string)
+	serial := msg.serial
+	if ifaceName == "org.freedesktop.DBus.Peer" {
+		switch name {
+		case "Ping":
+			conn.sendReply(sender, serial)
+		case "GetMachineId":
+			conn.sendReply(sender, serial, conn.uuid)
+		default:
+			conn.sendError(errmsgUnknownMethod, sender, serial)
+		}
+		return
+	}
+	if len(name) == 0 || unicode.IsLower([]rune(name)[0]) {
+		conn.sendError(errmsgUnknownMethod, sender, serial)
+	}
+	var m reflect.Value
+	if hasIface {
+		conn.handlersLck.RLock()
+		obj, ok := conn.handlers[path]
+		if !ok {
+			conn.sendError(errmsgNoObject, sender, serial)
+			conn.handlersLck.RUnlock()
+			return
+		}
+		iface := obj[ifaceName]
+		conn.handlersLck.RUnlock()
+		m = exportedMethod(iface, name)
+	} else {
+		conn.handlersLck.RLock()
+		if _, ok := conn.handlers[path]; !ok {
+			conn.sendError(errmsgNoObject, sender, serial)
+			conn.handlersLck.RUnlock()
+			return
+		}
+		for _, v := range conn.handlers[path] {
+			m = exportedMethod(v, name)
+			if m.IsValid() {
+				break
+			}
+		}
+		conn.handlersLck.RUnlock()
+	}
+	if !m.IsValid() {
+		conn.sendError(errmsgUnknownMethod, sender, serial)
+		return
+	}
+	t := m.Type()
+	vs := msg.Body
+	pointers := make([]interface{}, t.NumIn())
+	decode := make([]interface{}, 0, len(vs))
+	for i := 0; i < t.NumIn(); i++ {
+		tp := t.In(i)
+		val := reflect.New(tp)
+		pointers[i] = val.Interface()
+		if tp == reflect.TypeOf((*Sender)(nil)).Elem() {
+			val.Elem().SetString(sender)
+		} else {
+			decode = append(decode, pointers[i])
+		}
+	}
+	if len(decode) != len(vs) {
+		conn.sendError(errmsgInvalidArg, sender, serial)
+		return
+	}
+	if err := Store(vs, decode...); err != nil {
+		conn.sendError(errmsgInvalidArg, sender, serial)
+		return
+	}
+	params := make([]reflect.Value, len(pointers))
+	for i := 0; i < len(pointers); i++ {
+		params[i] = reflect.ValueOf(pointers[i]).Elem()
+	}
+	ret := m.Call(params)
+	if em := ret[t.NumOut()-1].Interface().(*Error); em != nil {
+		conn.sendError(*em, sender, serial)
+		return
+	}
+	if msg.Flags&FlagNoReplyExpected == 0 {
+		reply := new(Message)
+		reply.Type = TypeMethodReply
+		reply.serial = conn.getSerial()
+		reply.Headers = make(map[HeaderField]Variant)
+		if hasSender {
+			reply.Headers[FieldDestination] = msg.Headers[FieldSender]
+		}
+		reply.Headers[FieldReplySerial] = MakeVariant(msg.serial)
+		reply.Body = make([]interface{}, len(ret)-1)
+		for i := 0; i < len(ret)-1; i++ {
+			reply.Body[i] = ret[i].Interface()
+		}
+		if len(ret) != 1 {
+			reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
+		}
+		conn.outLck.RLock()
+		if !conn.closed {
+			conn.out <- reply
+		}
+		conn.outLck.RUnlock()
+	}
+}
+
+// Emit emits the given signal on the message bus. The name parameter must be
+// formatted as "interface.member", e.g., "org.freedesktop.DBus.NameLost".
+func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) error {
+	if !path.IsValid() {
+		return errors.New("dbus: invalid object path")
+	}
+	i := strings.LastIndex(name, ".")
+	if i == -1 {
+		return errors.New("dbus: invalid method name")
+	}
+	iface := name[:i]
+	member := name[i+1:]
+	if !isValidMember(member) {
+		return errors.New("dbus: invalid method name")
+	}
+	if !isValidInterface(iface) {
+		return errors.New("dbus: invalid interface name")
+	}
+	msg := new(Message)
+	msg.Type = TypeSignal
+	msg.serial = conn.getSerial()
+	msg.Headers = make(map[HeaderField]Variant)
+	msg.Headers[FieldInterface] = MakeVariant(iface)
+	msg.Headers[FieldMember] = MakeVariant(member)
+	msg.Headers[FieldPath] = MakeVariant(path)
+	msg.Body = values
+	if len(values) > 0 {
+		msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
+	}
+	conn.outLck.RLock()
+	defer conn.outLck.RUnlock()
+	if conn.closed {
+		return ErrClosed
+	}
+	conn.out <- msg
+	return nil
+}
+
+// Export registers the given value to be exported as an object on the
+// message bus.
+//
+// If a method call on the given path and interface is received, an exported
+// method with the same name is called with v as the receiver if the
+// parameters match and the last return value is of type *Error. If this
+// *Error is not nil, it is sent back to the caller as an error.
+// Otherwise, a method reply is sent with the other return values as its body.
+//
+// Any parameters with the special type Sender are set to the sender of the
+// dbus message when the method is called. Parameters of this type do not
+// contribute to the dbus signature of the method (i.e. the method is exposed
+// as if the parameters of type Sender were not there).
+//
+// Every method call is executed in a new goroutine, so the method may be called
+// in multiple goroutines at once.
+//
+// Method calls on the interface org.freedesktop.DBus.Peer will be automatically
+// handled for every object.
+//
+// Passing nil as the first parameter will cause conn to cease handling calls on
+// the given combination of path and interface.
+//
+// Export returns an error if path is not a valid path name.
+func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error {
+	if !path.IsValid() {
+		return errors.New("dbus: invalid path name")
+	}
+	conn.handlersLck.Lock()
+	if v == nil {
+		if _, ok := conn.handlers[path]; ok {
+			delete(conn.handlers[path], iface)
+			if len(conn.handlers[path]) == 0 {
+				delete(conn.handlers, path)
+			}
+		}
+		return nil
+	}
+	if _, ok := conn.handlers[path]; !ok {
+		conn.handlers[path] = make(map[string]interface{})
+	}
+	conn.handlers[path][iface] = v
+	conn.handlersLck.Unlock()
+	return nil
+}
+
+// ReleaseName calls org.freedesktop.DBus.ReleaseName. You should use only this
+// method to release a name (see below).
+func (conn *Conn) ReleaseName(name string) (ReleaseNameReply, error) {
+	var r uint32
+	err := conn.busObj.Call("org.freedesktop.DBus.ReleaseName", 0, name).Store(&r)
+	if err != nil {
+		return 0, err
+	}
+	if r == uint32(ReleaseNameReplyReleased) {
+		conn.namesLck.Lock()
+		for i, v := range conn.names {
+			if v == name {
+				copy(conn.names[i:], conn.names[i+1:])
+				conn.names = conn.names[:len(conn.names)-1]
+			}
+		}
+		conn.namesLck.Unlock()
+	}
+	return ReleaseNameReply(r), nil
+}
+
+// RequestName calls org.freedesktop.DBus.RequestName. You should use only this
+// method to request a name because package dbus needs to keep track of all
+// names that the connection has.
+func (conn *Conn) RequestName(name string, flags RequestNameFlags) (RequestNameReply, error) {
+	var r uint32
+	err := conn.busObj.Call("org.freedesktop.DBus.RequestName", 0, name, flags).Store(&r)
+	if err != nil {
+		return 0, err
+	}
+	if r == uint32(RequestNameReplyPrimaryOwner) {
+		conn.namesLck.Lock()
+		conn.names = append(conn.names, name)
+		conn.namesLck.Unlock()
+	}
+	return RequestNameReply(r), nil
+}
+
+// ReleaseNameReply is the reply to a ReleaseName call.
+type ReleaseNameReply uint32
+
+const (
+	ReleaseNameReplyReleased ReleaseNameReply = 1 + iota
+	ReleaseNameReplyNonExistent
+	ReleaseNameReplyNotOwner
+)
+
+// RequestNameFlags represents the possible flags for a RequestName call.
+type RequestNameFlags uint32
+
+const (
+	NameFlagAllowReplacement RequestNameFlags = 1 << iota
+	NameFlagReplaceExisting
+	NameFlagDoNotQueue
+)
+
+// RequestNameReply is the reply to a RequestName call.
+type RequestNameReply uint32
+
+const (
+	RequestNameReplyPrimaryOwner RequestNameReply = 1 + iota
+	RequestNameReplyInQueue
+	RequestNameReplyExists
+	RequestNameReplyAlreadyOwner
+)

+ 28 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir.go

@@ -0,0 +1,28 @@
+package dbus
+
+import (
+	"os"
+	"sync"
+)
+
+var (
+	homeDir     string
+	homeDirLock sync.Mutex
+)
+
+func getHomeDir() string {
+	homeDirLock.Lock()
+	defer homeDirLock.Unlock()
+
+	if homeDir != "" {
+		return homeDir
+	}
+
+	homeDir = os.Getenv("HOME")
+	if homeDir != "" {
+		return homeDir
+	}
+
+	homeDir = lookupHomeDir()
+	return homeDir
+}

+ 15 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_dynamic.go

@@ -0,0 +1,15 @@
+// +build !static_build
+
+package dbus
+
+import (
+	"os/user"
+)
+
+func lookupHomeDir() string {
+	u, err := user.Current()
+	if err != nil {
+		return "/"
+	}
+	return u.HomeDir
+}

+ 45 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/homedir_static.go

@@ -0,0 +1,45 @@
+// +build static_build
+
+package dbus
+
+import (
+	"bufio"
+	"os"
+	"strconv"
+	"strings"
+)
+
+func lookupHomeDir() string {
+	myUid := os.Getuid()
+
+	f, err := os.Open("/etc/passwd")
+	if err != nil {
+		return "/"
+	}
+	defer f.Close()
+
+	s := bufio.NewScanner(f)
+
+	for s.Scan() {
+		if err := s.Err(); err != nil {
+			break
+		}
+
+		line := strings.TrimSpace(s.Text())
+		if line == "" {
+			continue
+		}
+
+		parts := strings.Split(line, ":")
+
+		if len(parts) >= 6 {
+			uid, err := strconv.Atoi(parts[2])
+			if err == nil && uid == myUid {
+				return parts[5]
+			}
+		}
+	}
+
+	// Default to / if we can't get a better value
+	return "/"
+}

+ 27 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/call.go

@@ -0,0 +1,27 @@
+package introspect
+
+import (
+	"encoding/xml"
+	"github.com/godbus/dbus"
+	"strings"
+)
+
+// Call calls org.freedesktop.Introspectable.Introspect on a remote object
+// and returns the introspection data.
+func Call(o *dbus.Object) (*Node, error) {
+	var xmldata string
+	var node Node
+
+	err := o.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xmldata)
+	if err != nil {
+		return nil, err
+	}
+	err = xml.NewDecoder(strings.NewReader(xmldata)).Decode(&node)
+	if err != nil {
+		return nil, err
+	}
+	if node.Name == "" {
+		node.Name = string(o.Path())
+	}
+	return &node, nil
+}

+ 80 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspect.go

@@ -0,0 +1,80 @@
+// Package introspect provides some utilities for dealing with the DBus
+// introspection format.
+package introspect
+
+import "encoding/xml"
+
+// The introspection data for the org.freedesktop.DBus.Introspectable interface.
+var IntrospectData = Interface{
+	Name: "org.freedesktop.DBus.Introspectable",
+	Methods: []Method{
+		{
+			Name: "Introspect",
+			Args: []Arg{
+				{"out", "s", "out"},
+			},
+		},
+	},
+}
+
+// The introspection data for the org.freedesktop.DBus.Introspectable interface,
+// as a string.
+const IntrospectDataString = `
+	<interface name="org.freedesktop.DBus.Introspectable">
+		<method name="Introspect">
+			<arg name="out" direction="out" type="s"/>
+		</method>
+	</interface>
+`
+
+// Node is the root element of an introspection.
+type Node struct {
+	XMLName    xml.Name    `xml:"node"`
+	Name       string      `xml:"name,attr,omitempty"`
+	Interfaces []Interface `xml:"interface"`
+	Children   []Node      `xml:"node,omitempty"`
+}
+
+// Interface describes a DBus interface that is available on the message bus.
+type Interface struct {
+	Name        string       `xml:"name,attr"`
+	Methods     []Method     `xml:"method"`
+	Signals     []Signal     `xml:"signal"`
+	Properties  []Property   `xml:"property"`
+	Annotations []Annotation `xml:"annotation"`
+}
+
+// Method describes a Method on an Interface as retured by an introspection.
+type Method struct {
+	Name        string       `xml:"name,attr"`
+	Args        []Arg        `xml:"arg"`
+	Annotations []Annotation `xml:"annotation"`
+}
+
+// Signal describes a Signal emitted on an Interface.
+type Signal struct {
+	Name        string       `xml:"name,attr"`
+	Args        []Arg        `xml:"arg"`
+	Annotations []Annotation `xml:"annotation"`
+}
+
+// Property describes a property of an Interface.
+type Property struct {
+	Name        string       `xml:"name,attr"`
+	Type        string       `xml:"type,attr"`
+	Access      string       `xml:"access,attr"`
+	Annotations []Annotation `xml:"annotation"`
+}
+
+// Arg represents an argument of a method or a signal.
+type Arg struct {
+	Name      string `xml:"name,attr,omitempty"`
+	Type      string `xml:"type,attr"`
+	Direction string `xml:"direction,attr,omitempty"`
+}
+
+// Annotation is an annotation in the introspection format.
+type Annotation struct {
+	Name  string `xml:"name,attr"`
+	Value string `xml:"value,attr"`
+}

+ 74 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/introspect/introspectable.go

@@ -0,0 +1,74 @@
+package introspect
+
+import (
+	"encoding/xml"
+	"github.com/godbus/dbus"
+	"reflect"
+)
+
+// Introspectable implements org.freedesktop.Introspectable.
+//
+// You can create it by converting the XML-formatted introspection data from a
+// string to an Introspectable or call NewIntrospectable with a Node. Then,
+// export it as org.freedesktop.Introspectable on you object.
+type Introspectable string
+
+// NewIntrospectable returns an Introspectable that returns the introspection
+// data that corresponds to the given Node. If n.Interfaces doesn't contain the
+// data for org.freedesktop.DBus.Introspectable, it is added automatically.
+func NewIntrospectable(n *Node) Introspectable {
+	found := false
+	for _, v := range n.Interfaces {
+		if v.Name == "org.freedesktop.DBus.Introspectable" {
+			found = true
+			break
+		}
+	}
+	if !found {
+		n.Interfaces = append(n.Interfaces, IntrospectData)
+	}
+	b, err := xml.Marshal(n)
+	if err != nil {
+		panic(err)
+	}
+	return Introspectable(b)
+}
+
+// Introspect implements org.freedesktop.Introspectable.Introspect.
+func (i Introspectable) Introspect() (string, *dbus.Error) {
+	return string(i), nil
+}
+
+// Methods returns the description of the methods of v. This can be used to
+// create a Node which can be passed to NewIntrospectable.
+func Methods(v interface{}) []Method {
+	t := reflect.TypeOf(v)
+	ms := make([]Method, 0, t.NumMethod())
+	for i := 0; i < t.NumMethod(); i++ {
+		if t.Method(i).PkgPath != "" {
+			continue
+		}
+		mt := t.Method(i).Type
+		if mt.NumOut() == 0 ||
+			mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{"", nil}) {
+
+			continue
+		}
+		var m Method
+		m.Name = t.Method(i).Name
+		m.Args = make([]Arg, 0, mt.NumIn()+mt.NumOut()-2)
+		for j := 1; j < mt.NumIn(); j++ {
+			if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() {
+				arg := Arg{"", dbus.SignatureOfType(mt.In(j)).String(), "in"}
+				m.Args = append(m.Args, arg)
+			}
+		}
+		for j := 0; j < mt.NumOut()-1; j++ {
+			arg := Arg{"", dbus.SignatureOfType(mt.Out(j)).String(), "out"}
+			m.Args = append(m.Args, arg)
+		}
+		m.Annotations = make([]Annotation, 0)
+		ms = append(ms, m)
+	}
+	return ms
+}

+ 346 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/message.go

@@ -0,0 +1,346 @@
+package dbus
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"io"
+	"reflect"
+	"strconv"
+)
+
+const protoVersion byte = 1
+
+// Flags represents the possible flags of a D-Bus message.
+type Flags byte
+
+const (
+	// FlagNoReplyExpected signals that the message is not expected to generate
+	// a reply. If this flag is set on outgoing messages, any possible reply
+	// will be discarded.
+	FlagNoReplyExpected Flags = 1 << iota
+	// FlagNoAutoStart signals that the message bus should not automatically
+	// start an application when handling this message.
+	FlagNoAutoStart
+)
+
+// Type represents the possible types of a D-Bus message.
+type Type byte
+
+const (
+	TypeMethodCall Type = 1 + iota
+	TypeMethodReply
+	TypeError
+	TypeSignal
+	typeMax
+)
+
+func (t Type) String() string {
+	switch t {
+	case TypeMethodCall:
+		return "method call"
+	case TypeMethodReply:
+		return "reply"
+	case TypeError:
+		return "error"
+	case TypeSignal:
+		return "signal"
+	}
+	return "invalid"
+}
+
+// HeaderField represents the possible byte codes for the headers
+// of a D-Bus message.
+type HeaderField byte
+
+const (
+	FieldPath HeaderField = 1 + iota
+	FieldInterface
+	FieldMember
+	FieldErrorName
+	FieldReplySerial
+	FieldDestination
+	FieldSender
+	FieldSignature
+	FieldUnixFDs
+	fieldMax
+)
+
+// An InvalidMessageError describes the reason why a D-Bus message is regarded as
+// invalid.
+type InvalidMessageError string
+
+func (e InvalidMessageError) Error() string {
+	return "dbus: invalid message: " + string(e)
+}
+
+// fieldType are the types of the various header fields.
+var fieldTypes = [fieldMax]reflect.Type{
+	FieldPath:        objectPathType,
+	FieldInterface:   stringType,
+	FieldMember:      stringType,
+	FieldErrorName:   stringType,
+	FieldReplySerial: uint32Type,
+	FieldDestination: stringType,
+	FieldSender:      stringType,
+	FieldSignature:   signatureType,
+	FieldUnixFDs:     uint32Type,
+}
+
+// requiredFields lists the header fields that are required by the different
+// message types.
+var requiredFields = [typeMax][]HeaderField{
+	TypeMethodCall:  {FieldPath, FieldMember},
+	TypeMethodReply: {FieldReplySerial},
+	TypeError:       {FieldErrorName, FieldReplySerial},
+	TypeSignal:      {FieldPath, FieldInterface, FieldMember},
+}
+
+// Message represents a single D-Bus message.
+type Message struct {
+	Type
+	Flags
+	Headers map[HeaderField]Variant
+	Body    []interface{}
+
+	serial uint32
+}
+
+type header struct {
+	Field byte
+	Variant
+}
+
+// DecodeMessage tries to decode a single message in the D-Bus wire format
+// from the given reader. The byte order is figured out from the first byte.
+// The possibly returned error can be an error of the underlying reader, an
+// InvalidMessageError or a FormatError.
+func DecodeMessage(rd io.Reader) (msg *Message, err error) {
+	var order binary.ByteOrder
+	var hlength, length uint32
+	var typ, flags, proto byte
+	var headers []header
+
+	b := make([]byte, 1)
+	_, err = rd.Read(b)
+	if err != nil {
+		return
+	}
+	switch b[0] {
+	case 'l':
+		order = binary.LittleEndian
+	case 'B':
+		order = binary.BigEndian
+	default:
+		return nil, InvalidMessageError("invalid byte order")
+	}
+
+	dec := newDecoder(rd, order)
+	dec.pos = 1
+
+	msg = new(Message)
+	vs, err := dec.Decode(Signature{"yyyuu"})
+	if err != nil {
+		return nil, err
+	}
+	if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
+		return nil, err
+	}
+	msg.Type = Type(typ)
+	msg.Flags = Flags(flags)
+
+	// get the header length separately because we need it later
+	b = make([]byte, 4)
+	_, err = io.ReadFull(rd, b)
+	if err != nil {
+		return nil, err
+	}
+	binary.Read(bytes.NewBuffer(b), order, &hlength)
+	if hlength+length+16 > 1<<27 {
+		return nil, InvalidMessageError("message is too long")
+	}
+	dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order)
+	dec.pos = 12
+	vs, err = dec.Decode(Signature{"a(yv)"})
+	if err != nil {
+		return nil, err
+	}
+	if err = Store(vs, &headers); err != nil {
+		return nil, err
+	}
+
+	msg.Headers = make(map[HeaderField]Variant)
+	for _, v := range headers {
+		msg.Headers[HeaderField(v.Field)] = v.Variant
+	}
+
+	dec.align(8)
+	body := make([]byte, int(length))
+	if length != 0 {
+		_, err := io.ReadFull(rd, body)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	if err = msg.IsValid(); err != nil {
+		return nil, err
+	}
+	sig, _ := msg.Headers[FieldSignature].value.(Signature)
+	if sig.str != "" {
+		buf := bytes.NewBuffer(body)
+		dec = newDecoder(buf, order)
+		vs, err := dec.Decode(sig)
+		if err != nil {
+			return nil, err
+		}
+		msg.Body = vs
+	}
+
+	return
+}
+
+// EncodeTo encodes and sends a message to the given writer. The byte order must
+// be either binary.LittleEndian or binary.BigEndian. If the message is not
+// valid or an error occurs when writing, an error is returned.
+func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
+	if err := msg.IsValid(); err != nil {
+		return err
+	}
+	var vs [7]interface{}
+	switch order {
+	case binary.LittleEndian:
+		vs[0] = byte('l')
+	case binary.BigEndian:
+		vs[0] = byte('B')
+	default:
+		return errors.New("dbus: invalid byte order")
+	}
+	body := new(bytes.Buffer)
+	enc := newEncoder(body, order)
+	if len(msg.Body) != 0 {
+		enc.Encode(msg.Body...)
+	}
+	vs[1] = msg.Type
+	vs[2] = msg.Flags
+	vs[3] = protoVersion
+	vs[4] = uint32(len(body.Bytes()))
+	vs[5] = msg.serial
+	headers := make([]header, 0, len(msg.Headers))
+	for k, v := range msg.Headers {
+		headers = append(headers, header{byte(k), v})
+	}
+	vs[6] = headers
+	var buf bytes.Buffer
+	enc = newEncoder(&buf, order)
+	enc.Encode(vs[:]...)
+	enc.align(8)
+	body.WriteTo(&buf)
+	if buf.Len() > 1<<27 {
+		return InvalidMessageError("message is too long")
+	}
+	if _, err := buf.WriteTo(out); err != nil {
+		return err
+	}
+	return nil
+}
+
+// IsValid checks whether msg is a valid message and returns an
+// InvalidMessageError if it is not.
+func (msg *Message) IsValid() error {
+	if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected) != 0 {
+		return InvalidMessageError("invalid flags")
+	}
+	if msg.Type == 0 || msg.Type >= typeMax {
+		return InvalidMessageError("invalid message type")
+	}
+	for k, v := range msg.Headers {
+		if k == 0 || k >= fieldMax {
+			return InvalidMessageError("invalid header")
+		}
+		if reflect.TypeOf(v.value) != fieldTypes[k] {
+			return InvalidMessageError("invalid type of header field")
+		}
+	}
+	for _, v := range requiredFields[msg.Type] {
+		if _, ok := msg.Headers[v]; !ok {
+			return InvalidMessageError("missing required header")
+		}
+	}
+	if path, ok := msg.Headers[FieldPath]; ok {
+		if !path.value.(ObjectPath).IsValid() {
+			return InvalidMessageError("invalid path name")
+		}
+	}
+	if iface, ok := msg.Headers[FieldInterface]; ok {
+		if !isValidInterface(iface.value.(string)) {
+			return InvalidMessageError("invalid interface name")
+		}
+	}
+	if member, ok := msg.Headers[FieldMember]; ok {
+		if !isValidMember(member.value.(string)) {
+			return InvalidMessageError("invalid member name")
+		}
+	}
+	if errname, ok := msg.Headers[FieldErrorName]; ok {
+		if !isValidInterface(errname.value.(string)) {
+			return InvalidMessageError("invalid error name")
+		}
+	}
+	if len(msg.Body) != 0 {
+		if _, ok := msg.Headers[FieldSignature]; !ok {
+			return InvalidMessageError("missing signature")
+		}
+	}
+	return nil
+}
+
+// Serial returns the message's serial number. The returned value is only valid
+// for messages received by eavesdropping.
+func (msg *Message) Serial() uint32 {
+	return msg.serial
+}
+
+// String returns a string representation of a message similar to the format of
+// dbus-monitor.
+func (msg *Message) String() string {
+	if err := msg.IsValid(); err != nil {
+		return "<invalid>"
+	}
+	s := msg.Type.String()
+	if v, ok := msg.Headers[FieldSender]; ok {
+		s += " from " + v.value.(string)
+	}
+	if v, ok := msg.Headers[FieldDestination]; ok {
+		s += " to " + v.value.(string)
+	}
+	s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
+	if v, ok := msg.Headers[FieldReplySerial]; ok {
+		s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
+	}
+	if v, ok := msg.Headers[FieldUnixFDs]; ok {
+		s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
+	}
+	if v, ok := msg.Headers[FieldPath]; ok {
+		s += " path " + string(v.value.(ObjectPath))
+	}
+	if v, ok := msg.Headers[FieldInterface]; ok {
+		s += " interface " + v.value.(string)
+	}
+	if v, ok := msg.Headers[FieldErrorName]; ok {
+		s += " error " + v.value.(string)
+	}
+	if v, ok := msg.Headers[FieldMember]; ok {
+		s += " member " + v.value.(string)
+	}
+	if len(msg.Body) != 0 {
+		s += "\n"
+	}
+	for i, v := range msg.Body {
+		s += "  " + MakeVariant(v).String()
+		if i != len(msg.Body)-1 {
+			s += "\n"
+		}
+	}
+	return s
+}

+ 264 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/prop/prop.go

@@ -0,0 +1,264 @@
+// Package prop provides the Properties struct which can be used to implement
+// org.freedesktop.DBus.Properties.
+package prop
+
+import (
+	"github.com/godbus/dbus"
+	"github.com/godbus/dbus/introspect"
+	"sync"
+)
+
+// EmitType controls how org.freedesktop.DBus.Properties.PropertiesChanged is
+// emitted for a property. If it is EmitTrue, the signal is emitted. If it is
+// EmitInvalidates, the signal is also emitted, but the new value of the property
+// is not disclosed.
+type EmitType byte
+
+const (
+	EmitFalse EmitType = iota
+	EmitTrue
+	EmitInvalidates
+)
+
+// ErrIfaceNotFound is the error returned to peers who try to access properties
+// on interfaces that aren't found.
+var ErrIfaceNotFound = &dbus.Error{"org.freedesktop.DBus.Properties.Error.InterfaceNotFound", nil}
+
+// ErrPropNotFound is the error returned to peers trying to access properties
+// that aren't found.
+var ErrPropNotFound = &dbus.Error{"org.freedesktop.DBus.Properties.Error.PropertyNotFound", nil}
+
+// ErrReadOnly is the error returned to peers trying to set a read-only
+// property.
+var ErrReadOnly = &dbus.Error{"org.freedesktop.DBus.Properties.Error.ReadOnly", nil}
+
+// ErrInvalidArg is returned to peers if the type of the property that is being
+// changed and the argument don't match.
+var ErrInvalidArg = &dbus.Error{"org.freedesktop.DBus.Properties.Error.InvalidArg", nil}
+
+// The introspection data for the org.freedesktop.DBus.Properties interface.
+var IntrospectData = introspect.Interface{
+	Name: "org.freedesktop.DBus.Properties",
+	Methods: []introspect.Method{
+		{
+			Name: "Get",
+			Args: []introspect.Arg{
+				{"interface", "s", "in"},
+				{"property", "s", "in"},
+				{"value", "v", "out"},
+			},
+		},
+		{
+			Name: "GetAll",
+			Args: []introspect.Arg{
+				{"interface", "s", "in"},
+				{"props", "a{sv}", "out"},
+			},
+		},
+		{
+			Name: "Set",
+			Args: []introspect.Arg{
+				{"interface", "s", "in"},
+				{"property", "s", "in"},
+				{"value", "v", "in"},
+			},
+		},
+	},
+	Signals: []introspect.Signal{
+		{
+			Name: "PropertiesChanged",
+			Args: []introspect.Arg{
+				{"interface", "s", "out"},
+				{"changed_properties", "a{sv}", "out"},
+				{"invalidates_properties", "as", "out"},
+			},
+		},
+	},
+}
+
+// The introspection data for the org.freedesktop.DBus.Properties interface, as
+// a string.
+const IntrospectDataString = `
+	<interface name="org.freedesktop.DBus.Introspectable">
+		<method name="Get">
+			<arg name="interface" direction="in" type="s"/>
+			<arg name="property" direction="in" type="s"/>
+			<arg name="value" direction="out" type="v"/>
+		</method>
+		<method name="GetAll">
+			<arg name="interface" direction="in" type="s"/>
+			<arg name="props" direction="out" type="a{sv}"/>
+		</method>
+		<method name="Set">
+			<arg name="interface" direction="in" type="s"/>
+			<arg name="property" direction="in" type="s"/>
+			<arg name="value" direction="in" type="v"/>
+		</method>
+		<signal name="PropertiesChanged">
+			<arg name="interface" type="s"/>
+			<arg name="changed_properties" type="a{sv}"/>
+			<arg name="invalidates_properties" type="as"/>
+		</signal>
+	</interface>
+`
+
+// Prop represents a single property. It is used for creating a Properties
+// value.
+type Prop struct {
+	// Initial value. Must be a DBus-representable type.
+	Value interface{}
+
+	// If true, the value can be modified by calls to Set.
+	Writable bool
+
+	// Controls how org.freedesktop.DBus.Properties.PropertiesChanged is
+	// emitted if this property changes.
+	Emit EmitType
+
+	// If not nil, anytime this property is changed by Set, this function is
+	// called with an appropiate Change as its argument. If the returned error
+	// is not nil, it is sent back to the caller of Set and the property is not
+	// changed.
+	Callback func(*Change) *dbus.Error
+}
+
+// Change represents a change of a property by a call to Set.
+type Change struct {
+	Props *Properties
+	Iface string
+	Name  string
+	Value interface{}
+}
+
+// Properties is a set of values that can be made available to the message bus
+// using the org.freedesktop.DBus.Properties interface. It is safe for
+// concurrent use by multiple goroutines.
+type Properties struct {
+	m    map[string]map[string]*Prop
+	mut  sync.RWMutex
+	conn *dbus.Conn
+	path dbus.ObjectPath
+}
+
+// New returns a new Properties structure that manages the given properties.
+// The key for the first-level map of props is the name of the interface; the
+// second-level key is the name of the property. The returned structure will be
+// exported as org.freedesktop.DBus.Properties on path.
+func New(conn *dbus.Conn, path dbus.ObjectPath, props map[string]map[string]*Prop) *Properties {
+	p := &Properties{m: props, conn: conn, path: path}
+	conn.Export(p, path, "org.freedesktop.DBus.Properties")
+	return p
+}
+
+// Get implements org.freedesktop.DBus.Properties.Get.
+func (p *Properties) Get(iface, property string) (dbus.Variant, *dbus.Error) {
+	p.mut.RLock()
+	defer p.mut.RUnlock()
+	m, ok := p.m[iface]
+	if !ok {
+		return dbus.Variant{}, ErrIfaceNotFound
+	}
+	prop, ok := m[property]
+	if !ok {
+		return dbus.Variant{}, ErrPropNotFound
+	}
+	return dbus.MakeVariant(prop.Value), nil
+}
+
+// GetAll implements org.freedesktop.DBus.Properties.GetAll.
+func (p *Properties) GetAll(iface string) (map[string]dbus.Variant, *dbus.Error) {
+	p.mut.RLock()
+	defer p.mut.RUnlock()
+	m, ok := p.m[iface]
+	if !ok {
+		return nil, ErrIfaceNotFound
+	}
+	rm := make(map[string]dbus.Variant, len(m))
+	for k, v := range m {
+		rm[k] = dbus.MakeVariant(v.Value)
+	}
+	return rm, nil
+}
+
+// GetMust returns the value of the given property and panics if either the
+// interface or the property name are invalid.
+func (p *Properties) GetMust(iface, property string) interface{} {
+	p.mut.RLock()
+	defer p.mut.RUnlock()
+	return p.m[iface][property].Value
+}
+
+// Introspection returns the introspection data that represents the properties
+// of iface.
+func (p *Properties) Introspection(iface string) []introspect.Property {
+	p.mut.RLock()
+	defer p.mut.RUnlock()
+	m := p.m[iface]
+	s := make([]introspect.Property, 0, len(m))
+	for k, v := range m {
+		p := introspect.Property{Name: k, Type: dbus.SignatureOf(v.Value).String()}
+		if v.Writable {
+			p.Access = "readwrite"
+		} else {
+			p.Access = "read"
+		}
+		s = append(s, p)
+	}
+	return s
+}
+
+// set sets the given property and emits PropertyChanged if appropiate. p.mut
+// must already be locked.
+func (p *Properties) set(iface, property string, v interface{}) {
+	prop := p.m[iface][property]
+	prop.Value = v
+	switch prop.Emit {
+	case EmitFalse:
+		// do nothing
+	case EmitInvalidates:
+		p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
+			iface, map[string]dbus.Variant{}, []string{property})
+	case EmitTrue:
+		p.conn.Emit(p.path, "org.freedesktop.DBus.Properties.PropertiesChanged",
+			iface, map[string]dbus.Variant{property: dbus.MakeVariant(v)},
+			[]string{})
+	default:
+		panic("invalid value for EmitType")
+	}
+}
+
+// Set implements org.freedesktop.Properties.Set.
+func (p *Properties) Set(iface, property string, newv dbus.Variant) *dbus.Error {
+	p.mut.Lock()
+	defer p.mut.Unlock()
+	m, ok := p.m[iface]
+	if !ok {
+		return ErrIfaceNotFound
+	}
+	prop, ok := m[property]
+	if !ok {
+		return ErrPropNotFound
+	}
+	if !prop.Writable {
+		return ErrReadOnly
+	}
+	if newv.Signature() != dbus.SignatureOf(prop.Value) {
+		return ErrInvalidArg
+	}
+	if prop.Callback != nil {
+		err := prop.Callback(&Change{p, iface, property, newv.Value()})
+		if err != nil {
+			return err
+		}
+	}
+	p.set(iface, property, newv.Value())
+	return nil
+}
+
+// SetMust sets the value of the given property and panics if the interface or
+// the property name are invalid.
+func (p *Properties) SetMust(iface, property string, v interface{}) {
+	p.mut.Lock()
+	p.set(iface, property, v)
+	p.mut.Unlock()
+}

+ 369 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/proto_test.go

@@ -0,0 +1,369 @@
+package dbus
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io/ioutil"
+	"math"
+	"reflect"
+	"testing"
+)
+
+var protoTests = []struct {
+	vs           []interface{}
+	bigEndian    []byte
+	littleEndian []byte
+}{
+	{
+		[]interface{}{int32(0)},
+		[]byte{0, 0, 0, 0},
+		[]byte{0, 0, 0, 0},
+	},
+	{
+		[]interface{}{true, false},
+		[]byte{0, 0, 0, 1, 0, 0, 0, 0},
+		[]byte{1, 0, 0, 0, 0, 0, 0, 0},
+	},
+	{
+		[]interface{}{byte(0), uint16(12), int16(32), uint32(43)},
+		[]byte{0, 0, 0, 12, 0, 32, 0, 0, 0, 0, 0, 43},
+		[]byte{0, 0, 12, 0, 32, 0, 0, 0, 43, 0, 0, 0},
+	},
+	{
+		[]interface{}{int64(-1), uint64(1<<64 - 1)},
+		bytes.Repeat([]byte{255}, 16),
+		bytes.Repeat([]byte{255}, 16),
+	},
+	{
+		[]interface{}{math.Inf(+1)},
+		[]byte{0x7f, 0xf0, 0, 0, 0, 0, 0, 0},
+		[]byte{0, 0, 0, 0, 0, 0, 0xf0, 0x7f},
+	},
+	{
+		[]interface{}{"foo"},
+		[]byte{0, 0, 0, 3, 'f', 'o', 'o', 0},
+		[]byte{3, 0, 0, 0, 'f', 'o', 'o', 0},
+	},
+	{
+		[]interface{}{Signature{"ai"}},
+		[]byte{2, 'a', 'i', 0},
+		[]byte{2, 'a', 'i', 0},
+	},
+	{
+		[]interface{}{[]int16{42, 256}},
+		[]byte{0, 0, 0, 4, 0, 42, 1, 0},
+		[]byte{4, 0, 0, 0, 42, 0, 0, 1},
+	},
+	{
+		[]interface{}{MakeVariant("foo")},
+		[]byte{1, 's', 0, 0, 0, 0, 0, 3, 'f', 'o', 'o', 0},
+		[]byte{1, 's', 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0},
+	},
+	{
+		[]interface{}{MakeVariant(MakeVariant(Signature{"v"}))},
+		[]byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
+		[]byte{1, 'v', 0, 1, 'g', 0, 1, 'v', 0},
+	},
+	{
+		[]interface{}{map[int32]bool{42: true}},
+		[]byte{0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1},
+		[]byte{8, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 1, 0, 0, 0},
+	},
+	{
+		[]interface{}{map[string]Variant{}, byte(42)},
+		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+	},
+	{
+		[]interface{}{[]uint64{}, byte(42)},
+		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+		[]byte{0, 0, 0, 0, 0, 0, 0, 0, 42},
+	},
+}
+
+func TestProto(t *testing.T) {
+	for i, v := range protoTests {
+		buf := new(bytes.Buffer)
+		bigEnc := newEncoder(buf, binary.BigEndian)
+		bigEnc.Encode(v.vs...)
+		marshalled := buf.Bytes()
+		if bytes.Compare(marshalled, v.bigEndian) != 0 {
+			t.Errorf("test %d (marshal be): got '%v', but expected '%v'\n", i+1, marshalled,
+				v.bigEndian)
+		}
+		buf.Reset()
+		litEnc := newEncoder(buf, binary.LittleEndian)
+		litEnc.Encode(v.vs...)
+		marshalled = buf.Bytes()
+		if bytes.Compare(marshalled, v.littleEndian) != 0 {
+			t.Errorf("test %d (marshal le): got '%v', but expected '%v'\n", i+1, marshalled,
+				v.littleEndian)
+		}
+		unmarshalled := reflect.MakeSlice(reflect.TypeOf(v.vs),
+			0, 0)
+		for i := range v.vs {
+			unmarshalled = reflect.Append(unmarshalled,
+				reflect.New(reflect.TypeOf(v.vs[i])))
+		}
+		bigDec := newDecoder(bytes.NewReader(v.bigEndian), binary.BigEndian)
+		vs, err := bigDec.Decode(SignatureOf(v.vs...))
+		if err != nil {
+			t.Errorf("test %d (unmarshal be): %s\n", i+1, err)
+			continue
+		}
+		if !reflect.DeepEqual(vs, v.vs) {
+			t.Errorf("test %d (unmarshal be): got %#v, but expected %#v\n", i+1, vs, v.vs)
+		}
+		litDec := newDecoder(bytes.NewReader(v.littleEndian), binary.LittleEndian)
+		vs, err = litDec.Decode(SignatureOf(v.vs...))
+		if err != nil {
+			t.Errorf("test %d (unmarshal le): %s\n", i+1, err)
+			continue
+		}
+		if !reflect.DeepEqual(vs, v.vs) {
+			t.Errorf("test %d (unmarshal le): got %#v, but expected %#v\n", i+1, vs, v.vs)
+		}
+
+	}
+}
+
+func TestProtoMap(t *testing.T) {
+	m := map[string]uint8{
+		"foo": 23,
+		"bar": 2,
+	}
+	var n map[string]uint8
+	buf := new(bytes.Buffer)
+	enc := newEncoder(buf, binary.LittleEndian)
+	enc.Encode(m)
+	dec := newDecoder(buf, binary.LittleEndian)
+	vs, err := dec.Decode(Signature{"a{sy}"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = Store(vs, &n); err != nil {
+		t.Fatal(err)
+	}
+	if len(n) != 2 || n["foo"] != 23 || n["bar"] != 2 {
+		t.Error("got", n)
+	}
+}
+
+func TestProtoVariantStruct(t *testing.T) {
+	var variant Variant
+	v := MakeVariant(struct {
+		A int32
+		B int16
+	}{1, 2})
+	buf := new(bytes.Buffer)
+	enc := newEncoder(buf, binary.LittleEndian)
+	enc.Encode(v)
+	dec := newDecoder(buf, binary.LittleEndian)
+	vs, err := dec.Decode(Signature{"v"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = Store(vs, &variant); err != nil {
+		t.Fatal(err)
+	}
+	sl := variant.Value().([]interface{})
+	v1, v2 := sl[0].(int32), sl[1].(int16)
+	if v1 != int32(1) {
+		t.Error("got", v1, "as first int")
+	}
+	if v2 != int16(2) {
+		t.Error("got", v2, "as second int")
+	}
+}
+
+func TestProtoStructTag(t *testing.T) {
+	type Bar struct {
+		A int32
+		B chan interface{} `dbus:"-"`
+		C int32
+	}
+	var bar1, bar2 Bar
+	bar1.A = 234
+	bar2.C = 345
+	buf := new(bytes.Buffer)
+	enc := newEncoder(buf, binary.LittleEndian)
+	enc.Encode(bar1)
+	dec := newDecoder(buf, binary.LittleEndian)
+	vs, err := dec.Decode(Signature{"(ii)"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = Store(vs, &bar2); err != nil {
+		t.Fatal(err)
+	}
+	if bar1 != bar2 {
+		t.Error("struct tag test: got", bar2)
+	}
+}
+
+func TestProtoStoreStruct(t *testing.T) {
+	var foo struct {
+		A int32
+		B string
+		c chan interface{}
+		D interface{} `dbus:"-"`
+	}
+	src := []interface{}{[]interface{}{int32(42), "foo"}}
+	err := Store(src, &foo)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestProtoStoreNestedStruct(t *testing.T) {
+	var foo struct {
+		A int32
+		B struct {
+			C string
+			D float64
+		}
+	}
+	src := []interface{}{
+		[]interface{}{
+			int32(42),
+			[]interface{}{
+				"foo",
+				3.14,
+			},
+		},
+	}
+	err := Store(src, &foo)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestMessage(t *testing.T) {
+	buf := new(bytes.Buffer)
+	message := new(Message)
+	message.Type = TypeMethodCall
+	message.serial = 32
+	message.Headers = map[HeaderField]Variant{
+		FieldPath:   MakeVariant(ObjectPath("/org/foo/bar")),
+		FieldMember: MakeVariant("baz"),
+	}
+	message.Body = make([]interface{}, 0)
+	err := message.EncodeTo(buf, binary.LittleEndian)
+	if err != nil {
+		t.Error(err)
+	}
+	_, err = DecodeMessage(buf)
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestProtoStructInterfaces(t *testing.T) {
+	b := []byte{42}
+	vs, err := newDecoder(bytes.NewReader(b), binary.LittleEndian).Decode(Signature{"(y)"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if vs[0].([]interface{})[0].(byte) != 42 {
+		t.Errorf("wrongs results (got %v)", vs)
+	}
+}
+
+// ordinary org.freedesktop.DBus.Hello call
+var smallMessage = &Message{
+	Type:   TypeMethodCall,
+	serial: 1,
+	Headers: map[HeaderField]Variant{
+		FieldDestination: MakeVariant("org.freedesktop.DBus"),
+		FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/DBus")),
+		FieldInterface:   MakeVariant("org.freedesktop.DBus"),
+		FieldMember:      MakeVariant("Hello"),
+	},
+}
+
+// org.freedesktop.Notifications.Notify
+var bigMessage = &Message{
+	Type:   TypeMethodCall,
+	serial: 2,
+	Headers: map[HeaderField]Variant{
+		FieldDestination: MakeVariant("org.freedesktop.Notifications"),
+		FieldPath:        MakeVariant(ObjectPath("/org/freedesktop/Notifications")),
+		FieldInterface:   MakeVariant("org.freedesktop.Notifications"),
+		FieldMember:      MakeVariant("Notify"),
+		FieldSignature:   MakeVariant(Signature{"susssasa{sv}i"}),
+	},
+	Body: []interface{}{
+		"app_name",
+		uint32(0),
+		"dialog-information",
+		"Notification",
+		"This is the body of a notification",
+		[]string{"ok", "Ok"},
+		map[string]Variant{
+			"sound-name": MakeVariant("dialog-information"),
+		},
+		int32(-1),
+	},
+}
+
+func BenchmarkDecodeMessageSmall(b *testing.B) {
+	var err error
+	var rd *bytes.Reader
+
+	b.StopTimer()
+	buf := new(bytes.Buffer)
+	err = smallMessage.EncodeTo(buf, binary.LittleEndian)
+	if err != nil {
+		b.Fatal(err)
+	}
+	decoded := buf.Bytes()
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		rd = bytes.NewReader(decoded)
+		_, err = DecodeMessage(rd)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkDecodeMessageBig(b *testing.B) {
+	var err error
+	var rd *bytes.Reader
+
+	b.StopTimer()
+	buf := new(bytes.Buffer)
+	err = bigMessage.EncodeTo(buf, binary.LittleEndian)
+	if err != nil {
+		b.Fatal(err)
+	}
+	decoded := buf.Bytes()
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		rd = bytes.NewReader(decoded)
+		_, err = DecodeMessage(rd)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncodeMessageSmall(b *testing.B) {
+	var err error
+	for i := 0; i < b.N; i++ {
+		err = smallMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncodeMessageBig(b *testing.B) {
+	var err error
+	for i := 0; i < b.N; i++ {
+		err = bigMessage.EncodeTo(ioutil.Discard, binary.LittleEndian)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}

+ 257 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig.go

@@ -0,0 +1,257 @@
+package dbus
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+var sigToType = map[byte]reflect.Type{
+	'y': byteType,
+	'b': boolType,
+	'n': int16Type,
+	'q': uint16Type,
+	'i': int32Type,
+	'u': uint32Type,
+	'x': int64Type,
+	't': uint64Type,
+	'd': float64Type,
+	's': stringType,
+	'g': signatureType,
+	'o': objectPathType,
+	'v': variantType,
+	'h': unixFDIndexType,
+}
+
+// Signature represents a correct type signature as specified by the D-Bus
+// specification. The zero value represents the empty signature, "".
+type Signature struct {
+	str string
+}
+
+// SignatureOf returns the concatenation of all the signatures of the given
+// values. It panics if one of them is not representable in D-Bus.
+func SignatureOf(vs ...interface{}) Signature {
+	var s string
+	for _, v := range vs {
+		s += getSignature(reflect.TypeOf(v))
+	}
+	return Signature{s}
+}
+
+// SignatureOfType returns the signature of the given type. It panics if the
+// type is not representable in D-Bus.
+func SignatureOfType(t reflect.Type) Signature {
+	return Signature{getSignature(t)}
+}
+
+// getSignature returns the signature of the given type and panics on unknown types.
+func getSignature(t reflect.Type) string {
+	// handle simple types first
+	switch t.Kind() {
+	case reflect.Uint8:
+		return "y"
+	case reflect.Bool:
+		return "b"
+	case reflect.Int16:
+		return "n"
+	case reflect.Uint16:
+		return "q"
+	case reflect.Int32:
+		if t == unixFDType {
+			return "h"
+		}
+		return "i"
+	case reflect.Uint32:
+		if t == unixFDIndexType {
+			return "h"
+		}
+		return "u"
+	case reflect.Int64:
+		return "x"
+	case reflect.Uint64:
+		return "t"
+	case reflect.Float64:
+		return "d"
+	case reflect.Ptr:
+		return getSignature(t.Elem())
+	case reflect.String:
+		if t == objectPathType {
+			return "o"
+		}
+		return "s"
+	case reflect.Struct:
+		if t == variantType {
+			return "v"
+		} else if t == signatureType {
+			return "g"
+		}
+		var s string
+		for i := 0; i < t.NumField(); i++ {
+			field := t.Field(i)
+			if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
+				s += getSignature(t.Field(i).Type)
+			}
+		}
+		return "(" + s + ")"
+	case reflect.Array, reflect.Slice:
+		return "a" + getSignature(t.Elem())
+	case reflect.Map:
+		if !isKeyType(t.Key()) {
+			panic(InvalidTypeError{t})
+		}
+		return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}"
+	}
+	panic(InvalidTypeError{t})
+}
+
+// ParseSignature returns the signature represented by this string, or a
+// SignatureError if the string is not a valid signature.
+func ParseSignature(s string) (sig Signature, err error) {
+	if len(s) == 0 {
+		return
+	}
+	if len(s) > 255 {
+		return Signature{""}, SignatureError{s, "too long"}
+	}
+	sig.str = s
+	for err == nil && len(s) != 0 {
+		err, s = validSingle(s, 0)
+	}
+	if err != nil {
+		sig = Signature{""}
+	}
+
+	return
+}
+
+// ParseSignatureMust behaves like ParseSignature, except that it panics if s
+// is not valid.
+func ParseSignatureMust(s string) Signature {
+	sig, err := ParseSignature(s)
+	if err != nil {
+		panic(err)
+	}
+	return sig
+}
+
+// Empty retruns whether the signature is the empty signature.
+func (s Signature) Empty() bool {
+	return s.str == ""
+}
+
+// Single returns whether the signature represents a single, complete type.
+func (s Signature) Single() bool {
+	err, r := validSingle(s.str, 0)
+	return err != nil && r == ""
+}
+
+// String returns the signature's string representation.
+func (s Signature) String() string {
+	return s.str
+}
+
+// A SignatureError indicates that a signature passed to a function or received
+// on a connection is not a valid signature.
+type SignatureError struct {
+	Sig    string
+	Reason string
+}
+
+func (e SignatureError) Error() string {
+	return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
+}
+
+// Try to read a single type from this string. If it was successfull, err is nil
+// and rem is the remaining unparsed part. Otherwise, err is a non-nil
+// SignatureError and rem is "". depth is the current recursion depth which may
+// not be greater than 64 and should be given as 0 on the first call.
+func validSingle(s string, depth int) (err error, rem string) {
+	if s == "" {
+		return SignatureError{Sig: s, Reason: "empty signature"}, ""
+	}
+	if depth > 64 {
+		return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
+	}
+	switch s[0] {
+	case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v', 'h':
+		return nil, s[1:]
+	case 'a':
+		if len(s) > 1 && s[1] == '{' {
+			i := findMatching(s[1:], '{', '}')
+			if i == -1 {
+				return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
+			}
+			i++
+			rem = s[i+1:]
+			s = s[2:i]
+			if err, _ = validSingle(s[:1], depth+1); err != nil {
+				return err, ""
+			}
+			err, nr := validSingle(s[1:], depth+1)
+			if err != nil {
+				return err, ""
+			}
+			if nr != "" {
+				return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
+			}
+			return nil, rem
+		}
+		return validSingle(s[1:], depth+1)
+	case '(':
+		i := findMatching(s, '(', ')')
+		if i == -1 {
+			return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
+		}
+		rem = s[i+1:]
+		s = s[1:i]
+		for err == nil && s != "" {
+			err, s = validSingle(s, depth+1)
+		}
+		if err != nil {
+			rem = ""
+		}
+		return
+	}
+	return SignatureError{Sig: s, Reason: "invalid type character"}, ""
+}
+
+func findMatching(s string, left, right rune) int {
+	n := 0
+	for i, v := range s {
+		if v == left {
+			n++
+		} else if v == right {
+			n--
+		}
+		if n == 0 {
+			return i
+		}
+	}
+	return -1
+}
+
+// typeFor returns the type of the given signature. It ignores any left over
+// characters and panics if s doesn't start with a valid type signature.
+func typeFor(s string) (t reflect.Type) {
+	err, _ := validSingle(s, 0)
+	if err != nil {
+		panic(err)
+	}
+
+	if t, ok := sigToType[s[0]]; ok {
+		return t
+	}
+	switch s[0] {
+	case 'a':
+		if s[1] == '{' {
+			i := strings.LastIndex(s, "}")
+			t = reflect.MapOf(sigToType[s[2]], typeFor(s[3:i]))
+		} else {
+			t = reflect.SliceOf(typeFor(s[1:]))
+		}
+	case '(':
+		t = interfacesType
+	}
+	return
+}

+ 70 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/sig_test.go

@@ -0,0 +1,70 @@
+package dbus
+
+import (
+	"testing"
+)
+
+var sigTests = []struct {
+	vs  []interface{}
+	sig Signature
+}{
+	{
+		[]interface{}{new(int32)},
+		Signature{"i"},
+	},
+	{
+		[]interface{}{new(string)},
+		Signature{"s"},
+	},
+	{
+		[]interface{}{new(Signature)},
+		Signature{"g"},
+	},
+	{
+		[]interface{}{new([]int16)},
+		Signature{"an"},
+	},
+	{
+		[]interface{}{new(int16), new(uint32)},
+		Signature{"nu"},
+	},
+	{
+		[]interface{}{new(map[byte]Variant)},
+		Signature{"a{yv}"},
+	},
+	{
+		[]interface{}{new(Variant), new([]map[int32]string)},
+		Signature{"vaa{is}"},
+	},
+}
+
+func TestSig(t *testing.T) {
+	for i, v := range sigTests {
+		sig := SignatureOf(v.vs...)
+		if sig != v.sig {
+			t.Errorf("test %d: got %q, expected %q", i+1, sig.str, v.sig.str)
+		}
+	}
+}
+
+var getSigTest = []interface{}{
+	[]struct {
+		b byte
+		i int32
+		t uint64
+		s string
+	}{},
+	map[string]Variant{},
+}
+
+func BenchmarkGetSignatureSimple(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		SignatureOf("", int32(0))
+	}
+}
+
+func BenchmarkGetSignatureLong(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		SignatureOf(getSigTest...)
+	}
+}

+ 6 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_darwin.go

@@ -0,0 +1,6 @@
+package dbus
+
+func (t *unixTransport) SendNullByte() error {
+	_, err := t.Write([]byte{0})
+	return err
+}

+ 35 - 0
vendor/src/github.com/docker/libcontainer/vendor/src/github.com/godbus/dbus/transport_generic.go

@@ -0,0 +1,35 @@
+package dbus
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+)
+
+type genericTransport struct {
+	io.ReadWriteCloser
+}
+
+func (t genericTransport) SendNullByte() error {
+	_, err := t.Write([]byte{0})
+	return err
+}
+
+func (t genericTransport) SupportsUnixFDs() bool {
+	return false
+}
+
+func (t genericTransport) EnableUnixFDs() {}
+
+func (t genericTransport) ReadMessage() (*Message, error) {
+	return DecodeMessage(t)
+}
+
+func (t genericTransport) SendMessage(msg *Message) error {
+	for _, v := range msg.Body {
+		if _, ok := v.(UnixFD); ok {
+			return errors.New("dbus: unix fd passing not enabled")
+		}
+	}
+	return msg.EncodeTo(t, binary.LittleEndian)
+}

Some files were not shown because too many files changed in this diff