浏览代码

Fix up Godeps and update docker/docker packages

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 9 年之前
父节点
当前提交
e026deb981
共有 100 个文件被更改,包括 2678 次插入5557 次删除
  1. 56 46
      libnetwork/Godeps/Godeps.json
  2. 0 83
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/attach.go
  3. 0 310
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/build.go
  4. 0 203
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/cli.go
  5. 0 17
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/client.go
  6. 0 80
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/commit.go
  7. 0 57
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/cp.go
  8. 0 160
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/create.go
  9. 0 52
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/diff.go
  10. 0 62
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/events.go
  11. 0 131
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/exec.go
  12. 0 46
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/export.go
  13. 0 34
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/help.go
  14. 0 257
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/hijack.go
  15. 0 73
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/history.go
  16. 0 126
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/images.go
  17. 0 64
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/import.go
  18. 0 91
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/info.go
  19. 0 124
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/inspect.go
  20. 0 32
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/kill.go
  21. 0 41
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/load.go
  22. 0 144
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/login.go
  23. 0 36
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/logout.go
  24. 0 69
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/logs.go
  25. 0 30
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/pause.go
  26. 0 64
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/port.go
  27. 0 175
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/ps.go
  28. 0 47
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/pull.go
  29. 0 49
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/push.go
  30. 0 25
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rename.go
  31. 0 38
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/restart.go
  32. 0 54
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rm.go
  33. 0 59
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rmi.go
  34. 0 247
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/run.go
  35. 0 57
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/save.go
  36. 0 84
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/search.go
  37. 0 167
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/start.go
  38. 0 198
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stats.go
  39. 0 29
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stats_unit_test.go
  40. 0 40
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stop.go
  41. 0 41
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/tag.go
  42. 0 46
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/top.go
  43. 0 30
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/unpause.go
  44. 0 345
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/utils.go
  45. 0 61
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/version.go
  46. 0 34
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/wait.go
  47. 23 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/blkiodev/blkio.go
  48. 67 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/envfile.go
  49. 142 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/envfile_test.go
  50. 146 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts.go
  51. 164 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_test.go
  52. 8 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_unix.go
  53. 6 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_windows.go
  54. 42 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ip.go
  55. 54 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ip_test.go
  56. 331 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts.go
  57. 301 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_test.go
  58. 6 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_unix.go
  59. 56 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_windows.go
  60. 56 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/throttledevice.go
  61. 52 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ulimit.go
  62. 42 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ulimit_test.go
  63. 56 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/weightdevice.go
  64. 6 6
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/README.md
  65. 60 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/backends.go
  66. 2 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/discovery.go
  67. 58 47
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/discovery_test.go
  68. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/file/file.go
  69. 43 35
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/file/file_test.go
  70. 29 31
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/generator_test.go
  71. 28 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv.go
  72. 259 54
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv_test.go
  73. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/nodes/nodes.go
  74. 27 19
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/nodes/nodes_test.go
  75. 72 9
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe.go
  76. 34 17
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe_test.go
  77. 71 87
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
  78. 18 148
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go
  79. 10 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/temp_unix.go
  80. 18 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/temp_windows.go
  81. 51 10
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writeflusher.go
  82. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go
  83. 68 5
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/flag.go
  84. 23 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go
  85. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go
  86. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux_test.go
  87. 0 116
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse.go
  88. 0 78
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse_test.go
  89. 16 11
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go
  90. 0 61
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_test.go
  91. 96 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_unix_test.go
  92. 10 8
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go
  93. 3 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go
  94. 3 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go
  95. 0 40
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_linux.go
  96. 0 124
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_test.go
  97. 0 47
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_windows.go
  98. 0 157
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers.go
  99. 0 157
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers_test.go
  100. 60 21
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go

+ 56 - 46
libnetwork/Godeps/Godeps.json

@@ -59,100 +59,110 @@
 			"Comment": "v1-26-gef32fa3",
 			"Rev": "ef32fa3046d9f249d399f98ebaf9be944430fd1d"
 		},
+		{
+			"ImportPath": "github.com/docker/docker/api/types/blkiodev",
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
+		},
+		{
+			"ImportPath": "github.com/docker/docker/opts",
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
+		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/discovery",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/homedir",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/ioutils",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
-		},
-		{
-			"ImportPath": "github.com/docker/docker/pkg/listenbuffer",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/mflag",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/mount",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
-			"ImportPath": "github.com/docker/docker/pkg/parsers",
-			"Comment": "v1.4.1-4106-g637023a",
-			"Rev": "637023a5f8d8347a0e271c09d5c9bc84fbc97693"
+			"ImportPath": "github.com/docker/docker/pkg/parsers/kernel",
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/plugins",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/proxy",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/random",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/reexec",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/signal",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/sockets",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/stringid",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/symlink",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/system",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/term",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/tlsconfig",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
+		},
+		{
+			"ImportPath": "github.com/docker/docker/pkg/ulimit",
+			"Comment": "v1.4.1-8734-g577cf61",
+			"Rev": "577cf61afad695f0ba226cdf8a995a8c78883e51"
 		},
 		{
-			"ImportPath": "github.com/docker/docker/pkg/units",
-			"Comment": "v1.4.1-6485-g949270b",
-			"Rev": "949270ba7ca3c93f25a13abf68d5e0e4c05be08a"
+			"ImportPath": "github.com/docker/go-units",
+			"Comment": "v0.1.0-16-g8e2d452",
+			"Rev": "8e2d4523730c73120e10d4652f36ad6010998f4e"
 		},
 		{
 			"ImportPath": "github.com/docker/libkv",
@@ -195,8 +205,8 @@
 		},
 		{
 			"ImportPath": "github.com/opencontainers/runc/libcontainer",
-			"Comment": "v0.0.3",
-			"Rev": "072fa6fdccaba49b11ba91ad4265b1ec1043787e"
+			"Comment": "v0.0.6-6-gba1568d",
+			"Rev": "ba1568de399395774ad84c2ace65937814c542ed"
 		},
 		{
 			"ImportPath": "github.com/samuel/go-zookeeper/zk",
@@ -208,7 +218,7 @@
 		},
 		{
 			"ImportPath": "github.com/syndtr/gocapability/capability",
-			"Rev": "e55e5833692b49e49a0073ad5baf7803f21bebf4"
+			"Rev": "2c00daeb6c3b45114c80ac44119e7b8801fdd852"
 		},
 		{
 			"ImportPath": "github.com/ugorji/go/codec",

+ 0 - 83
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/attach.go

@@ -1,83 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"net/url"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/signal"
-)
-
-// CmdAttach attaches to a running container.
-//
-// Usage: docker attach [OPTIONS] CONTAINER
-func (cli *DockerCli) CmdAttach(args ...string) error {
-	var (
-		cmd     = cli.Subcmd("attach", "CONTAINER", "Attach to a running container", true)
-		noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN")
-		proxy   = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process")
-	)
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-	name := cmd.Arg(0)
-
-	stream, _, _, err := cli.call("GET", "/containers/"+name+"/json", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	var c types.ContainerJSON
-	if err := json.NewDecoder(stream).Decode(&c); err != nil {
-		return err
-	}
-
-	if !c.State.Running {
-		return fmt.Errorf("You cannot attach to a stopped container, start it first")
-	}
-
-	if err := cli.CheckTtyInput(!*noStdin, c.Config.Tty); err != nil {
-		return err
-	}
-
-	if c.Config.Tty && cli.isTerminalOut {
-		if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil {
-			logrus.Debugf("Error monitoring TTY size: %s", err)
-		}
-	}
-
-	var in io.ReadCloser
-
-	v := url.Values{}
-	v.Set("stream", "1")
-	if !*noStdin && c.Config.OpenStdin {
-		v.Set("stdin", "1")
-		in = cli.in
-	}
-
-	v.Set("stdout", "1")
-	v.Set("stderr", "1")
-
-	if *proxy && !c.Config.Tty {
-		sigc := cli.forwardAllSignals(cmd.Arg(0))
-		defer signal.StopCatch(sigc)
-	}
-
-	if err := cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), c.Config.Tty, in, cli.out, cli.err, nil, nil); err != nil {
-		return err
-	}
-
-	_, status, err := getExitCode(cli, cmd.Arg(0))
-	if err != nil {
-		return err
-	}
-	if status != 0 {
-		return StatusError{StatusCode: status}
-	}
-
-	return nil
-}

+ 0 - 310
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/build.go

@@ -1,310 +0,0 @@
-package client
-
-import (
-	"bufio"
-	"encoding/base64"
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"os"
-	"os/exec"
-	"path"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/graph/tags"
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/fileutils"
-	"github.com/docker/docker/pkg/jsonmessage"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/pkg/progressreader"
-	"github.com/docker/docker/pkg/streamformatter"
-	"github.com/docker/docker/pkg/symlink"
-	"github.com/docker/docker/pkg/units"
-	"github.com/docker/docker/pkg/urlutil"
-	"github.com/docker/docker/registry"
-	"github.com/docker/docker/utils"
-)
-
-const (
-	tarHeaderSize = 512
-)
-
-// CmdBuild builds a new image from the source code at a given path.
-//
-// If '-' is provided instead of a path or URL, Docker will build an image from either a Dockerfile or tar archive read from STDIN.
-//
-// Usage: docker build [OPTIONS] PATH | URL | -
-func (cli *DockerCli) CmdBuild(args ...string) error {
-	cmd := cli.Subcmd("build", "PATH | URL | -", "Build a new image from the source code at PATH", true)
-	tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) for the image")
-	suppressOutput := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the verbose output generated by the containers")
-	noCache := cmd.Bool([]string{"#no-cache", "-no-cache"}, false, "Do not use cache when building the image")
-	rm := cmd.Bool([]string{"#rm", "-rm"}, true, "Remove intermediate containers after a successful build")
-	forceRm := cmd.Bool([]string{"-force-rm"}, false, "Always remove intermediate containers")
-	pull := cmd.Bool([]string{"-pull"}, false, "Always attempt to pull a newer version of the image")
-	dockerfileName := cmd.String([]string{"f", "-file"}, "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
-	flMemoryString := cmd.String([]string{"m", "-memory"}, "", "Memory limit")
-	flMemorySwap := cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap")
-	flCPUShares := cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
-	flCpuPeriod := cmd.Int64([]string{"-cpu-period"}, 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
-	flCpuQuota := cmd.Int64([]string{"-cpu-quota"}, 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
-	flCPUSetCpus := cmd.String([]string{"-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
-	flCPUSetMems := cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
-	flCgroupParent := cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
-
-	cmd.Require(flag.Exact, 1)
-	cmd.ParseFlags(args, true)
-
-	var (
-		context  archive.Archive
-		isRemote bool
-		err      error
-	)
-
-	_, err = exec.LookPath("git")
-	hasGit := err == nil
-	if cmd.Arg(0) == "-" {
-		// As a special case, 'docker build -' will build from either an empty context with the
-		// contents of stdin as a Dockerfile, or a tar-ed context from stdin.
-		buf := bufio.NewReader(cli.in)
-		magic, err := buf.Peek(tarHeaderSize)
-		if err != nil && err != io.EOF {
-			return fmt.Errorf("failed to peek context header from STDIN: %v", err)
-		}
-		if !archive.IsArchive(magic) {
-			dockerfile, err := ioutil.ReadAll(buf)
-			if err != nil {
-				return fmt.Errorf("failed to read Dockerfile from STDIN: %v", err)
-			}
-
-			// -f option has no meaning when we're reading it from stdin,
-			// so just use our default Dockerfile name
-			*dockerfileName = api.DefaultDockerfileName
-			context, err = archive.Generate(*dockerfileName, string(dockerfile))
-		} else {
-			context = ioutil.NopCloser(buf)
-		}
-	} else if urlutil.IsURL(cmd.Arg(0)) && (!urlutil.IsGitURL(cmd.Arg(0)) || !hasGit) {
-		isRemote = true
-	} else {
-		root := cmd.Arg(0)
-		if urlutil.IsGitURL(root) {
-			root, err = utils.GitClone(root)
-			if err != nil {
-				return err
-			}
-			defer os.RemoveAll(root)
-		}
-		if _, err := os.Stat(root); err != nil {
-			return err
-		}
-
-		absRoot, err := filepath.Abs(root)
-		if err != nil {
-			return err
-		}
-
-		filename := *dockerfileName // path to Dockerfile
-
-		if *dockerfileName == "" {
-			// No -f/--file was specified so use the default
-			*dockerfileName = api.DefaultDockerfileName
-			filename = filepath.Join(absRoot, *dockerfileName)
-
-			// Just to be nice ;-) look for 'dockerfile' too but only
-			// use it if we found it, otherwise ignore this check
-			if _, err = os.Lstat(filename); os.IsNotExist(err) {
-				tmpFN := path.Join(absRoot, strings.ToLower(*dockerfileName))
-				if _, err = os.Lstat(tmpFN); err == nil {
-					*dockerfileName = strings.ToLower(*dockerfileName)
-					filename = tmpFN
-				}
-			}
-		}
-
-		origDockerfile := *dockerfileName // used for error msg
-		if filename, err = filepath.Abs(filename); err != nil {
-			return err
-		}
-
-		// Verify that 'filename' is within the build context
-		filename, err = symlink.FollowSymlinkInScope(filename, absRoot)
-		if err != nil {
-			return fmt.Errorf("The Dockerfile (%s) must be within the build context (%s)", origDockerfile, root)
-		}
-
-		// Now reset the dockerfileName to be relative to the build context
-		*dockerfileName, err = filepath.Rel(absRoot, filename)
-		if err != nil {
-			return err
-		}
-		// And canonicalize dockerfile name to a platform-independent one
-		*dockerfileName, err = archive.CanonicalTarNameForPath(*dockerfileName)
-		if err != nil {
-			return fmt.Errorf("Cannot canonicalize dockerfile path %s: %v", *dockerfileName, err)
-		}
-
-		if _, err = os.Lstat(filename); os.IsNotExist(err) {
-			return fmt.Errorf("Cannot locate Dockerfile: %s", origDockerfile)
-		}
-		var includes = []string{"."}
-
-		excludes, err := utils.ReadDockerIgnore(path.Join(root, ".dockerignore"))
-		if err != nil {
-			return err
-		}
-
-		// If .dockerignore mentions .dockerignore or the Dockerfile
-		// then make sure we send both files over to the daemon
-		// because Dockerfile is, obviously, needed no matter what, and
-		// .dockerignore is needed to know if either one needs to be
-		// removed.  The deamon will remove them for us, if needed, after it
-		// parses the Dockerfile.
-		keepThem1, _ := fileutils.Matches(".dockerignore", excludes)
-		keepThem2, _ := fileutils.Matches(*dockerfileName, excludes)
-		if keepThem1 || keepThem2 {
-			includes = append(includes, ".dockerignore", *dockerfileName)
-		}
-
-		if err := utils.ValidateContextDirectory(root, excludes); err != nil {
-			return fmt.Errorf("Error checking context: '%s'.", err)
-		}
-		options := &archive.TarOptions{
-			Compression:     archive.Uncompressed,
-			ExcludePatterns: excludes,
-			IncludeFiles:    includes,
-		}
-		context, err = archive.TarWithOptions(root, options)
-		if err != nil {
-			return err
-		}
-	}
-
-	// windows: show error message about modified file permissions
-	// FIXME: this is not a valid warning when the daemon is running windows. should be removed once docker engine for windows can build.
-	if runtime.GOOS == "windows" {
-		fmt.Fprintln(cli.err, `SECURITY WARNING: You are building a Docker image from Windows against a Linux Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.`)
-	}
-
-	var body io.Reader
-	// Setup an upload progress bar
-	// FIXME: ProgressReader shouldn't be this annoying to use
-	if context != nil {
-		sf := streamformatter.NewStreamFormatter()
-		body = progressreader.New(progressreader.Config{
-			In:        context,
-			Out:       cli.out,
-			Formatter: sf,
-			NewLines:  true,
-			ID:        "",
-			Action:    "Sending build context to Docker daemon",
-		})
-	}
-
-	var memory int64
-	if *flMemoryString != "" {
-		parsedMemory, err := units.RAMInBytes(*flMemoryString)
-		if err != nil {
-			return err
-		}
-		memory = parsedMemory
-	}
-
-	var memorySwap int64
-	if *flMemorySwap != "" {
-		if *flMemorySwap == "-1" {
-			memorySwap = -1
-		} else {
-			parsedMemorySwap, err := units.RAMInBytes(*flMemorySwap)
-			if err != nil {
-				return err
-			}
-			memorySwap = parsedMemorySwap
-		}
-	}
-	// Send the build context
-	v := &url.Values{}
-
-	//Check if the given image name can be resolved
-	if *tag != "" {
-		repository, tag := parsers.ParseRepositoryTag(*tag)
-		if err := registry.ValidateRepositoryName(repository); err != nil {
-			return err
-		}
-		if len(tag) > 0 {
-			if err := tags.ValidateTagName(tag); err != nil {
-				return err
-			}
-		}
-	}
-
-	v.Set("t", *tag)
-
-	if *suppressOutput {
-		v.Set("q", "1")
-	}
-	if isRemote {
-		v.Set("remote", cmd.Arg(0))
-	}
-	if *noCache {
-		v.Set("nocache", "1")
-	}
-	if *rm {
-		v.Set("rm", "1")
-	} else {
-		v.Set("rm", "0")
-	}
-
-	if *forceRm {
-		v.Set("forcerm", "1")
-	}
-
-	if *pull {
-		v.Set("pull", "1")
-	}
-
-	v.Set("cpusetcpus", *flCPUSetCpus)
-	v.Set("cpusetmems", *flCPUSetMems)
-	v.Set("cpushares", strconv.FormatInt(*flCPUShares, 10))
-	v.Set("cpuquota", strconv.FormatInt(*flCpuQuota, 10))
-	v.Set("cpuperiod", strconv.FormatInt(*flCpuPeriod, 10))
-	v.Set("memory", strconv.FormatInt(memory, 10))
-	v.Set("memswap", strconv.FormatInt(memorySwap, 10))
-	v.Set("cgroupparent", *flCgroupParent)
-
-	v.Set("dockerfile", *dockerfileName)
-
-	headers := http.Header(make(map[string][]string))
-	buf, err := json.Marshal(cli.configFile.AuthConfigs)
-	if err != nil {
-		return err
-	}
-	headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
-
-	if context != nil {
-		headers.Set("Content-Type", "application/tar")
-	}
-	sopts := &streamOpts{
-		rawTerminal: true,
-		in:          body,
-		out:         cli.out,
-		headers:     headers,
-	}
-	err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), sopts)
-	if jerr, ok := err.(*jsonmessage.JSONError); ok {
-		// If no error code is set, default to 1
-		if jerr.Code == 0 {
-			jerr.Code = 1
-		}
-		return StatusError{Status: jerr.Message, StatusCode: jerr.Code}
-	}
-	return err
-}

+ 0 - 203
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/cli.go

@@ -1,203 +0,0 @@
-package client
-
-import (
-	"crypto/tls"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"net/http"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"text/template"
-
-	"github.com/docker/docker/cliconfig"
-	"github.com/docker/docker/pkg/homedir"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/term"
-	"github.com/docker/docker/utils"
-)
-
-// DockerCli represents the docker command line client.
-// Instances of the client can be returned from NewDockerCli.
-type DockerCli struct {
-	// proto holds the client protocol i.e. unix.
-	proto string
-	// addr holds the client address.
-	addr string
-
-	// configFile has the client configuration file
-	configFile *cliconfig.ConfigFile
-	// in holds the input stream and closer (io.ReadCloser) for the client.
-	in io.ReadCloser
-	// out holds the output stream (io.Writer) for the client.
-	out io.Writer
-	// err holds the error stream (io.Writer) for the client.
-	err io.Writer
-	// keyFile holds the key file as a string.
-	keyFile string
-	// tlsConfig holds the TLS configuration for the client, and will
-	// set the scheme to https in NewDockerCli if present.
-	tlsConfig *tls.Config
-	// scheme holds the scheme of the client i.e. https.
-	scheme string
-	// inFd holds the file descriptor of the client's STDIN (if valid).
-	inFd uintptr
-	// outFd holds file descriptor of the client's STDOUT (if valid).
-	outFd uintptr
-	// isTerminalIn indicates whether the client's STDIN is a TTY
-	isTerminalIn bool
-	// isTerminalOut dindicates whether the client's STDOUT is a TTY
-	isTerminalOut bool
-	// transport holds the client transport instance.
-	transport *http.Transport
-}
-
-var funcMap = template.FuncMap{
-	"json": func(v interface{}) string {
-		a, _ := json.Marshal(v)
-		return string(a)
-	},
-}
-
-func (cli *DockerCli) Out() io.Writer {
-	return cli.out
-}
-
-func (cli *DockerCli) Err() io.Writer {
-	return cli.err
-}
-
-func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
-	camelArgs := make([]string, len(args))
-	for i, s := range args {
-		if len(s) == 0 {
-			return nil, false
-		}
-		camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
-	}
-	methodName := "Cmd" + strings.Join(camelArgs, "")
-	method := reflect.ValueOf(cli).MethodByName(methodName)
-	if !method.IsValid() {
-		return nil, false
-	}
-	return method.Interface().(func(...string) error), true
-}
-
-// Cmd executes the specified command.
-func (cli *DockerCli) Cmd(args ...string) error {
-	if len(args) > 1 {
-		method, exists := cli.getMethod(args[:2]...)
-		if exists {
-			return method(args[2:]...)
-		}
-	}
-	if len(args) > 0 {
-		method, exists := cli.getMethod(args[0])
-		if !exists {
-			return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'.", args[0])
-		}
-		return method(args[1:]...)
-	}
-	return cli.CmdHelp()
-}
-
-// Subcmd is a subcommand of the main "docker" command.
-// A subcommand represents an action that can be performed
-// from the Docker command line client.
-//
-// To see all available subcommands, run "docker --help".
-func (cli *DockerCli) Subcmd(name, signature, description string, exitOnError bool) *flag.FlagSet {
-	var errorHandling flag.ErrorHandling
-	if exitOnError {
-		errorHandling = flag.ExitOnError
-	} else {
-		errorHandling = flag.ContinueOnError
-	}
-	flags := flag.NewFlagSet(name, errorHandling)
-	if signature != "" {
-		signature = " " + signature
-	}
-	flags.Usage = func() {
-		flags.ShortUsage()
-		flags.PrintDefaults()
-	}
-	flags.ShortUsage = func() {
-		options := ""
-		if flags.FlagCountUndeprecated() > 0 {
-			options = " [OPTIONS]"
-		}
-		fmt.Fprintf(flags.Out(), "\nUsage: docker %s%s%s\n\n%s\n", name, options, signature, description)
-	}
-	return flags
-}
-
-// CheckTtyInput checks if we are trying to attach to a container tty
-// from a non-tty client input stream, and if so, returns an error.
-func (cli *DockerCli) CheckTtyInput(attachStdin, ttyMode bool) error {
-	// In order to attach to a container tty, input stream for the client must
-	// be a tty itself: redirecting or piping the client standard input is
-	// incompatible with `docker run -t`, `docker exec -t` or `docker attach`.
-	if ttyMode && attachStdin && !cli.isTerminalIn {
-		return errors.New("cannot enable tty mode on non tty input")
-	}
-	return nil
-}
-
-// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
-// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config
-// is set the client scheme will be set to https.
-// The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035).
-func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, addr string, tlsConfig *tls.Config) *DockerCli {
-	var (
-		inFd          uintptr
-		outFd         uintptr
-		isTerminalIn  = false
-		isTerminalOut = false
-		scheme        = "http"
-	)
-
-	if tlsConfig != nil {
-		scheme = "https"
-	}
-	if in != nil {
-		inFd, isTerminalIn = term.GetFdInfo(in)
-	}
-
-	if out != nil {
-		outFd, isTerminalOut = term.GetFdInfo(out)
-	}
-
-	if err == nil {
-		err = out
-	}
-
-	// The transport is created here for reuse during the client session.
-	tr := &http.Transport{
-		TLSClientConfig: tlsConfig,
-	}
-	utils.ConfigureTCPTransport(tr, proto, addr)
-
-	configFile, e := cliconfig.Load(filepath.Join(homedir.Get(), ".docker"))
-	if e != nil {
-		fmt.Fprintf(err, "WARNING: Error loading config file:%v\n", e)
-	}
-
-	return &DockerCli{
-		proto:         proto,
-		addr:          addr,
-		configFile:    configFile,
-		in:            in,
-		out:           out,
-		err:           err,
-		keyFile:       keyFile,
-		inFd:          inFd,
-		outFd:         outFd,
-		isTerminalIn:  isTerminalIn,
-		isTerminalOut: isTerminalOut,
-		tlsConfig:     tlsConfig,
-		scheme:        scheme,
-		transport:     tr,
-	}
-}

+ 0 - 17
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/client.go

@@ -1,17 +0,0 @@
-// Package client provides a command-line interface for Docker.
-//
-// Run "docker help SUBCOMMAND" or "docker SUBCOMMAND --help" to see more information on any Docker subcommand, including the full list of options supported for the subcommand.
-// See https://docs.docker.com/installation/ for instructions on installing Docker.
-package client
-
-import "fmt"
-
-// An StatusError reports an unsuccessful exit by a command.
-type StatusError struct {
-	Status     string
-	StatusCode int
-}
-
-func (e StatusError) Error() string {
-	return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
-}

+ 0 - 80
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/commit.go

@@ -1,80 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-	"github.com/docker/docker/runconfig"
-)
-
-// CmdCommit creates a new image from a container's changes.
-//
-// Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-func (cli *DockerCli) CmdCommit(args ...string) error {
-	cmd := cli.Subcmd("commit", "CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes", true)
-	flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
-	flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
-	flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
-	flChanges := opts.NewListOpts(nil)
-	cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
-	// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
-	flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
-	cmd.Require(flag.Max, 2)
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	var (
-		name            = cmd.Arg(0)
-		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
-	)
-
-	//Check if the given image name can be resolved
-	if repository != "" {
-		if err := registry.ValidateRepositoryName(repository); err != nil {
-			return err
-		}
-	}
-
-	v := url.Values{}
-	v.Set("container", name)
-	v.Set("repo", repository)
-	v.Set("tag", tag)
-	v.Set("comment", *flComment)
-	v.Set("author", *flAuthor)
-	for _, change := range flChanges.GetAll() {
-		v.Add("changes", change)
-	}
-
-	if *flPause != true {
-		v.Set("pause", "0")
-	}
-
-	var (
-		config   *runconfig.Config
-		response types.ContainerCommitResponse
-	)
-
-	if *flConfig != "" {
-		config = &runconfig.Config{}
-		if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
-			return err
-		}
-	}
-	stream, _, _, err := cli.call("POST", "/commit?"+v.Encode(), config, nil)
-	if err != nil {
-		return err
-	}
-
-	if err := json.NewDecoder(stream).Decode(&response); err != nil {
-		return err
-	}
-
-	fmt.Fprintln(cli.out, response.ID)
-	return nil
-}

+ 0 - 57
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/cp.go

@@ -1,57 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"io"
-	"strings"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/archive"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdCp copies files/folders from a path on the container to a directory on the host running the command.
-//
-// If HOSTDIR is '-', the data is written as a tar file to STDOUT.
-//
-// Usage: docker cp CONTAINER:PATH HOSTDIR
-func (cli *DockerCli) CmdCp(args ...string) error {
-	cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTDIR|-", "Copy files/folders from a PATH on the container to a HOSTDIR on the host\nrunning the command. Use '-' to write the data as a tar file to STDOUT.", true)
-	cmd.Require(flag.Exact, 2)
-
-	cmd.ParseFlags(args, true)
-
-	// deal with path name with `:`
-	info := strings.SplitN(cmd.Arg(0), ":", 2)
-
-	if len(info) != 2 {
-		return fmt.Errorf("Error: Path not specified")
-	}
-
-	cfg := &types.CopyConfig{
-		Resource: info[1],
-	}
-	stream, _, statusCode, err := cli.call("POST", "/containers/"+info[0]+"/copy", cfg, nil)
-	if stream != nil {
-		defer stream.Close()
-	}
-	if statusCode == 404 {
-		return fmt.Errorf("No such container: %v", info[0])
-	}
-	if err != nil {
-		return err
-	}
-
-	hostPath := cmd.Arg(1)
-	if statusCode == 200 {
-		if hostPath == "-" {
-			_, err = io.Copy(cli.out, stream)
-		} else {
-			err = archive.Untar(stream, hostPath, &archive.TarOptions{NoLchown: true})
-		}
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}

+ 0 - 160
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/create.go

@@ -1,160 +0,0 @@
-package client
-
-import (
-	"encoding/base64"
-	"encoding/json"
-	"fmt"
-	"io"
-	"net/url"
-	"os"
-	"strings"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/graph/tags"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-	"github.com/docker/docker/runconfig"
-	"github.com/docker/docker/utils"
-)
-
-func (cli *DockerCli) pullImage(image string) error {
-	return cli.pullImageCustomOut(image, cli.out)
-}
-
-func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
-	v := url.Values{}
-	repos, tag := parsers.ParseRepositoryTag(image)
-	// pull only the image tagged 'latest' if no tag was specified
-	if tag == "" {
-		tag = tags.DEFAULTTAG
-	}
-	v.Set("fromImage", repos)
-	v.Set("tag", tag)
-
-	// Resolve the Repository name from fqn to RepositoryInfo
-	repoInfo, err := registry.ParseRepositoryInfo(repos)
-	if err != nil {
-		return err
-	}
-
-	// Resolve the Auth config relevant for this server
-	authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index)
-	buf, err := json.Marshal(authConfig)
-	if err != nil {
-		return err
-	}
-
-	registryAuthHeader := []string{
-		base64.URLEncoding.EncodeToString(buf),
-	}
-	sopts := &streamOpts{
-		rawTerminal: true,
-		out:         out,
-		headers:     map[string][]string{"X-Registry-Auth": registryAuthHeader},
-	}
-	if err := cli.stream("POST", "/images/create?"+v.Encode(), sopts); err != nil {
-		return err
-	}
-	return nil
-}
-
-type cidFile struct {
-	path    string
-	file    *os.File
-	written bool
-}
-
-func newCIDFile(path string) (*cidFile, error) {
-	if _, err := os.Stat(path); err == nil {
-		return nil, fmt.Errorf("Container ID file found, make sure the other container isn't running or delete %s", path)
-	}
-
-	f, err := os.Create(path)
-	if err != nil {
-		return nil, fmt.Errorf("Failed to create the container ID file: %s", err)
-	}
-
-	return &cidFile{path: path, file: f}, nil
-}
-
-func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runconfig.HostConfig, cidfile, name string) (*types.ContainerCreateResponse, error) {
-	containerValues := url.Values{}
-	if name != "" {
-		containerValues.Set("name", name)
-	}
-
-	mergedConfig := runconfig.MergeConfigs(config, hostConfig)
-
-	var containerIDFile *cidFile
-	if cidfile != "" {
-		var err error
-		if containerIDFile, err = newCIDFile(cidfile); err != nil {
-			return nil, err
-		}
-		defer containerIDFile.Close()
-	}
-
-	//create the container
-	stream, _, statusCode, err := cli.call("POST", "/containers/create?"+containerValues.Encode(), mergedConfig, nil)
-	//if image not found try to pull it
-	if statusCode == 404 && strings.Contains(err.Error(), config.Image) {
-		repo, tag := parsers.ParseRepositoryTag(config.Image)
-		if tag == "" {
-			tag = tags.DEFAULTTAG
-		}
-		fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", utils.ImageReference(repo, tag))
-
-		// we don't want to write to stdout anything apart from container.ID
-		if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil {
-			return nil, err
-		}
-		// Retry
-		if stream, _, _, err = cli.call("POST", "/containers/create?"+containerValues.Encode(), mergedConfig, nil); err != nil {
-			return nil, err
-		}
-	} else if err != nil {
-		return nil, err
-	}
-
-	var response types.ContainerCreateResponse
-	if err := json.NewDecoder(stream).Decode(&response); err != nil {
-		return nil, err
-	}
-	for _, warning := range response.Warnings {
-		fmt.Fprintf(cli.err, "WARNING: %s\n", warning)
-	}
-	if containerIDFile != nil {
-		if err = containerIDFile.Write(response.ID); err != nil {
-			return nil, err
-		}
-	}
-	return &response, nil
-}
-
-// CmdCreate creates a new container from a given image.
-//
-// Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
-func (cli *DockerCli) CmdCreate(args ...string) error {
-	cmd := cli.Subcmd("create", "IMAGE [COMMAND] [ARG...]", "Create a new container", true)
-
-	// These are flags not stored in Config/HostConfig
-	var (
-		flName = cmd.String([]string{"-name"}, "", "Assign a name to the container")
-	)
-
-	config, hostConfig, cmd, err := runconfig.Parse(cmd, args)
-	if err != nil {
-		cmd.ReportError(err.Error(), true)
-		os.Exit(1)
-	}
-	if config.Image == "" {
-		cmd.Usage()
-		return nil
-	}
-	response, err := cli.createContainer(config, hostConfig, hostConfig.ContainerIDFile, *flName)
-	if err != nil {
-		return err
-	}
-	fmt.Fprintf(cli.out, "%s\n", response.ID)
-	return nil
-}

+ 0 - 52
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/diff.go

@@ -1,52 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/archive"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdDiff shows changes on a container's filesystem.
-//
-// Each changed file is printed on a separate line, prefixed with a single
-// character that indicates the status of the file: C (modified), A (added),
-// or D (deleted).
-//
-// Usage: docker diff CONTAINER
-func (cli *DockerCli) CmdDiff(args ...string) error {
-	cmd := cli.Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem", true)
-	cmd.Require(flag.Exact, 1)
-	cmd.ParseFlags(args, true)
-
-	if cmd.Arg(0) == "" {
-		return fmt.Errorf("Container name cannot be empty")
-	}
-
-	rdr, _, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	changes := []types.ContainerChange{}
-	if err := json.NewDecoder(rdr).Decode(&changes); err != nil {
-		return err
-	}
-
-	for _, change := range changes {
-		var kind string
-		switch change.Kind {
-		case archive.ChangeModify:
-			kind = "C"
-		case archive.ChangeAdd:
-			kind = "A"
-		case archive.ChangeDelete:
-			kind = "D"
-		}
-		fmt.Fprintf(cli.out, "%s %s\n", kind, change.Path)
-	}
-
-	return nil
-}

+ 0 - 62
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/events.go

@@ -1,62 +0,0 @@
-package client
-
-import (
-	"net/url"
-	"time"
-
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers/filters"
-	"github.com/docker/docker/pkg/timeutils"
-)
-
-// CmdEvents prints a live stream of real time events from the server.
-//
-// Usage: docker events [OPTIONS]
-func (cli *DockerCli) CmdEvents(args ...string) error {
-	cmd := cli.Subcmd("events", "", "Get real time events from the server", true)
-	since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp")
-	until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
-	flFilter := opts.NewListOpts(nil)
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
-	cmd.Require(flag.Exact, 0)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		v               = url.Values{}
-		eventFilterArgs = filters.Args{}
-	)
-
-	// Consolidate all filter flags, and sanity check them early.
-	// They'll get process in the daemon/server.
-	for _, f := range flFilter.GetAll() {
-		var err error
-		eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs)
-		if err != nil {
-			return err
-		}
-	}
-	ref := time.Now()
-	if *since != "" {
-		v.Set("since", timeutils.GetTimestamp(*since, ref))
-	}
-	if *until != "" {
-		v.Set("until", timeutils.GetTimestamp(*until, ref))
-	}
-	if len(eventFilterArgs) > 0 {
-		filterJSON, err := filters.ToParam(eventFilterArgs)
-		if err != nil {
-			return err
-		}
-		v.Set("filters", filterJSON)
-	}
-	sopts := &streamOpts{
-		rawTerminal: true,
-		out:         cli.out,
-	}
-	if err := cli.stream("GET", "/events?"+v.Encode(), sopts); err != nil {
-		return err
-	}
-	return nil
-}

+ 0 - 131
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/exec.go

@@ -1,131 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/promise"
-	"github.com/docker/docker/runconfig"
-)
-
-// CmdExec runs a command in a running container.
-//
-// Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
-func (cli *DockerCli) CmdExec(args ...string) error {
-	cmd := cli.Subcmd("exec", "CONTAINER COMMAND [ARG...]", "Run a command in a running container", true)
-
-	execConfig, err := runconfig.ParseExec(cmd, args)
-	// just in case the ParseExec does not exit
-	if execConfig.Container == "" || err != nil {
-		return StatusError{StatusCode: 1}
-	}
-
-	stream, _, _, err := cli.call("POST", "/containers/"+execConfig.Container+"/exec", execConfig, nil)
-	if err != nil {
-		return err
-	}
-
-	var response types.ContainerExecCreateResponse
-	if err := json.NewDecoder(stream).Decode(&response); err != nil {
-		return err
-	}
-
-	execID := response.ID
-
-	if execID == "" {
-		fmt.Fprintf(cli.out, "exec ID empty")
-		return nil
-	}
-
-	//Temp struct for execStart so that we don't need to transfer all the execConfig
-	execStartCheck := &types.ExecStartCheck{
-		Detach: execConfig.Detach,
-		Tty:    execConfig.Tty,
-	}
-
-	if !execConfig.Detach {
-		if err := cli.CheckTtyInput(execConfig.AttachStdin, execConfig.Tty); err != nil {
-			return err
-		}
-	} else {
-		if _, _, err := readBody(cli.call("POST", "/exec/"+execID+"/start", execStartCheck, nil)); err != nil {
-			return err
-		}
-		// For now don't print this - wait for when we support exec wait()
-		// fmt.Fprintf(cli.out, "%s\n", execID)
-		return nil
-	}
-
-	// Interactive exec requested.
-	var (
-		out, stderr io.Writer
-		in          io.ReadCloser
-		hijacked    = make(chan io.Closer)
-		errCh       chan error
-	)
-
-	// Block the return until the chan gets closed
-	defer func() {
-		logrus.Debugf("End of CmdExec(), Waiting for hijack to finish.")
-		if _, ok := <-hijacked; ok {
-			fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
-		}
-	}()
-
-	if execConfig.AttachStdin {
-		in = cli.in
-	}
-	if execConfig.AttachStdout {
-		out = cli.out
-	}
-	if execConfig.AttachStderr {
-		if execConfig.Tty {
-			stderr = cli.out
-		} else {
-			stderr = cli.err
-		}
-	}
-	errCh = promise.Go(func() error {
-		return cli.hijack("POST", "/exec/"+execID+"/start", execConfig.Tty, in, out, stderr, hijacked, execConfig)
-	})
-
-	// Acknowledge the hijack before starting
-	select {
-	case closer := <-hijacked:
-		// Make sure that hijack gets closed when returning. (result
-		// in closing hijack chan and freeing server's goroutines.
-		if closer != nil {
-			defer closer.Close()
-		}
-	case err := <-errCh:
-		if err != nil {
-			logrus.Debugf("Error hijack: %s", err)
-			return err
-		}
-	}
-
-	if execConfig.Tty && cli.isTerminalIn {
-		if err := cli.monitorTtySize(execID, true); err != nil {
-			fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
-		}
-	}
-
-	if err := <-errCh; err != nil {
-		logrus.Debugf("Error hijack: %s", err)
-		return err
-	}
-
-	var status int
-	if _, status, err = getExecExitCode(cli, execID); err != nil {
-		return err
-	}
-
-	if status != 0 {
-		return StatusError{StatusCode: status}
-	}
-
-	return nil
-}

+ 0 - 46
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/export.go

@@ -1,46 +0,0 @@
-package client
-
-import (
-	"errors"
-	"io"
-	"os"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdExport exports a filesystem as a tar archive.
-//
-// The tar archive is streamed to STDOUT by default or written to a file.
-//
-// Usage: docker export [OPTIONS] CONTAINER
-func (cli *DockerCli) CmdExport(args ...string) error {
-	cmd := cli.Subcmd("export", "CONTAINER", "Export a filesystem as a tar archive (streamed to STDOUT by default)", true)
-	outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT")
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		output io.Writer = cli.out
-		err    error
-	)
-	if *outfile != "" {
-		output, err = os.Create(*outfile)
-		if err != nil {
-			return err
-		}
-	} else if cli.isTerminalOut {
-		return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.")
-	}
-
-	image := cmd.Arg(0)
-	sopts := &streamOpts{
-		rawTerminal: true,
-		out:         output,
-	}
-	if err := cli.stream("GET", "/containers/"+image+"/export", sopts); err != nil {
-		return err
-	}
-
-	return nil
-}

+ 0 - 34
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/help.go

@@ -1,34 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdHelp displays information on a Docker command.
-//
-// If more than one command is specified, information is only shown for the first command.
-//
-// Usage: docker help COMMAND or docker COMMAND --help
-func (cli *DockerCli) CmdHelp(args ...string) error {
-	if len(args) > 1 {
-		method, exists := cli.getMethod(args[:2]...)
-		if exists {
-			method("--help")
-			return nil
-		}
-	}
-	if len(args) > 0 {
-		method, exists := cli.getMethod(args[0])
-		if !exists {
-			return fmt.Errorf("docker: '%s' is not a docker command. See 'docker --help'.", args[0])
-		}
-		method("--help")
-		return nil
-	}
-
-	flag.Usage()
-
-	return nil
-}

+ 0 - 257
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/hijack.go

@@ -1,257 +0,0 @@
-package client
-
-import (
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"net/http"
-	"net/http/httputil"
-	"os"
-	"runtime"
-	"strings"
-	"time"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/autogen/dockerversion"
-	"github.com/docker/docker/pkg/promise"
-	"github.com/docker/docker/pkg/stdcopy"
-	"github.com/docker/docker/pkg/term"
-)
-
-type tlsClientCon struct {
-	*tls.Conn
-	rawConn net.Conn
-}
-
-func (c *tlsClientCon) CloseWrite() error {
-	// Go standard tls.Conn doesn't provide the CloseWrite() method so we do it
-	// on its underlying connection.
-	if cwc, ok := c.rawConn.(interface {
-		CloseWrite() error
-	}); ok {
-		return cwc.CloseWrite()
-	}
-	return nil
-}
-
-func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {
-	return tlsDialWithDialer(new(net.Dialer), network, addr, config)
-}
-
-// We need to copy Go's implementation of tls.Dial (pkg/cryptor/tls/tls.go) in
-// order to return our custom tlsClientCon struct which holds both the tls.Conn
-// object _and_ its underlying raw connection. The rationale for this is that
-// we need to be able to close the write end of the connection when attaching,
-// which tls.Conn does not provide.
-func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {
-	// We want the Timeout and Deadline values from dialer to cover the
-	// whole process: TCP connection and TLS handshake. This means that we
-	// also need to start our own timers now.
-	timeout := dialer.Timeout
-
-	if !dialer.Deadline.IsZero() {
-		deadlineTimeout := dialer.Deadline.Sub(time.Now())
-		if timeout == 0 || deadlineTimeout < timeout {
-			timeout = deadlineTimeout
-		}
-	}
-
-	var errChannel chan error
-
-	if timeout != 0 {
-		errChannel = make(chan error, 2)
-		time.AfterFunc(timeout, func() {
-			errChannel <- errors.New("")
-		})
-	}
-
-	rawConn, err := dialer.Dial(network, addr)
-	if err != nil {
-		return nil, err
-	}
-	// When we set up a TCP connection for hijack, there could be long periods
-	// of inactivity (a long running command with no output) that in certain
-	// network setups may cause ECONNTIMEOUT, leaving the client in an unknown
-	// state. Setting TCP KeepAlive on the socket connection will prohibit
-	// ECONNTIMEOUT unless the socket connection truly is broken
-	if tcpConn, ok := rawConn.(*net.TCPConn); ok {
-		tcpConn.SetKeepAlive(true)
-		tcpConn.SetKeepAlivePeriod(30 * time.Second)
-	}
-
-	colonPos := strings.LastIndex(addr, ":")
-	if colonPos == -1 {
-		colonPos = len(addr)
-	}
-	hostname := addr[:colonPos]
-
-	// If no ServerName is set, infer the ServerName
-	// from the hostname we're connecting to.
-	if config.ServerName == "" {
-		// Make a copy to avoid polluting argument or default.
-		c := *config
-		c.ServerName = hostname
-		config = &c
-	}
-
-	conn := tls.Client(rawConn, config)
-
-	if timeout == 0 {
-		err = conn.Handshake()
-	} else {
-		go func() {
-			errChannel <- conn.Handshake()
-		}()
-
-		err = <-errChannel
-	}
-
-	if err != nil {
-		rawConn.Close()
-		return nil, err
-	}
-
-	// This is Docker difference with standard's crypto/tls package: returned a
-	// wrapper which holds both the TLS and raw connections.
-	return &tlsClientCon{conn, rawConn}, nil
-}
-
-func (cli *DockerCli) dial() (net.Conn, error) {
-	if cli.tlsConfig != nil && cli.proto != "unix" {
-		// Notice this isn't Go standard's tls.Dial function
-		return tlsDial(cli.proto, cli.addr, cli.tlsConfig)
-	}
-	return net.Dial(cli.proto, cli.addr)
-}
-
-func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.ReadCloser, stdout, stderr io.Writer, started chan io.Closer, data interface{}) error {
-	defer func() {
-		if started != nil {
-			close(started)
-		}
-	}()
-
-	params, err := cli.encodeData(data)
-	if err != nil {
-		return err
-	}
-	req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params)
-	if err != nil {
-		return err
-	}
-
-	// Add CLI Config's HTTP Headers BEFORE we set the Docker headers
-	// then the user can't change OUR headers
-	for k, v := range cli.configFile.HttpHeaders {
-		req.Header.Set(k, v)
-	}
-
-	req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION+" ("+runtime.GOOS+")")
-	req.Header.Set("Content-Type", "text/plain")
-	req.Header.Set("Connection", "Upgrade")
-	req.Header.Set("Upgrade", "tcp")
-	req.Host = cli.addr
-
-	dial, err := cli.dial()
-	// When we set up a TCP connection for hijack, there could be long periods
-	// of inactivity (a long running command with no output) that in certain
-	// network setups may cause ECONNTIMEOUT, leaving the client in an unknown
-	// state. Setting TCP KeepAlive on the socket connection will prohibit
-	// ECONNTIMEOUT unless the socket connection truly is broken
-	if tcpConn, ok := dial.(*net.TCPConn); ok {
-		tcpConn.SetKeepAlive(true)
-		tcpConn.SetKeepAlivePeriod(30 * time.Second)
-	}
-	if err != nil {
-		if strings.Contains(err.Error(), "connection refused") {
-			return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?")
-		}
-		return err
-	}
-	clientconn := httputil.NewClientConn(dial, nil)
-	defer clientconn.Close()
-
-	// Server hijacks the connection, error 'connection closed' expected
-	clientconn.Do(req)
-
-	rwc, br := clientconn.Hijack()
-	defer rwc.Close()
-
-	if started != nil {
-		started <- rwc
-	}
-
-	var receiveStdout chan error
-
-	var oldState *term.State
-
-	if in != nil && setRawTerminal && cli.isTerminalIn && os.Getenv("NORAW") == "" {
-		oldState, err = term.SetRawTerminal(cli.inFd)
-		if err != nil {
-			return err
-		}
-		defer term.RestoreTerminal(cli.inFd, oldState)
-	}
-
-	if stdout != nil || stderr != nil {
-		receiveStdout = promise.Go(func() (err error) {
-			defer func() {
-				if in != nil {
-					if setRawTerminal && cli.isTerminalIn {
-						term.RestoreTerminal(cli.inFd, oldState)
-					}
-					// For some reason this Close call blocks on darwin..
-					// As the client exists right after, simply discard the close
-					// until we find a better solution.
-					if runtime.GOOS != "darwin" {
-						in.Close()
-					}
-				}
-			}()
-
-			// When TTY is ON, use regular copy
-			if setRawTerminal && stdout != nil {
-				_, err = io.Copy(stdout, br)
-			} else {
-				_, err = stdcopy.StdCopy(stdout, stderr, br)
-			}
-			logrus.Debugf("[hijack] End of stdout")
-			return err
-		})
-	}
-
-	sendStdin := promise.Go(func() error {
-		if in != nil {
-			io.Copy(rwc, in)
-			logrus.Debugf("[hijack] End of stdin")
-		}
-
-		if conn, ok := rwc.(interface {
-			CloseWrite() error
-		}); ok {
-			if err := conn.CloseWrite(); err != nil {
-				logrus.Debugf("Couldn't send EOF: %s", err)
-			}
-		}
-		// Discard errors due to pipe interruption
-		return nil
-	})
-
-	if stdout != nil || stderr != nil {
-		if err := <-receiveStdout; err != nil {
-			logrus.Debugf("Error receiveStdout: %s", err)
-			return err
-		}
-	}
-
-	if !cli.isTerminalIn {
-		if err := <-sendStdin; err != nil {
-			logrus.Debugf("Error sendStdin: %s", err)
-			return err
-		}
-	}
-	return nil
-}

+ 0 - 73
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/history.go

@@ -1,73 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"text/tabwriter"
-	"time"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/units"
-)
-
-// CmdHistory shows the history of an image.
-//
-// Usage: docker history [OPTIONS] IMAGE
-func (cli *DockerCli) CmdHistory(args ...string) error {
-	cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image", true)
-	human := cmd.Bool([]string{"H", "-human"}, true, "Print sizes and dates in human readable format")
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
-	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
-	cmd.Require(flag.Exact, 1)
-	cmd.ParseFlags(args, true)
-
-	rdr, _, _, err := cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	history := []types.ImageHistory{}
-	if err := json.NewDecoder(rdr).Decode(&history); err != nil {
-		return err
-	}
-
-	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	if !*quiet {
-		fmt.Fprintln(w, "IMAGE\tCREATED\tCREATED BY\tSIZE\tCOMMENT")
-	}
-
-	for _, entry := range history {
-		if *noTrunc {
-			fmt.Fprintf(w, entry.ID)
-		} else {
-			fmt.Fprintf(w, stringid.TruncateID(entry.ID))
-		}
-		if !*quiet {
-			if *human {
-				fmt.Fprintf(w, "\t%s ago\t", units.HumanDuration(time.Now().UTC().Sub(time.Unix(entry.Created, 0))))
-			} else {
-				fmt.Fprintf(w, "\t%s\t", time.Unix(entry.Created, 0).Format(time.RFC3339))
-			}
-
-			if *noTrunc {
-				fmt.Fprintf(w, "%s\t", entry.CreatedBy)
-			} else {
-				fmt.Fprintf(w, "%s\t", stringutils.Truncate(entry.CreatedBy, 45))
-			}
-
-			if *human {
-				fmt.Fprintf(w, "%s\t", units.HumanSize(float64(entry.Size)))
-			} else {
-				fmt.Fprintf(w, "%d\t", entry.Size)
-			}
-
-			fmt.Fprintf(w, "%s", entry.Comment)
-		}
-		fmt.Fprintf(w, "\n")
-	}
-	w.Flush()
-	return nil
-}

+ 0 - 126
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/images.go

@@ -1,126 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-	"text/tabwriter"
-	"time"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/pkg/parsers/filters"
-	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/units"
-	"github.com/docker/docker/utils"
-)
-
-// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
-//
-// Usage: docker images [OPTIONS] [REPOSITORY]
-func (cli *DockerCli) CmdImages(args ...string) error {
-	cmd := cli.Subcmd("images", "[REPOSITORY]", "List images", true)
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
-	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
-	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
-	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
-
-	flFilter := opts.NewListOpts(nil)
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
-	cmd.Require(flag.Max, 1)
-	cmd.ParseFlags(args, true)
-
-	// Consolidate all filter flags, and sanity check them early.
-	// They'll get process in the daemon/server.
-	imageFilterArgs := filters.Args{}
-	for _, f := range flFilter.GetAll() {
-		var err error
-		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
-		if err != nil {
-			return err
-		}
-	}
-
-	matchName := cmd.Arg(0)
-	v := url.Values{}
-	if len(imageFilterArgs) > 0 {
-		filterJSON, err := filters.ToParam(imageFilterArgs)
-		if err != nil {
-			return err
-		}
-		v.Set("filters", filterJSON)
-	}
-
-	if cmd.NArg() == 1 {
-		// FIXME rename this parameter, to not be confused with the filters flag
-		v.Set("filter", matchName)
-	}
-	if *all {
-		v.Set("all", "1")
-	}
-
-	rdr, _, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil)
-	if err != nil {
-		return err
-	}
-
-	images := []types.Image{}
-	if err := json.NewDecoder(rdr).Decode(&images); err != nil {
-		return err
-	}
-
-	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	if !*quiet {
-		if *showDigests {
-			fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
-		} else {
-			fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
-		}
-	}
-
-	for _, image := range images {
-		ID := image.ID
-		if !*noTrunc {
-			ID = stringid.TruncateID(ID)
-		}
-
-		repoTags := image.RepoTags
-		repoDigests := image.RepoDigests
-
-		if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
-			// dangling image - clear out either repoTags or repoDigsts so we only show it once below
-			repoDigests = []string{}
-		}
-
-		// combine the tags and digests lists
-		tagsAndDigests := append(repoTags, repoDigests...)
-		for _, repoAndRef := range tagsAndDigests {
-			repo, ref := parsers.ParseRepositoryTag(repoAndRef)
-			// default tag and digest to none - if there's a value, it'll be set below
-			tag := "<none>"
-			digest := "<none>"
-			if utils.DigestReference(ref) {
-				digest = ref
-			} else {
-				tag = ref
-			}
-
-			if !*quiet {
-				if *showDigests {
-					fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
-				} else {
-					fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
-				}
-			} else {
-				fmt.Fprintln(w, ID)
-			}
-		}
-	}
-
-	if !*quiet {
-		w.Flush()
-	}
-	return nil
-}

+ 0 - 64
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/import.go

@@ -1,64 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"io"
-	"net/url"
-
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-)
-
-// CmdImport creates an empty filesystem image, imports the contents of the tarball into the image, and optionally tags the image.
-//
-// The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file. If the URL is '-', then the tar file is read from STDIN.
-//
-// Usage: docker import [OPTIONS] URL [REPOSITORY[:TAG]]
-func (cli *DockerCli) CmdImport(args ...string) error {
-	cmd := cli.Subcmd("import", "URL|- [REPOSITORY[:TAG]]", "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
-	flChanges := opts.NewListOpts(nil)
-	cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		v          = url.Values{}
-		src        = cmd.Arg(0)
-		repository = cmd.Arg(1)
-	)
-
-	v.Set("fromSrc", src)
-	v.Set("repo", repository)
-	for _, change := range flChanges.GetAll() {
-		v.Add("changes", change)
-	}
-	if cmd.NArg() == 3 {
-		fmt.Fprintf(cli.err, "[DEPRECATED] The format 'URL|- [REPOSITORY [TAG]]' has been deprecated. Please use URL|- [REPOSITORY[:TAG]]\n")
-		v.Set("tag", cmd.Arg(2))
-	}
-
-	if repository != "" {
-		//Check if the given image name can be resolved
-		repo, _ := parsers.ParseRepositoryTag(repository)
-		if err := registry.ValidateRepositoryName(repo); err != nil {
-			return err
-		}
-	}
-
-	var in io.Reader
-
-	if src == "-" {
-		in = cli.in
-	}
-
-	sopts := &streamOpts{
-		rawTerminal: true,
-		in:          in,
-		out:         cli.out,
-	}
-
-	return cli.stream("POST", "/images/create?"+v.Encode(), sopts)
-}

+ 0 - 91
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/info.go

@@ -1,91 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/ioutils"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/units"
-)
-
-// CmdInfo displays system-wide information.
-//
-// Usage: docker info
-func (cli *DockerCli) CmdInfo(args ...string) error {
-	cmd := cli.Subcmd("info", "", "Display system-wide information", true)
-	cmd.Require(flag.Exact, 0)
-	cmd.ParseFlags(args, true)
-
-	rdr, _, _, err := cli.call("GET", "/info", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	info := &types.Info{}
-	if err := json.NewDecoder(rdr).Decode(info); err != nil {
-		return fmt.Errorf("Error reading remote info: %v", err)
-	}
-
-	fmt.Fprintf(cli.out, "Containers: %d\n", info.Containers)
-	fmt.Fprintf(cli.out, "Images: %d\n", info.Images)
-	ioutils.FprintfIfNotEmpty(cli.out, "Storage Driver: %s\n", info.Driver)
-	if info.DriverStatus != nil {
-		for _, pair := range info.DriverStatus {
-			fmt.Fprintf(cli.out, " %s: %s\n", pair[0], pair[1])
-		}
-	}
-	ioutils.FprintfIfNotEmpty(cli.out, "Execution Driver: %s\n", info.ExecutionDriver)
-	ioutils.FprintfIfNotEmpty(cli.out, "Logging Driver: %s\n", info.LoggingDriver)
-	ioutils.FprintfIfNotEmpty(cli.out, "Kernel Version: %s\n", info.KernelVersion)
-	ioutils.FprintfIfNotEmpty(cli.out, "Operating System: %s\n", info.OperatingSystem)
-	fmt.Fprintf(cli.out, "CPUs: %d\n", info.NCPU)
-	fmt.Fprintf(cli.out, "Total Memory: %s\n", units.BytesSize(float64(info.MemTotal)))
-	ioutils.FprintfIfNotEmpty(cli.out, "Name: %s\n", info.Name)
-	ioutils.FprintfIfNotEmpty(cli.out, "ID: %s\n", info.ID)
-
-	if info.Debug {
-		fmt.Fprintf(cli.out, "Debug mode (server): %v\n", info.Debug)
-		fmt.Fprintf(cli.out, "File Descriptors: %d\n", info.NFd)
-		fmt.Fprintf(cli.out, "Goroutines: %d\n", info.NGoroutines)
-		fmt.Fprintf(cli.out, "System Time: %s\n", info.SystemTime)
-		fmt.Fprintf(cli.out, "EventsListeners: %d\n", info.NEventsListener)
-		fmt.Fprintf(cli.out, "Init SHA1: %s\n", info.InitSha1)
-		fmt.Fprintf(cli.out, "Init Path: %s\n", info.InitPath)
-		fmt.Fprintf(cli.out, "Docker Root Dir: %s\n", info.DockerRootDir)
-	}
-
-	ioutils.FprintfIfNotEmpty(cli.out, "Http Proxy: %s\n", info.HttpProxy)
-	ioutils.FprintfIfNotEmpty(cli.out, "Https Proxy: %s\n", info.HttpsProxy)
-	ioutils.FprintfIfNotEmpty(cli.out, "No Proxy: %s\n", info.NoProxy)
-
-	if info.IndexServerAddress != "" {
-		u := cli.configFile.AuthConfigs[info.IndexServerAddress].Username
-		if len(u) > 0 {
-			fmt.Fprintf(cli.out, "Username: %v\n", u)
-			fmt.Fprintf(cli.out, "Registry: %v\n", info.IndexServerAddress)
-		}
-	}
-	if !info.MemoryLimit {
-		fmt.Fprintf(cli.err, "WARNING: No memory limit support\n")
-	}
-	if !info.SwapLimit {
-		fmt.Fprintf(cli.err, "WARNING: No swap limit support\n")
-	}
-	if !info.IPv4Forwarding {
-		fmt.Fprintf(cli.err, "WARNING: IPv4 forwarding is disabled.\n")
-	}
-	if info.Labels != nil {
-		fmt.Fprintln(cli.out, "Labels:")
-		for _, attribute := range info.Labels {
-			fmt.Fprintf(cli.out, " %s\n", attribute)
-		}
-	}
-
-	if info.ExperimentalBuild {
-		fmt.Fprintf(cli.out, "Experimental: true\n")
-	}
-
-	return nil
-}

+ 0 - 124
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/inspect.go

@@ -1,124 +0,0 @@
-package client
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"strings"
-	"text/template"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdInspect displays low-level information on one or more containers or images.
-//
-// Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
-func (cli *DockerCli) CmdInspect(args ...string) error {
-	cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image", true)
-	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var tmpl *template.Template
-	if *tmplStr != "" {
-		var err error
-		if tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr); err != nil {
-			return StatusError{StatusCode: 64,
-				Status: "Template parsing error: " + err.Error()}
-		}
-	}
-
-	indented := new(bytes.Buffer)
-	indented.WriteString("[\n")
-	status := 0
-	isImage := false
-
-	for _, name := range cmd.Args() {
-		obj, _, err := readBody(cli.call("GET", "/containers/"+name+"/json", nil, nil))
-		if err != nil {
-			obj, _, err = readBody(cli.call("GET", "/images/"+name+"/json", nil, nil))
-			isImage = true
-			if err != nil {
-				if strings.Contains(err.Error(), "No such") {
-					fmt.Fprintf(cli.err, "Error: No such image or container: %s\n", name)
-				} else {
-					fmt.Fprintf(cli.err, "%s", err)
-				}
-				status = 1
-				continue
-			}
-		}
-
-		if tmpl == nil {
-			if err = json.Indent(indented, obj, "", "    "); err != nil {
-				fmt.Fprintf(cli.err, "%s\n", err)
-				status = 1
-				continue
-			}
-		} else {
-			rdr := bytes.NewReader(obj)
-			dec := json.NewDecoder(rdr)
-
-			if isImage {
-				inspPtr := types.ImageInspect{}
-				if err := dec.Decode(&inspPtr); err != nil {
-					fmt.Fprintf(cli.err, "%s\n", err)
-					status = 1
-					continue
-				}
-				if err := tmpl.Execute(cli.out, inspPtr); err != nil {
-					rdr.Seek(0, 0)
-					var raw interface{}
-					if err := dec.Decode(&raw); err != nil {
-						return err
-					}
-					if err = tmpl.Execute(cli.out, raw); err != nil {
-						return err
-					}
-				}
-			} else {
-				inspPtr := types.ContainerJSON{}
-				if err := dec.Decode(&inspPtr); err != nil {
-					fmt.Fprintf(cli.err, "%s\n", err)
-					status = 1
-					continue
-				}
-				if err := tmpl.Execute(cli.out, inspPtr); err != nil {
-					rdr.Seek(0, 0)
-					var raw interface{}
-					if err := dec.Decode(&raw); err != nil {
-						return err
-					}
-					if err = tmpl.Execute(cli.out, raw); err != nil {
-						return err
-					}
-				}
-			}
-			cli.out.Write([]byte{'\n'})
-		}
-		indented.WriteString(",")
-	}
-
-	if indented.Len() > 1 {
-		// Remove trailing ','
-		indented.Truncate(indented.Len() - 1)
-	}
-	indented.WriteString("]\n")
-
-	if tmpl == nil {
-		// Note that we will always write "[]" when "-f" isn't specified,
-		// to make sure the output would always be array, see
-		// https://github.com/docker/docker/pull/9500#issuecomment-65846734
-		if _, err := io.Copy(cli.out, indented); err != nil {
-			return err
-		}
-	}
-
-	if status != 0 {
-		return StatusError{StatusCode: status}
-	}
-	return nil
-}

+ 0 - 32
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/kill.go

@@ -1,32 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdKill kills one or more running container using SIGKILL or a specified signal.
-//
-// Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdKill(args ...string) error {
-	cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal", true)
-	signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", name, *signal), nil, nil)); err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to kill containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 41
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/load.go

@@ -1,41 +0,0 @@
-package client
-
-import (
-	"io"
-	"os"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdLoad loads an image from a tar archive.
-//
-// The tar archive is read from STDIN by default, or from a tar archive file.
-//
-// Usage: docker load [OPTIONS]
-func (cli *DockerCli) CmdLoad(args ...string) error {
-	cmd := cli.Subcmd("load", "", "Load an image from a tar archive on STDIN", true)
-	infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN")
-	cmd.Require(flag.Exact, 0)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		input io.Reader = cli.in
-		err   error
-	)
-	if *infile != "" {
-		input, err = os.Open(*infile)
-		if err != nil {
-			return err
-		}
-	}
-	sopts := &streamOpts{
-		rawTerminal: true,
-		in:          input,
-		out:         cli.out,
-	}
-	if err := cli.stream("POST", "/images/load", sopts); err != nil {
-		return err
-	}
-	return nil
-}

+ 0 - 144
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/login.go

@@ -1,144 +0,0 @@
-package client
-
-import (
-	"bufio"
-	"encoding/json"
-	"fmt"
-	"io"
-	"os"
-	"strings"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/cliconfig"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/term"
-	"github.com/docker/docker/registry"
-)
-
-// CmdLogin logs in or registers a user to a Docker registry service.
-//
-// If no server is specified, the user will be logged into or registered to the registry's index server.
-//
-// Usage: docker login SERVER
-func (cli *DockerCli) CmdLogin(args ...string) error {
-	cmd := cli.Subcmd("login", "[SERVER]", "Register or log in to a Docker registry server, if no server is\nspecified \""+registry.IndexServerAddress()+"\" is the default.", true)
-	cmd.Require(flag.Max, 1)
-
-	var username, password, email string
-
-	cmd.StringVar(&username, []string{"u", "-username"}, "", "Username")
-	cmd.StringVar(&password, []string{"p", "-password"}, "", "Password")
-	cmd.StringVar(&email, []string{"e", "-email"}, "", "Email")
-
-	cmd.ParseFlags(args, true)
-
-	serverAddress := registry.IndexServerAddress()
-	if len(cmd.Args()) > 0 {
-		serverAddress = cmd.Arg(0)
-	}
-
-	promptDefault := func(prompt string, configDefault string) {
-		if configDefault == "" {
-			fmt.Fprintf(cli.out, "%s: ", prompt)
-		} else {
-			fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault)
-		}
-	}
-
-	readInput := func(in io.Reader, out io.Writer) string {
-		reader := bufio.NewReader(in)
-		line, _, err := reader.ReadLine()
-		if err != nil {
-			fmt.Fprintln(out, err.Error())
-			os.Exit(1)
-		}
-		return string(line)
-	}
-
-	authconfig, ok := cli.configFile.AuthConfigs[serverAddress]
-	if !ok {
-		authconfig = cliconfig.AuthConfig{}
-	}
-
-	if username == "" {
-		promptDefault("Username", authconfig.Username)
-		username = readInput(cli.in, cli.out)
-		username = strings.Trim(username, " ")
-		if username == "" {
-			username = authconfig.Username
-		}
-	}
-	// Assume that a different username means they may not want to use
-	// the password or email from the config file, so prompt them
-	if username != authconfig.Username {
-		if password == "" {
-			oldState, err := term.SaveState(cli.inFd)
-			if err != nil {
-				return err
-			}
-			fmt.Fprintf(cli.out, "Password: ")
-			term.DisableEcho(cli.inFd, oldState)
-
-			password = readInput(cli.in, cli.out)
-			fmt.Fprint(cli.out, "\n")
-
-			term.RestoreTerminal(cli.inFd, oldState)
-			if password == "" {
-				return fmt.Errorf("Error : Password Required")
-			}
-		}
-
-		if email == "" {
-			promptDefault("Email", authconfig.Email)
-			email = readInput(cli.in, cli.out)
-			if email == "" {
-				email = authconfig.Email
-			}
-		}
-	} else {
-		// However, if they don't override the username use the
-		// password or email from the cmd line if specified. IOW, allow
-		// then to change/override them.  And if not specified, just
-		// use what's in the config file
-		if password == "" {
-			password = authconfig.Password
-		}
-		if email == "" {
-			email = authconfig.Email
-		}
-	}
-	authconfig.Username = username
-	authconfig.Password = password
-	authconfig.Email = email
-	authconfig.ServerAddress = serverAddress
-	cli.configFile.AuthConfigs[serverAddress] = authconfig
-
-	stream, _, statusCode, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil)
-	if statusCode == 401 {
-		delete(cli.configFile.AuthConfigs, serverAddress)
-		if err2 := cli.configFile.Save(); err2 != nil {
-			fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2)
-		}
-		return err
-	}
-	if err != nil {
-		return err
-	}
-
-	var response types.AuthResponse
-	if err := json.NewDecoder(stream).Decode(&response); err != nil {
-		// Upon error, remove entry
-		delete(cli.configFile.AuthConfigs, serverAddress)
-		return err
-	}
-
-	if err := cli.configFile.Save(); err != nil {
-		return fmt.Errorf("Error saving config file: %v", err)
-	}
-	fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename())
-
-	if response.Status != "" {
-		fmt.Fprintf(cli.out, "%s\n", response.Status)
-	}
-	return nil
-}

+ 0 - 36
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/logout.go

@@ -1,36 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/registry"
-)
-
-// CmdLogout logs a user out from a Docker registry.
-//
-// If no server is specified, the user will be logged out from the registry's index server.
-//
-// Usage: docker logout [SERVER]
-func (cli *DockerCli) CmdLogout(args ...string) error {
-	cmd := cli.Subcmd("logout", "[SERVER]", "Log out from a Docker registry, if no server is\nspecified \""+registry.IndexServerAddress()+"\" is the default.", true)
-	cmd.Require(flag.Max, 1)
-
-	cmd.ParseFlags(args, true)
-	serverAddress := registry.IndexServerAddress()
-	if len(cmd.Args()) > 0 {
-		serverAddress = cmd.Arg(0)
-	}
-
-	if _, ok := cli.configFile.AuthConfigs[serverAddress]; !ok {
-		fmt.Fprintf(cli.out, "Not logged in to %s\n", serverAddress)
-	} else {
-		fmt.Fprintf(cli.out, "Remove login credentials for %s\n", serverAddress)
-		delete(cli.configFile.AuthConfigs, serverAddress)
-
-		if err := cli.configFile.Save(); err != nil {
-			return fmt.Errorf("Failed to save docker config: %v", err)
-		}
-	}
-	return nil
-}

+ 0 - 69
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/logs.go

@@ -1,69 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-	"time"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/timeutils"
-)
-
-// CmdLogs fetches the logs of a given container.
-//
-// docker logs [OPTIONS] CONTAINER
-func (cli *DockerCli) CmdLogs(args ...string) error {
-	var (
-		cmd    = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container", true)
-		follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
-		since  = cmd.String([]string{"-since"}, "", "Show logs since timestamp")
-		times  = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
-		tail   = cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs")
-	)
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-
-	name := cmd.Arg(0)
-
-	stream, _, _, err := cli.call("GET", "/containers/"+name+"/json", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	var c types.ContainerJSON
-	if err := json.NewDecoder(stream).Decode(&c); err != nil {
-		return err
-	}
-
-	if logType := c.HostConfig.LogConfig.Type; logType != "json-file" {
-		return fmt.Errorf("\"logs\" command is supported only for \"json-file\" logging driver (got: %s)", logType)
-	}
-
-	v := url.Values{}
-	v.Set("stdout", "1")
-	v.Set("stderr", "1")
-
-	if *since != "" {
-		v.Set("since", timeutils.GetTimestamp(*since, time.Now()))
-	}
-
-	if *times {
-		v.Set("timestamps", "1")
-	}
-
-	if *follow {
-		v.Set("follow", "1")
-	}
-	v.Set("tail", *tail)
-
-	sopts := &streamOpts{
-		rawTerminal: c.Config.Tty,
-		out:         cli.out,
-		err:         cli.err,
-	}
-
-	return cli.stream("GET", "/containers/"+name+"/logs?"+v.Encode(), sopts)
-}

+ 0 - 30
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/pause.go

@@ -1,30 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdPause pauses all processes within one or more containers.
-//
-// Usage: docker pause CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdPause(args ...string) error {
-	cmd := cli.Subcmd("pause", "CONTAINER [CONTAINER...]", "Pause all processes within a container", true)
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/pause", name), nil, nil)); err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to pause containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 64
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/port.go

@@ -1,64 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"strings"
-
-	"github.com/docker/docker/nat"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdPort lists port mappings for a container.
-// If a private port is specified, it also shows the public-facing port that is NATed to the private port.
-//
-// Usage: docker port CONTAINER [PRIVATE_PORT[/PROTO]]
-func (cli *DockerCli) CmdPort(args ...string) error {
-	cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that\nis NAT-ed to the PRIVATE_PORT", true)
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	stream, _, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	var c struct {
-		NetworkSettings struct {
-			Ports nat.PortMap
-		}
-	}
-
-	if err := json.NewDecoder(stream).Decode(&c); err != nil {
-		return err
-	}
-
-	if cmd.NArg() == 2 {
-		var (
-			port  = cmd.Arg(1)
-			proto = "tcp"
-			parts = strings.SplitN(port, "/", 2)
-		)
-
-		if len(parts) == 2 && len(parts[1]) != 0 {
-			port = parts[0]
-			proto = parts[1]
-		}
-		natPort := port + "/" + proto
-		if frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
-			for _, frontend := range frontends {
-				fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort)
-			}
-			return nil
-		}
-		return fmt.Errorf("Error: No public port '%s' published for %s", natPort, cmd.Arg(0))
-	}
-
-	for from, frontends := range c.NetworkSettings.Ports {
-		for _, frontend := range frontends {
-			fmt.Fprintf(cli.out, "%s -> %s:%s\n", from, frontend.HostIp, frontend.HostPort)
-		}
-	}
-
-	return nil
-}

+ 0 - 175
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/ps.go

@@ -1,175 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-	"strconv"
-	"strings"
-	"text/tabwriter"
-	"time"
-
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers/filters"
-	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/units"
-)
-
-// CmdPs outputs a list of Docker containers.
-//
-// Usage: docker ps [OPTIONS]
-func (cli *DockerCli) CmdPs(args ...string) error {
-	var (
-		err error
-
-		psFilterArgs = filters.Args{}
-		v            = url.Values{}
-
-		cmd      = cli.Subcmd("ps", "", "List containers", true)
-		quiet    = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
-		size     = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
-		all      = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)")
-		noTrunc  = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
-		nLatest  = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container, include non-running")
-		since    = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show created since Id or Name, include non-running")
-		before   = cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name")
-		last     = cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running")
-		flFilter = opts.NewListOpts(nil)
-	)
-	cmd.Require(flag.Exact, 0)
-
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
-
-	cmd.ParseFlags(args, true)
-	if *last == -1 && *nLatest {
-		*last = 1
-	}
-
-	if *all {
-		v.Set("all", "1")
-	}
-
-	if *last != -1 {
-		v.Set("limit", strconv.Itoa(*last))
-	}
-
-	if *since != "" {
-		v.Set("since", *since)
-	}
-
-	if *before != "" {
-		v.Set("before", *before)
-	}
-
-	if *size {
-		v.Set("size", "1")
-	}
-
-	// Consolidate all filter flags, and sanity check them.
-	// They'll get processed in the daemon/server.
-	for _, f := range flFilter.GetAll() {
-		if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil {
-			return err
-		}
-	}
-
-	if len(psFilterArgs) > 0 {
-		filterJSON, err := filters.ToParam(psFilterArgs)
-		if err != nil {
-			return err
-		}
-
-		v.Set("filters", filterJSON)
-	}
-
-	rdr, _, _, err := cli.call("GET", "/containers/json?"+v.Encode(), nil, nil)
-	if err != nil {
-		return err
-	}
-
-	containers := []types.Container{}
-	if err := json.NewDecoder(rdr).Decode(&containers); err != nil {
-		return err
-	}
-
-	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	if !*quiet {
-		fmt.Fprint(w, "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES")
-
-		if *size {
-			fmt.Fprintln(w, "\tSIZE")
-		} else {
-			fmt.Fprint(w, "\n")
-		}
-	}
-
-	stripNamePrefix := func(ss []string) []string {
-		for i, s := range ss {
-			ss[i] = s[1:]
-		}
-
-		return ss
-	}
-
-	for _, container := range containers {
-		ID := container.ID
-
-		if !*noTrunc {
-			ID = stringid.TruncateID(ID)
-		}
-
-		if *quiet {
-			fmt.Fprintln(w, ID)
-
-			continue
-		}
-
-		var (
-			names   = stripNamePrefix(container.Names)
-			command = strconv.Quote(container.Command)
-		)
-
-		if !*noTrunc {
-			command = stringutils.Truncate(command, 20)
-
-			// only display the default name for the container with notrunc is passed
-			for _, name := range names {
-				if len(strings.Split(name, "/")) == 1 {
-					names = []string{name}
-					break
-				}
-			}
-		}
-
-		image := container.Image
-		if image == "" {
-			image = "<no image>"
-		}
-
-		fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", ID, image, command,
-			units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(container.Created), 0))),
-			container.Status, api.DisplayablePorts(container.Ports), strings.Join(names, ","))
-
-		if *size {
-			if container.SizeRootFs > 0 {
-				fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(float64(container.SizeRw)), units.HumanSize(float64(container.SizeRootFs)))
-			} else {
-				fmt.Fprintf(w, "%s\n", units.HumanSize(float64(container.SizeRw)))
-			}
-
-			continue
-		}
-
-		fmt.Fprint(w, "\n")
-	}
-
-	if !*quiet {
-		w.Flush()
-	}
-
-	return nil
-}

+ 0 - 47
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/pull.go

@@ -1,47 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"net/url"
-
-	"github.com/docker/docker/graph/tags"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-	"github.com/docker/docker/utils"
-)
-
-// CmdPull pulls an image or a repository from the registry.
-//
-// Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST]
-func (cli *DockerCli) CmdPull(args ...string) error {
-	cmd := cli.Subcmd("pull", "NAME[:TAG|@DIGEST]", "Pull an image or a repository from the registry", true)
-	allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository")
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		v         = url.Values{}
-		remote    = cmd.Arg(0)
-		newRemote = remote
-	)
-	taglessRemote, tag := parsers.ParseRepositoryTag(remote)
-	if tag == "" && !*allTags {
-		newRemote = utils.ImageReference(taglessRemote, tags.DEFAULTTAG)
-	}
-	if tag != "" && *allTags {
-		return fmt.Errorf("tag can't be used with --all-tags/-a")
-	}
-
-	v.Set("fromImage", newRemote)
-
-	// Resolve the Repository name from fqn to RepositoryInfo
-	repoInfo, err := registry.ParseRepositoryInfo(taglessRemote)
-	if err != nil {
-		return err
-	}
-
-	_, _, err = cli.clientRequestAttemptLogin("POST", "/images/create?"+v.Encode(), nil, cli.out, repoInfo.Index, "pull")
-	return err
-}

+ 0 - 49
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/push.go

@@ -1,49 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"net/url"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-)
-
-// CmdPush pushes an image or repository to the registry.
-//
-// Usage: docker push NAME[:TAG]
-func (cli *DockerCli) CmdPush(args ...string) error {
-	cmd := cli.Subcmd("push", "NAME[:TAG]", "Push an image or a repository to the registry", true)
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-
-	name := cmd.Arg(0)
-
-	remote, tag := parsers.ParseRepositoryTag(name)
-
-	// Resolve the Repository name from fqn to RepositoryInfo
-	repoInfo, err := registry.ParseRepositoryInfo(remote)
-	if err != nil {
-		return err
-	}
-	// Resolve the Auth config relevant for this server
-	authConfig := registry.ResolveAuthConfig(cli.configFile, repoInfo.Index)
-	// If we're not using a custom registry, we know the restrictions
-	// applied to repository names and can warn the user in advance.
-	// Custom repositories can have different rules, and we must also
-	// allow pushing by image ID.
-	if repoInfo.Official {
-		username := authConfig.Username
-		if username == "" {
-			username = "<user>"
-		}
-		return fmt.Errorf("You cannot push a \"root\" repository. Please rename your repository to <user>/<repo> (ex: %s/%s)", username, repoInfo.LocalName)
-	}
-
-	v := url.Values{}
-	v.Set("tag", tag)
-
-	_, _, err = cli.clientRequestAttemptLogin("POST", "/images/"+remote+"/push?"+v.Encode(), nil, cli.out, repoInfo.Index, "push")
-	return err
-}

+ 0 - 25
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rename.go

@@ -1,25 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdRename renames a container.
-//
-// Usage: docker rename OLD_NAME NEW_NAME
-func (cli *DockerCli) CmdRename(args ...string) error {
-	cmd := cli.Subcmd("rename", "OLD_NAME NEW_NAME", "Rename a container", true)
-	cmd.Require(flag.Exact, 2)
-	cmd.ParseFlags(args, true)
-
-	oldName := cmd.Arg(0)
-	newName := cmd.Arg(1)
-
-	if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/rename?name=%s", oldName, newName), nil, nil)); err != nil {
-		fmt.Fprintf(cli.err, "%s\n", err)
-		return fmt.Errorf("Error: failed to rename container named %s", oldName)
-	}
-	return nil
-}

+ 0 - 38
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/restart.go

@@ -1,38 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"net/url"
-	"strconv"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdRestart restarts one or more running containers.
-//
-// Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdRestart(args ...string) error {
-	cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container", true)
-	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Seconds to wait for stop before killing the container")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	v := url.Values{}
-	v.Set("t", strconv.Itoa(*nSeconds))
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/restart?"+v.Encode(), nil, nil))
-		if err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to restart containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 54
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rm.go

@@ -1,54 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"net/url"
-	"strings"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdRm removes one or more containers.
-//
-// Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdRm(args ...string) error {
-	cmd := cli.Subcmd("rm", "CONTAINER [CONTAINER...]", "Remove one or more containers", true)
-	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container")
-	link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link")
-	force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	val := url.Values{}
-	if *v {
-		val.Set("v", "1")
-	}
-	if *link {
-		val.Set("link", "1")
-	}
-
-	if *force {
-		val.Set("force", "1")
-	}
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		if name == "" {
-			return fmt.Errorf("Container name cannot be empty")
-		}
-		name = strings.Trim(name, "/")
-
-		_, _, err := readBody(cli.call("DELETE", "/containers/"+name+"?"+val.Encode(), nil, nil))
-		if err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to remove containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 59
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/rmi.go

@@ -1,59 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdRmi removes all images with the specified name(s).
-//
-// Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
-func (cli *DockerCli) CmdRmi(args ...string) error {
-	var (
-		cmd     = cli.Subcmd("rmi", "IMAGE [IMAGE...]", "Remove one or more images", true)
-		force   = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image")
-		noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents")
-	)
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	v := url.Values{}
-	if *force {
-		v.Set("force", "1")
-	}
-	if *noprune {
-		v.Set("noprune", "1")
-	}
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		rdr, _, _, err := cli.call("DELETE", "/images/"+name+"?"+v.Encode(), nil, nil)
-		if err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			dels := []types.ImageDelete{}
-			if err := json.NewDecoder(rdr).Decode(&dels); err != nil {
-				fmt.Fprintf(cli.err, "%s\n", err)
-				errNames = append(errNames, name)
-				continue
-			}
-
-			for _, del := range dels {
-				if del.Deleted != "" {
-					fmt.Fprintf(cli.out, "Deleted: %s\n", del.Deleted)
-				} else {
-					fmt.Fprintf(cli.out, "Untagged: %s\n", del.Untagged)
-				}
-			}
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to remove images: %v", errNames)
-	}
-	return nil
-}

+ 0 - 247
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/run.go

@@ -1,247 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"io"
-	"net/url"
-	"os"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/opts"
-	"github.com/docker/docker/pkg/promise"
-	"github.com/docker/docker/pkg/signal"
-	"github.com/docker/docker/runconfig"
-	"github.com/docker/libnetwork/resolvconf/dns"
-)
-
-func (cid *cidFile) Close() error {
-	cid.file.Close()
-
-	if !cid.written {
-		if err := os.Remove(cid.path); err != nil {
-			return fmt.Errorf("failed to remove the CID file '%s': %s \n", cid.path, err)
-		}
-	}
-
-	return nil
-}
-
-func (cid *cidFile) Write(id string) error {
-	if _, err := cid.file.Write([]byte(id)); err != nil {
-		return fmt.Errorf("Failed to write the container ID to the file: %s", err)
-	}
-	cid.written = true
-	return nil
-}
-
-// CmdRun runs a command in a new container.
-//
-// Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-func (cli *DockerCli) CmdRun(args ...string) error {
-	cmd := cli.Subcmd("run", "IMAGE [COMMAND] [ARG...]", "Run a command in a new container", true)
-
-	// These are flags not stored in Config/HostConfig
-	var (
-		flAutoRemove = cmd.Bool([]string{"-rm"}, false, "Automatically remove the container when it exits")
-		flDetach     = cmd.Bool([]string{"d", "-detach"}, false, "Run container in background and print container ID")
-		flSigProxy   = cmd.Bool([]string{"-sig-proxy"}, true, "Proxy received signals to the process")
-		flName       = cmd.String([]string{"-name"}, "", "Assign a name to the container")
-		flAttach     *opts.ListOpts
-
-		ErrConflictAttachDetach               = fmt.Errorf("Conflicting options: -a and -d")
-		ErrConflictRestartPolicyAndAutoRemove = fmt.Errorf("Conflicting options: --restart and --rm")
-		ErrConflictDetachAutoRemove           = fmt.Errorf("Conflicting options: --rm and -d")
-	)
-
-	config, hostConfig, cmd, err := runconfig.Parse(cmd, args)
-	// just in case the Parse does not exit
-	if err != nil {
-		cmd.ReportError(err.Error(), true)
-		os.Exit(1)
-	}
-
-	if len(hostConfig.Dns) > 0 {
-		// check the DNS settings passed via --dns against
-		// localhost regexp to warn if they are trying to
-		// set a DNS to a localhost address
-		for _, dnsIP := range hostConfig.Dns {
-			if dns.IsLocalhost(dnsIP) {
-				fmt.Fprintf(cli.err, "WARNING: Localhost DNS setting (--dns=%s) may fail in containers.\n", dnsIP)
-				break
-			}
-		}
-	}
-	if config.Image == "" {
-		cmd.Usage()
-		return nil
-	}
-
-	if !*flDetach {
-		if err := cli.CheckTtyInput(config.AttachStdin, config.Tty); err != nil {
-			return err
-		}
-	} else {
-		if fl := cmd.Lookup("-attach"); fl != nil {
-			flAttach = fl.Value.(*opts.ListOpts)
-			if flAttach.Len() != 0 {
-				return ErrConflictAttachDetach
-			}
-		}
-		if *flAutoRemove {
-			return ErrConflictDetachAutoRemove
-		}
-
-		config.AttachStdin = false
-		config.AttachStdout = false
-		config.AttachStderr = false
-		config.StdinOnce = false
-	}
-
-	// Disable flSigProxy when in TTY mode
-	sigProxy := *flSigProxy
-	if config.Tty {
-		sigProxy = false
-	}
-
-	createResponse, err := cli.createContainer(config, hostConfig, hostConfig.ContainerIDFile, *flName)
-	if err != nil {
-		return err
-	}
-	if sigProxy {
-		sigc := cli.forwardAllSignals(createResponse.ID)
-		defer signal.StopCatch(sigc)
-	}
-	var (
-		waitDisplayID chan struct{}
-		errCh         chan error
-	)
-	if !config.AttachStdout && !config.AttachStderr {
-		// Make this asynchronous to allow the client to write to stdin before having to read the ID
-		waitDisplayID = make(chan struct{})
-		go func() {
-			defer close(waitDisplayID)
-			fmt.Fprintf(cli.out, "%s\n", createResponse.ID)
-		}()
-	}
-	if *flAutoRemove && (hostConfig.RestartPolicy.IsAlways() || hostConfig.RestartPolicy.IsOnFailure()) {
-		return ErrConflictRestartPolicyAndAutoRemove
-	}
-	// We need to instantiate the chan because the select needs it. It can
-	// be closed but can't be uninitialized.
-	hijacked := make(chan io.Closer)
-	// Block the return until the chan gets closed
-	defer func() {
-		logrus.Debugf("End of CmdRun(), Waiting for hijack to finish.")
-		if _, ok := <-hijacked; ok {
-			fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
-		}
-	}()
-	if config.AttachStdin || config.AttachStdout || config.AttachStderr {
-		var (
-			out, stderr io.Writer
-			in          io.ReadCloser
-			v           = url.Values{}
-		)
-		v.Set("stream", "1")
-		if config.AttachStdin {
-			v.Set("stdin", "1")
-			in = cli.in
-		}
-		if config.AttachStdout {
-			v.Set("stdout", "1")
-			out = cli.out
-		}
-		if config.AttachStderr {
-			v.Set("stderr", "1")
-			if config.Tty {
-				stderr = cli.out
-			} else {
-				stderr = cli.err
-			}
-		}
-		errCh = promise.Go(func() error {
-			return cli.hijack("POST", "/containers/"+createResponse.ID+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil)
-		})
-	} else {
-		close(hijacked)
-	}
-	// Acknowledge the hijack before starting
-	select {
-	case closer := <-hijacked:
-		// Make sure that the hijack gets closed when returning (results
-		// in closing the hijack chan and freeing server's goroutines)
-		if closer != nil {
-			defer closer.Close()
-		}
-	case err := <-errCh:
-		if err != nil {
-			logrus.Debugf("Error hijack: %s", err)
-			return err
-		}
-	}
-
-	defer func() {
-		if *flAutoRemove {
-			if _, _, err = readBody(cli.call("DELETE", "/containers/"+createResponse.ID+"?v=1", nil, nil)); err != nil {
-				fmt.Fprintf(cli.err, "Error deleting container: %s\n", err)
-			}
-		}
-	}()
-
-	//start the container
-	if _, _, err = readBody(cli.call("POST", "/containers/"+createResponse.ID+"/start", nil, nil)); err != nil {
-		return err
-	}
-
-	if (config.AttachStdin || config.AttachStdout || config.AttachStderr) && config.Tty && cli.isTerminalOut {
-		if err := cli.monitorTtySize(createResponse.ID, false); err != nil {
-			fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
-		}
-	}
-
-	if errCh != nil {
-		if err := <-errCh; err != nil {
-			logrus.Debugf("Error hijack: %s", err)
-			return err
-		}
-	}
-
-	// Detached mode: wait for the id to be displayed and return.
-	if !config.AttachStdout && !config.AttachStderr {
-		// Detached mode
-		<-waitDisplayID
-		return nil
-	}
-
-	var status int
-
-	// Attached mode
-	if *flAutoRemove {
-		// Autoremove: wait for the container to finish, retrieve
-		// the exit code and remove the container
-		if _, _, err := readBody(cli.call("POST", "/containers/"+createResponse.ID+"/wait", nil, nil)); err != nil {
-			return err
-		}
-		if _, status, err = getExitCode(cli, createResponse.ID); err != nil {
-			return err
-		}
-	} else {
-		// No Autoremove: Simply retrieve the exit code
-		if !config.Tty {
-			// In non-TTY mode, we can't detach, so we must wait for container exit
-			if status, err = waitForExit(cli, createResponse.ID); err != nil {
-				return err
-			}
-		} else {
-			// In TTY mode, there is a race: if the process dies too slowly, the state could
-			// be updated after the getExitCode call and result in the wrong exit code being reported
-			if _, status, err = getExitCode(cli, createResponse.ID); err != nil {
-				return err
-			}
-		}
-	}
-	if status != 0 {
-		return StatusError{StatusCode: status}
-	}
-	return nil
-}

+ 0 - 57
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/save.go

@@ -1,57 +0,0 @@
-package client
-
-import (
-	"errors"
-	"io"
-	"net/url"
-	"os"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdSave saves one or more images to a tar archive.
-//
-// The tar archive is written to STDOUT by default, or written to a file.
-//
-// Usage: docker save [OPTIONS] IMAGE [IMAGE...]
-func (cli *DockerCli) CmdSave(args ...string) error {
-	cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)", true)
-	outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		output io.Writer = cli.out
-		err    error
-	)
-	if *outfile != "" {
-		output, err = os.Create(*outfile)
-		if err != nil {
-			return err
-		}
-	} else if cli.isTerminalOut {
-		return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.")
-	}
-
-	sopts := &streamOpts{
-		rawTerminal: true,
-		out:         output,
-	}
-
-	if len(cmd.Args()) == 1 {
-		image := cmd.Arg(0)
-		if err := cli.stream("GET", "/images/"+image+"/get", sopts); err != nil {
-			return err
-		}
-	} else {
-		v := url.Values{}
-		for _, arg := range cmd.Args() {
-			v.Add("names", arg)
-		}
-		if err := cli.stream("GET", "/images/get?"+v.Encode(), sopts); err != nil {
-			return err
-		}
-	}
-	return nil
-}

+ 0 - 84
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/search.go

@@ -1,84 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-	"sort"
-	"strings"
-	"text/tabwriter"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/registry"
-)
-
-// ByStars sorts search results in ascending order by number of stars.
-type ByStars []registry.SearchResult
-
-func (r ByStars) Len() int           { return len(r) }
-func (r ByStars) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
-func (r ByStars) Less(i, j int) bool { return r[i].StarCount < r[j].StarCount }
-
-// CmdSearch searches the Docker Hub for images.
-//
-// Usage: docker search [OPTIONS] TERM
-func (cli *DockerCli) CmdSearch(args ...string) error {
-	cmd := cli.Subcmd("search", "TERM", "Search the Docker Hub for images", true)
-	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
-	trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds")
-	automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds")
-	stars := cmd.Uint([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars")
-	cmd.Require(flag.Exact, 1)
-
-	cmd.ParseFlags(args, true)
-
-	name := cmd.Arg(0)
-	v := url.Values{}
-	v.Set("term", name)
-
-	// Resolve the Repository name from fqn to hostname + name
-	taglessRemote, _ := parsers.ParseRepositoryTag(name)
-	repoInfo, err := registry.ParseRepositoryInfo(taglessRemote)
-	if err != nil {
-		return err
-	}
-
-	rdr, _, err := cli.clientRequestAttemptLogin("GET", "/images/search?"+v.Encode(), nil, nil, repoInfo.Index, "search")
-	if err != nil {
-		return err
-	}
-
-	results := ByStars{}
-	if err := json.NewDecoder(rdr).Decode(&results); err != nil {
-		return err
-	}
-
-	sort.Sort(sort.Reverse(results))
-
-	w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0)
-	fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
-	for _, res := range results {
-		if ((*automated || *trusted) && (!res.IsTrusted && !res.IsAutomated)) || (int(*stars) > res.StarCount) {
-			continue
-		}
-		desc := strings.Replace(res.Description, "\n", " ", -1)
-		desc = strings.Replace(desc, "\r", " ", -1)
-		if !*noTrunc && len(desc) > 45 {
-			desc = stringutils.Truncate(desc, 42) + "..."
-		}
-		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
-		if res.IsOfficial {
-			fmt.Fprint(w, "[OK]")
-
-		}
-		fmt.Fprint(w, "\t")
-		if res.IsAutomated || res.IsTrusted {
-			fmt.Fprint(w, "[OK]")
-		}
-		fmt.Fprint(w, "\n")
-	}
-	w.Flush()
-	return nil
-}

+ 0 - 167
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/start.go

@@ -1,167 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"net/url"
-	"os"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/promise"
-	"github.com/docker/docker/pkg/signal"
-)
-
-func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
-	sigc := make(chan os.Signal, 128)
-	signal.CatchAll(sigc)
-	go func() {
-		for s := range sigc {
-			if s == signal.SIGCHLD {
-				continue
-			}
-			var sig string
-			for sigStr, sigN := range signal.SignalMap {
-				if sigN == s {
-					sig = sigStr
-					break
-				}
-			}
-			if sig == "" {
-				fmt.Fprintf(cli.err, "Unsupported signal: %v. Discarding.\n", s)
-			}
-			if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/kill?signal=%s", cid, sig), nil, nil)); err != nil {
-				logrus.Debugf("Error sending signal: %s", err)
-			}
-		}
-	}()
-	return sigc
-}
-
-// CmdStart starts one or more stopped containers.
-//
-// Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdStart(args ...string) error {
-	var (
-		cErr chan error
-		tty  bool
-
-		cmd       = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Start one or more stopped containers", true)
-		attach    = cmd.Bool([]string{"a", "-attach"}, false, "Attach STDOUT/STDERR and forward signals")
-		openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN")
-	)
-
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	if *attach || *openStdin {
-		if cmd.NArg() > 1 {
-			return fmt.Errorf("You cannot start and attach multiple containers at once.")
-		}
-
-		stream, _, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, nil)
-		if err != nil {
-			return err
-		}
-
-		var c types.ContainerJSON
-		if err := json.NewDecoder(stream).Decode(&c); err != nil {
-			return err
-		}
-
-		tty = c.Config.Tty
-
-		if !tty {
-			sigc := cli.forwardAllSignals(cmd.Arg(0))
-			defer signal.StopCatch(sigc)
-		}
-
-		var in io.ReadCloser
-
-		v := url.Values{}
-		v.Set("stream", "1")
-
-		if *openStdin && c.Config.OpenStdin {
-			v.Set("stdin", "1")
-			in = cli.in
-		}
-
-		v.Set("stdout", "1")
-		v.Set("stderr", "1")
-
-		hijacked := make(chan io.Closer)
-		// Block the return until the chan gets closed
-		defer func() {
-			logrus.Debugf("CmdStart() returned, defer waiting for hijack to finish.")
-			if _, ok := <-hijacked; ok {
-				fmt.Fprintln(cli.err, "Hijack did not finish (chan still open)")
-			}
-			cli.in.Close()
-		}()
-		cErr = promise.Go(func() error {
-			return cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), tty, in, cli.out, cli.err, hijacked, nil)
-		})
-
-		// Acknowledge the hijack before starting
-		select {
-		case closer := <-hijacked:
-			// Make sure that the hijack gets closed when returning (results
-			// in closing the hijack chan and freeing server's goroutines)
-			if closer != nil {
-				defer closer.Close()
-			}
-		case err := <-cErr:
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	var encounteredError error
-	var errNames []string
-	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil, nil))
-		if err != nil {
-			if !*attach && !*openStdin {
-				// attach and openStdin is false means it could be starting multiple containers
-				// when a container start failed, show the error message and start next
-				fmt.Fprintf(cli.err, "%s\n", err)
-				errNames = append(errNames, name)
-			} else {
-				encounteredError = err
-			}
-		} else {
-			if !*attach && !*openStdin {
-				fmt.Fprintf(cli.out, "%s\n", name)
-			}
-		}
-	}
-
-	if len(errNames) > 0 {
-		encounteredError = fmt.Errorf("Error: failed to start containers: %v", errNames)
-	}
-	if encounteredError != nil {
-		return encounteredError
-	}
-
-	if *openStdin || *attach {
-		if tty && cli.isTerminalOut {
-			if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil {
-				fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
-			}
-		}
-		if attchErr := <-cErr; attchErr != nil {
-			return attchErr
-		}
-		_, status, err := getExitCode(cli, cmd.Arg(0))
-		if err != nil {
-			return err
-		}
-		if status != 0 {
-			return StatusError{StatusCode: status}
-		}
-	}
-	return nil
-}

+ 0 - 198
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stats.go

@@ -1,198 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"net/url"
-	"sort"
-	"strings"
-	"sync"
-	"text/tabwriter"
-	"time"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/units"
-)
-
-type containerStats struct {
-	Name             string
-	CPUPercentage    float64
-	Memory           float64
-	MemoryLimit      float64
-	MemoryPercentage float64
-	NetworkRx        float64
-	NetworkTx        float64
-	mu               sync.RWMutex
-	err              error
-}
-
-func (s *containerStats) Collect(cli *DockerCli, streamStats bool) {
-	v := url.Values{}
-	if streamStats {
-		v.Set("stream", "1")
-	} else {
-		v.Set("stream", "0")
-	}
-	stream, _, _, err := cli.call("GET", "/containers/"+s.Name+"/stats?"+v.Encode(), nil, nil)
-	if err != nil {
-		s.mu.Lock()
-		s.err = err
-		s.mu.Unlock()
-		return
-	}
-	defer stream.Close()
-	var (
-		previousCPU    uint64
-		previousSystem uint64
-		dec            = json.NewDecoder(stream)
-		u              = make(chan error, 1)
-	)
-	go func() {
-		for {
-			var v *types.Stats
-			if err := dec.Decode(&v); err != nil {
-				u <- err
-				return
-			}
-			var (
-				memPercent = float64(v.MemoryStats.Usage) / float64(v.MemoryStats.Limit) * 100.0
-				cpuPercent = 0.0
-			)
-			previousCPU = v.PreCpuStats.CpuUsage.TotalUsage
-			previousSystem = v.PreCpuStats.SystemUsage
-			cpuPercent = calculateCPUPercent(previousCPU, previousSystem, v)
-			s.mu.Lock()
-			s.CPUPercentage = cpuPercent
-			s.Memory = float64(v.MemoryStats.Usage)
-			s.MemoryLimit = float64(v.MemoryStats.Limit)
-			s.MemoryPercentage = memPercent
-			s.NetworkRx = float64(v.Network.RxBytes)
-			s.NetworkTx = float64(v.Network.TxBytes)
-			s.mu.Unlock()
-			u <- nil
-			if !streamStats {
-				return
-			}
-		}
-	}()
-	for {
-		select {
-		case <-time.After(2 * time.Second):
-			// zero out the values if we have not received an update within
-			// the specified duration.
-			s.mu.Lock()
-			s.CPUPercentage = 0
-			s.Memory = 0
-			s.MemoryPercentage = 0
-			s.mu.Unlock()
-		case err := <-u:
-			if err != nil {
-				s.mu.Lock()
-				s.err = err
-				s.mu.Unlock()
-				return
-			}
-		}
-		if !streamStats {
-			return
-		}
-	}
-}
-
-func (s *containerStats) Display(w io.Writer) error {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	if s.err != nil {
-		return s.err
-	}
-	fmt.Fprintf(w, "%s\t%.2f%%\t%s/%s\t%.2f%%\t%s/%s\n",
-		s.Name,
-		s.CPUPercentage,
-		units.HumanSize(s.Memory), units.HumanSize(s.MemoryLimit),
-		s.MemoryPercentage,
-		units.HumanSize(s.NetworkRx), units.HumanSize(s.NetworkTx))
-	return nil
-}
-
-// CmdStats displays a live stream of resource usage statistics for one or more containers.
-//
-// This shows real-time information on CPU usage, memory usage, and network I/O.
-//
-// Usage: docker stats CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdStats(args ...string) error {
-	cmd := cli.Subcmd("stats", "CONTAINER [CONTAINER...]", "Display a live stream of one or more containers' resource usage statistics", true)
-	noStream := cmd.Bool([]string{"-no-stream"}, false, "Disable streaming stats and only pull the first result")
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	names := cmd.Args()
-	sort.Strings(names)
-	var (
-		cStats []*containerStats
-		w      = tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	)
-	printHeader := func() {
-		if !*noStream {
-			fmt.Fprint(cli.out, "\033[2J")
-			fmt.Fprint(cli.out, "\033[H")
-		}
-		io.WriteString(w, "CONTAINER\tCPU %\tMEM USAGE/LIMIT\tMEM %\tNET I/O\n")
-	}
-	for _, n := range names {
-		s := &containerStats{Name: n}
-		cStats = append(cStats, s)
-		go s.Collect(cli, !*noStream)
-	}
-	// do a quick pause so that any failed connections for containers that do not exist are able to be
-	// evicted before we display the initial or default values.
-	time.Sleep(1500 * time.Millisecond)
-	var errs []string
-	for _, c := range cStats {
-		c.mu.Lock()
-		if c.err != nil {
-			errs = append(errs, fmt.Sprintf("%s: %v", c.Name, c.err))
-		}
-		c.mu.Unlock()
-	}
-	if len(errs) > 0 {
-		return fmt.Errorf("%s", strings.Join(errs, ", "))
-	}
-	for range time.Tick(500 * time.Millisecond) {
-		printHeader()
-		toRemove := []int{}
-		for i, s := range cStats {
-			if err := s.Display(w); err != nil && !*noStream {
-				toRemove = append(toRemove, i)
-			}
-		}
-		for j := len(toRemove) - 1; j >= 0; j-- {
-			i := toRemove[j]
-			cStats = append(cStats[:i], cStats[i+1:]...)
-		}
-		if len(cStats) == 0 {
-			return nil
-		}
-		w.Flush()
-		if *noStream {
-			break
-		}
-	}
-	return nil
-}
-
-func calculateCPUPercent(previousCPU, previousSystem uint64, v *types.Stats) float64 {
-	var (
-		cpuPercent = 0.0
-		// calculate the change for the cpu usage of the container in between readings
-		cpuDelta = float64(v.CpuStats.CpuUsage.TotalUsage - previousCPU)
-		// calculate the change for the entire system between readings
-		systemDelta = float64(v.CpuStats.SystemUsage - previousSystem)
-	)
-
-	if systemDelta > 0.0 && cpuDelta > 0.0 {
-		cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CpuStats.CpuUsage.PercpuUsage)) * 100.0
-	}
-	return cpuPercent
-}

+ 0 - 29
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stats_unit_test.go

@@ -1,29 +0,0 @@
-package client
-
-import (
-	"bytes"
-	"sync"
-	"testing"
-)
-
-func TestDisplay(t *testing.T) {
-	c := &containerStats{
-		Name:             "app",
-		CPUPercentage:    30.0,
-		Memory:           100 * 1024 * 1024.0,
-		MemoryLimit:      2048 * 1024 * 1024.0,
-		MemoryPercentage: 100.0 / 2048.0 * 100.0,
-		NetworkRx:        100 * 1024 * 1024,
-		NetworkTx:        800 * 1024 * 1024,
-		mu:               sync.RWMutex{},
-	}
-	var b bytes.Buffer
-	if err := c.Display(&b); err != nil {
-		t.Fatalf("c.Display() gave error: %s", err)
-	}
-	got := b.String()
-	want := "app\t30.00%\t104.9 MB/2.147 GB\t4.88%\t104.9 MB/838.9 MB\n"
-	if got != want {
-		t.Fatalf("c.Display() = %q, want %q", got, want)
-	}
-}

+ 0 - 40
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/stop.go

@@ -1,40 +0,0 @@
-package client
-
-import (
-	"fmt"
-	"net/url"
-	"strconv"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdStop stops one or more running containers.
-//
-// A running container is stopped by first sending SIGTERM and then SIGKILL if the container fails to stop within a grace period (the default is 10 seconds).
-//
-// Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdStop(args ...string) error {
-	cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a\ngrace period", true)
-	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Seconds to wait for stop before killing it")
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	v := url.Values{}
-	v.Set("t", strconv.Itoa(*nSeconds))
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		_, _, err := readBody(cli.call("POST", "/containers/"+name+"/stop?"+v.Encode(), nil, nil))
-		if err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to stop containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 41
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/tag.go

@@ -1,41 +0,0 @@
-package client
-
-import (
-	"net/url"
-
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/pkg/parsers"
-	"github.com/docker/docker/registry"
-)
-
-// CmdTag tags an image into a repository.
-//
-// Usage: docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
-func (cli *DockerCli) CmdTag(args ...string) error {
-	cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository", true)
-	force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
-	cmd.Require(flag.Exact, 2)
-
-	cmd.ParseFlags(args, true)
-
-	var (
-		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
-		v               = url.Values{}
-	)
-
-	//Check if the given image name can be resolved
-	if err := registry.ValidateRepositoryName(repository); err != nil {
-		return err
-	}
-	v.Set("repo", repository)
-	v.Set("tag", tag)
-
-	if *force {
-		v.Set("force", "1")
-	}
-
-	if _, _, err := readBody(cli.call("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil, nil)); err != nil {
-		return err
-	}
-	return nil
-}

+ 0 - 46
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/top.go

@@ -1,46 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/url"
-	"strings"
-	"text/tabwriter"
-
-	"github.com/docker/docker/api/types"
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdTop displays the running processes of a container.
-//
-// Usage: docker top CONTAINER
-func (cli *DockerCli) CmdTop(args ...string) error {
-	cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container", true)
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	val := url.Values{}
-	if cmd.NArg() > 1 {
-		val.Set("ps_args", strings.Join(cmd.Args()[1:], " "))
-	}
-
-	stream, _, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/top?"+val.Encode(), nil, nil)
-	if err != nil {
-		return err
-	}
-
-	procList := types.ContainerProcessList{}
-	if err := json.NewDecoder(stream).Decode(&procList); err != nil {
-		return err
-	}
-
-	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
-	fmt.Fprintln(w, strings.Join(procList.Titles, "\t"))
-
-	for _, proc := range procList.Processes {
-		fmt.Fprintln(w, strings.Join(proc, "\t"))
-	}
-	w.Flush()
-	return nil
-}

+ 0 - 30
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/unpause.go

@@ -1,30 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdUnpause unpauses all processes within a container, for one or more containers.
-//
-// Usage: docker unpause CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdUnpause(args ...string) error {
-	cmd := cli.Subcmd("unpause", "CONTAINER [CONTAINER...]", "Unpause all processes within a container", true)
-	cmd.Require(flag.Min, 1)
-	cmd.ParseFlags(args, true)
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		if _, _, err := readBody(cli.call("POST", fmt.Sprintf("/containers/%s/unpause", name), nil, nil)); err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%s\n", name)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to unpause containers: %v", errNames)
-	}
-	return nil
-}

+ 0 - 345
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/utils.go

@@ -1,345 +0,0 @@
-package client
-
-import (
-	"bytes"
-	"encoding/base64"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"os"
-	gosignal "os/signal"
-	"runtime"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/autogen/dockerversion"
-	"github.com/docker/docker/cliconfig"
-	"github.com/docker/docker/pkg/jsonmessage"
-	"github.com/docker/docker/pkg/signal"
-	"github.com/docker/docker/pkg/stdcopy"
-	"github.com/docker/docker/pkg/term"
-	"github.com/docker/docker/registry"
-)
-
-var (
-	errConnectionRefused = errors.New("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?")
-)
-
-// HTTPClient creates a new HTTP client with the cli's client transport instance.
-func (cli *DockerCli) HTTPClient() *http.Client {
-	return &http.Client{Transport: cli.transport}
-}
-
-func (cli *DockerCli) encodeData(data interface{}) (*bytes.Buffer, error) {
-	params := bytes.NewBuffer(nil)
-	if data != nil {
-		if err := json.NewEncoder(params).Encode(data); err != nil {
-			return nil, err
-		}
-	}
-	return params, nil
-}
-
-func (cli *DockerCli) clientRequest(method, path string, in io.Reader, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
-	expectedPayload := (method == "POST" || method == "PUT")
-	if expectedPayload && in == nil {
-		in = bytes.NewReader([]byte{})
-	}
-	req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), in)
-	if err != nil {
-		return nil, nil, -1, err
-	}
-
-	// Add CLI Config's HTTP Headers BEFORE we set the Docker headers
-	// then the user can't change OUR headers
-	for k, v := range cli.configFile.HttpHeaders {
-		req.Header.Set(k, v)
-	}
-
-	req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION+" ("+runtime.GOOS+")")
-	req.URL.Host = cli.addr
-	req.URL.Scheme = cli.scheme
-
-	if headers != nil {
-		for k, v := range headers {
-			req.Header[k] = v
-		}
-	}
-
-	if expectedPayload && req.Header.Get("Content-Type") == "" {
-		req.Header.Set("Content-Type", "text/plain")
-	}
-
-	resp, err := cli.HTTPClient().Do(req)
-	statusCode := -1
-	if resp != nil {
-		statusCode = resp.StatusCode
-	}
-	if err != nil {
-		if strings.Contains(err.Error(), "connection refused") {
-			return nil, nil, statusCode, errConnectionRefused
-		}
-
-		if cli.tlsConfig == nil {
-			return nil, nil, statusCode, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
-		}
-		return nil, nil, statusCode, fmt.Errorf("An error occurred trying to connect: %v", err)
-	}
-
-	if statusCode < 200 || statusCode >= 400 {
-		body, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			return nil, nil, statusCode, err
-		}
-		if len(body) == 0 {
-			return nil, nil, statusCode, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(statusCode), req.URL)
-		}
-		return nil, nil, statusCode, fmt.Errorf("Error response from daemon: %s", bytes.TrimSpace(body))
-	}
-
-	return resp.Body, resp.Header, statusCode, nil
-}
-
-func (cli *DockerCli) clientRequestAttemptLogin(method, path string, in io.Reader, out io.Writer, index *registry.IndexInfo, cmdName string) (io.ReadCloser, int, error) {
-	cmdAttempt := func(authConfig cliconfig.AuthConfig) (io.ReadCloser, int, error) {
-		buf, err := json.Marshal(authConfig)
-		if err != nil {
-			return nil, -1, err
-		}
-		registryAuthHeader := []string{
-			base64.URLEncoding.EncodeToString(buf),
-		}
-
-		// begin the request
-		body, hdr, statusCode, err := cli.clientRequest(method, path, in, map[string][]string{
-			"X-Registry-Auth": registryAuthHeader,
-		})
-		if err == nil && out != nil {
-			// If we are streaming output, complete the stream since
-			// errors may not appear until later.
-			err = cli.streamBody(body, hdr.Get("Content-Type"), true, out, nil)
-		}
-		if err != nil {
-			// Since errors in a stream appear after status 200 has been written,
-			// we may need to change the status code.
-			if strings.Contains(err.Error(), "Authentication is required") ||
-				strings.Contains(err.Error(), "Status 401") ||
-				strings.Contains(err.Error(), "status code 401") {
-				statusCode = http.StatusUnauthorized
-			}
-		}
-		return body, statusCode, err
-	}
-
-	// Resolve the Auth config relevant for this server
-	authConfig := registry.ResolveAuthConfig(cli.configFile, index)
-	body, statusCode, err := cmdAttempt(authConfig)
-	if statusCode == http.StatusUnauthorized {
-		fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
-		if err = cli.CmdLogin(index.GetAuthConfigKey()); err != nil {
-			return nil, -1, err
-		}
-		authConfig = registry.ResolveAuthConfig(cli.configFile, index)
-		return cmdAttempt(authConfig)
-	}
-	return body, statusCode, err
-}
-
-func (cli *DockerCli) call(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
-	params, err := cli.encodeData(data)
-	if err != nil {
-		return nil, nil, -1, err
-	}
-
-	if data != nil {
-		if headers == nil {
-			headers = make(map[string][]string)
-		}
-		headers["Content-Type"] = []string{"application/json"}
-	}
-
-	body, hdr, statusCode, err := cli.clientRequest(method, path, params, headers)
-	return body, hdr, statusCode, err
-}
-
-type streamOpts struct {
-	rawTerminal bool
-	in          io.Reader
-	out         io.Writer
-	err         io.Writer
-	headers     map[string][]string
-}
-
-func (cli *DockerCli) stream(method, path string, opts *streamOpts) error {
-	body, hdr, _, err := cli.clientRequest(method, path, opts.in, opts.headers)
-	if err != nil {
-		return err
-	}
-	return cli.streamBody(body, hdr.Get("Content-Type"), opts.rawTerminal, opts.out, opts.err)
-}
-
-func (cli *DockerCli) streamBody(body io.ReadCloser, contentType string, rawTerminal bool, stdout, stderr io.Writer) error {
-	defer body.Close()
-
-	if api.MatchesContentType(contentType, "application/json") {
-		return jsonmessage.DisplayJSONMessagesStream(body, stdout, cli.outFd, cli.isTerminalOut)
-	}
-	if stdout != nil || stderr != nil {
-		// When TTY is ON, use regular copy
-		var err error
-		if rawTerminal {
-			_, err = io.Copy(stdout, body)
-		} else {
-			_, err = stdcopy.StdCopy(stdout, stderr, body)
-		}
-		logrus.Debugf("[stream] End of stdout")
-		return err
-	}
-	return nil
-}
-
-func (cli *DockerCli) resizeTty(id string, isExec bool) {
-	height, width := cli.getTtySize()
-	if height == 0 && width == 0 {
-		return
-	}
-	v := url.Values{}
-	v.Set("h", strconv.Itoa(height))
-	v.Set("w", strconv.Itoa(width))
-
-	path := ""
-	if !isExec {
-		path = "/containers/" + id + "/resize?"
-	} else {
-		path = "/exec/" + id + "/resize?"
-	}
-
-	if _, _, err := readBody(cli.call("POST", path+v.Encode(), nil, nil)); err != nil {
-		logrus.Debugf("Error resize: %s", err)
-	}
-}
-
-func waitForExit(cli *DockerCli, containerID string) (int, error) {
-	stream, _, _, err := cli.call("POST", "/containers/"+containerID+"/wait", nil, nil)
-	if err != nil {
-		return -1, err
-	}
-
-	var res types.ContainerWaitResponse
-	if err := json.NewDecoder(stream).Decode(&res); err != nil {
-		return -1, err
-	}
-
-	return res.StatusCode, nil
-}
-
-// getExitCode perform an inspect on the container. It returns
-// the running state and the exit code.
-func getExitCode(cli *DockerCli, containerID string) (bool, int, error) {
-	stream, _, _, err := cli.call("GET", "/containers/"+containerID+"/json", nil, nil)
-	if err != nil {
-		// If we can't connect, then the daemon probably died.
-		if err != errConnectionRefused {
-			return false, -1, err
-		}
-		return false, -1, nil
-	}
-
-	var c types.ContainerJSON
-	if err := json.NewDecoder(stream).Decode(&c); err != nil {
-		return false, -1, err
-	}
-
-	return c.State.Running, c.State.ExitCode, nil
-}
-
-// getExecExitCode perform an inspect on the exec command. It returns
-// the running state and the exit code.
-func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) {
-	stream, _, _, err := cli.call("GET", "/exec/"+execID+"/json", nil, nil)
-	if err != nil {
-		// If we can't connect, then the daemon probably died.
-		if err != errConnectionRefused {
-			return false, -1, err
-		}
-		return false, -1, nil
-	}
-
-	//TODO: Should we reconsider having a type in api/types?
-	//this is a response to exex/id/json not container
-	var c struct {
-		Running  bool
-		ExitCode int
-	}
-
-	if err := json.NewDecoder(stream).Decode(&c); err != nil {
-		return false, -1, err
-	}
-
-	return c.Running, c.ExitCode, nil
-}
-
-func (cli *DockerCli) monitorTtySize(id string, isExec bool) error {
-	cli.resizeTty(id, isExec)
-
-	if runtime.GOOS == "windows" {
-		go func() {
-			prevH, prevW := cli.getTtySize()
-			for {
-				time.Sleep(time.Millisecond * 250)
-				h, w := cli.getTtySize()
-
-				if prevW != w || prevH != h {
-					cli.resizeTty(id, isExec)
-				}
-				prevH = h
-				prevW = w
-			}
-		}()
-	} else {
-		sigchan := make(chan os.Signal, 1)
-		gosignal.Notify(sigchan, signal.SIGWINCH)
-		go func() {
-			for range sigchan {
-				cli.resizeTty(id, isExec)
-			}
-		}()
-	}
-	return nil
-}
-
-func (cli *DockerCli) getTtySize() (int, int) {
-	if !cli.isTerminalOut {
-		return 0, 0
-	}
-	ws, err := term.GetWinsize(cli.outFd)
-	if err != nil {
-		logrus.Debugf("Error getting size: %s", err)
-		if ws == nil {
-			return 0, 0
-		}
-	}
-	return int(ws.Height), int(ws.Width)
-}
-
-func readBody(stream io.ReadCloser, hdr http.Header, statusCode int, err error) ([]byte, int, error) {
-	if stream != nil {
-		defer stream.Close()
-	}
-	if err != nil {
-		return nil, statusCode, err
-	}
-	body, err := ioutil.ReadAll(stream)
-	if err != nil {
-		return nil, -1, err
-	}
-	return body, statusCode, nil
-}

+ 0 - 61
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/version.go

@@ -1,61 +0,0 @@
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"runtime"
-
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/autogen/dockerversion"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/utils"
-)
-
-// CmdVersion shows Docker version information.
-//
-// Available version information is shown for: client Docker version, client API version, client Go version, client Git commit, client OS/Arch, server Docker version, server API version, server Go version, server Git commit, and server OS/Arch.
-//
-// Usage: docker version
-func (cli *DockerCli) CmdVersion(args ...string) error {
-	cmd := cli.Subcmd("version", "", "Show the Docker version information.", true)
-	cmd.Require(flag.Exact, 0)
-
-	cmd.ParseFlags(args, true)
-
-	if dockerversion.VERSION != "" {
-		fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION)
-	}
-	fmt.Fprintf(cli.out, "Client API version: %s\n", api.APIVERSION)
-	fmt.Fprintf(cli.out, "Go version (client): %s\n", runtime.Version())
-	if dockerversion.GITCOMMIT != "" {
-		fmt.Fprintf(cli.out, "Git commit (client): %s\n", dockerversion.GITCOMMIT)
-	}
-	fmt.Fprintf(cli.out, "OS/Arch (client): %s/%s\n", runtime.GOOS, runtime.GOARCH)
-	if utils.ExperimentalBuild() {
-		fmt.Fprintf(cli.out, "Experimental (client): true\n")
-	}
-
-	stream, _, _, err := cli.call("GET", "/version", nil, nil)
-	if err != nil {
-		return err
-	}
-
-	var v types.Version
-	if err := json.NewDecoder(stream).Decode(&v); err != nil {
-		fmt.Fprintf(cli.err, "Error reading remote version: %s\n", err)
-		return err
-	}
-
-	fmt.Fprintf(cli.out, "Server version: %s\n", v.Version)
-	if v.ApiVersion != "" {
-		fmt.Fprintf(cli.out, "Server API version: %s\n", v.ApiVersion)
-	}
-	fmt.Fprintf(cli.out, "Go version (server): %s\n", v.GoVersion)
-	fmt.Fprintf(cli.out, "Git commit (server): %s\n", v.GitCommit)
-	fmt.Fprintf(cli.out, "OS/Arch (server): %s/%s\n", v.Os, v.Arch)
-	if v.Experimental {
-		fmt.Fprintf(cli.out, "Experimental (server): true\n")
-	}
-	return nil
-}

+ 0 - 34
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/client/wait.go

@@ -1,34 +0,0 @@
-package client
-
-import (
-	"fmt"
-
-	flag "github.com/docker/docker/pkg/mflag"
-)
-
-// CmdWait blocks until a container stops, then prints its exit code.
-//
-// If more than one container is specified, this will wait synchronously on each container.
-//
-// Usage: docker wait CONTAINER [CONTAINER...]
-func (cli *DockerCli) CmdWait(args ...string) error {
-	cmd := cli.Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.", true)
-	cmd.Require(flag.Min, 1)
-
-	cmd.ParseFlags(args, true)
-
-	var errNames []string
-	for _, name := range cmd.Args() {
-		status, err := waitForExit(cli, name)
-		if err != nil {
-			fmt.Fprintf(cli.err, "%s\n", err)
-			errNames = append(errNames, name)
-		} else {
-			fmt.Fprintf(cli.out, "%d\n", status)
-		}
-	}
-	if len(errNames) > 0 {
-		return fmt.Errorf("Error: failed to wait containers: %v", errNames)
-	}
-	return nil
-}

+ 23 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/blkiodev/blkio.go

@@ -0,0 +1,23 @@
+package blkiodev
+
+import "fmt"
+
+// WeightDevice is a structure that hold device:weight pair
+type WeightDevice struct {
+	Path   string
+	Weight uint16
+}
+
+func (w *WeightDevice) String() string {
+	return fmt.Sprintf("%s:%d", w.Path, w.Weight)
+}
+
+// ThrottleDevice is a structure that hold device:rate_per_second pair
+type ThrottleDevice struct {
+	Path string
+	Rate uint64
+}
+
+func (t *ThrottleDevice) String() string {
+	return fmt.Sprintf("%s:%d", t.Path, t.Rate)
+}

+ 67 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/envfile.go

@@ -0,0 +1,67 @@
+package opts
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+	"strings"
+)
+
+// ParseEnvFile reads a file with environment variables enumerated by lines
+//
+// ``Environment variable names used by the utilities in the Shell and
+// Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase
+// letters, digits, and the '_' (underscore) from the characters defined in
+// Portable Character Set and do not begin with a digit. *But*, other
+// characters may be permitted by an implementation; applications shall
+// tolerate the presence of such names.''
+// -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
+//
+// As of #16585, it's up to application inside docker to validate or not
+// environment variables, that's why we just strip leading whitespace and
+// nothing more.
+func ParseEnvFile(filename string) ([]string, error) {
+	fh, err := os.Open(filename)
+	if err != nil {
+		return []string{}, err
+	}
+	defer fh.Close()
+
+	lines := []string{}
+	scanner := bufio.NewScanner(fh)
+	for scanner.Scan() {
+		// trim the line from all leading whitespace first
+		line := strings.TrimLeft(scanner.Text(), whiteSpaces)
+		// line is not empty, and not starting with '#'
+		if len(line) > 0 && !strings.HasPrefix(line, "#") {
+			data := strings.SplitN(line, "=", 2)
+
+			// trim the front of a variable, but nothing else
+			variable := strings.TrimLeft(data[0], whiteSpaces)
+			if strings.ContainsAny(variable, whiteSpaces) {
+				return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)}
+			}
+
+			if len(data) > 1 {
+
+				// pass the value through, no trimming
+				lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1]))
+			} else {
+				// if only a pass-through variable is given, clean it up.
+				lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line)))
+			}
+		}
+	}
+	return lines, scanner.Err()
+}
+
+var whiteSpaces = " \t"
+
+// ErrBadEnvVariable typed error for bad environment variable
+type ErrBadEnvVariable struct {
+	msg string
+}
+
+func (e ErrBadEnvVariable) Error() string {
+	return fmt.Sprintf("poorly formatted environment: %s", e.msg)
+}

+ 142 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/envfile_test.go

@@ -0,0 +1,142 @@
+package opts
+
+import (
+	"bufio"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func tmpFileWithContent(content string, t *testing.T) string {
+	tmpFile, err := ioutil.TempFile("", "envfile-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer tmpFile.Close()
+
+	tmpFile.WriteString(content)
+	return tmpFile.Name()
+}
+
+// Test ParseEnvFile for a file with a few well formatted lines
+func TestParseEnvFileGoodFile(t *testing.T) {
+	content := `foo=bar
+    baz=quux
+# comment
+
+_foobar=foobaz
+with.dots=working
+and_underscore=working too
+`
+	// Adding a newline + a line with pure whitespace.
+	// This is being done like this instead of the block above
+	// because it's common for editors to trim trailing whitespace
+	// from lines, which becomes annoying since that's the
+	// exact thing we need to test.
+	content += "\n    \t  "
+	tmpFile := tmpFileWithContent(content, t)
+	defer os.Remove(tmpFile)
+
+	lines, err := ParseEnvFile(tmpFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expectedLines := []string{
+		"foo=bar",
+		"baz=quux",
+		"_foobar=foobaz",
+		"with.dots=working",
+		"and_underscore=working too",
+	}
+
+	if !reflect.DeepEqual(lines, expectedLines) {
+		t.Fatal("lines not equal to expected_lines")
+	}
+}
+
+// Test ParseEnvFile for an empty file
+func TestParseEnvFileEmptyFile(t *testing.T) {
+	tmpFile := tmpFileWithContent("", t)
+	defer os.Remove(tmpFile)
+
+	lines, err := ParseEnvFile(tmpFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(lines) != 0 {
+		t.Fatal("lines not empty; expected empty")
+	}
+}
+
+// Test ParseEnvFile for a non existent file
+func TestParseEnvFileNonExistentFile(t *testing.T) {
+	_, err := ParseEnvFile("foo_bar_baz")
+	if err == nil {
+		t.Fatal("ParseEnvFile succeeded; expected failure")
+	}
+	if _, ok := err.(*os.PathError); !ok {
+		t.Fatalf("Expected a PathError, got [%v]", err)
+	}
+}
+
+// Test ParseEnvFile for a badly formatted file
+func TestParseEnvFileBadlyFormattedFile(t *testing.T) {
+	content := `foo=bar
+    f   =quux
+`
+
+	tmpFile := tmpFileWithContent(content, t)
+	defer os.Remove(tmpFile)
+
+	_, err := ParseEnvFile(tmpFile)
+	if err == nil {
+		t.Fatalf("Expected a ErrBadEnvVariable, got nothing")
+	}
+	if _, ok := err.(ErrBadEnvVariable); !ok {
+		t.Fatalf("Expected a ErrBadEnvVariable, got [%v]", err)
+	}
+	expectedMessage := "poorly formatted environment: variable 'f   ' has white spaces"
+	if err.Error() != expectedMessage {
+		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
+	}
+}
+
+// Test ParseEnvFile for a file with a line exceeding bufio.MaxScanTokenSize
+func TestParseEnvFileLineTooLongFile(t *testing.T) {
+	content := strings.Repeat("a", bufio.MaxScanTokenSize+42)
+	content = fmt.Sprint("foo=", content)
+
+	tmpFile := tmpFileWithContent(content, t)
+	defer os.Remove(tmpFile)
+
+	_, err := ParseEnvFile(tmpFile)
+	if err == nil {
+		t.Fatal("ParseEnvFile succeeded; expected failure")
+	}
+}
+
+// ParseEnvFile with a random file, pass through
+func TestParseEnvFileRandomFile(t *testing.T) {
+	content := `first line
+another invalid line`
+	tmpFile := tmpFileWithContent(content, t)
+	defer os.Remove(tmpFile)
+
+	_, err := ParseEnvFile(tmpFile)
+
+	if err == nil {
+		t.Fatalf("Expected a ErrBadEnvVariable, got nothing")
+	}
+	if _, ok := err.(ErrBadEnvVariable); !ok {
+		t.Fatalf("Expected a ErrBadEnvvariable, got [%v]", err)
+	}
+	expectedMessage := "poorly formatted environment: variable 'first line' has white spaces"
+	if err.Error() != expectedMessage {
+		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
+	}
+}

+ 146 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts.go

@@ -0,0 +1,146 @@
+package opts
+
+import (
+	"fmt"
+	"net"
+	"net/url"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+var (
+	// DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. docker daemon -H tcp://
+	// TODO Windows. DefaultHTTPPort is only used on Windows if a -H parameter
+	// is not supplied. A better longer term solution would be to use a named
+	// pipe as the default on the Windows daemon.
+	// These are the IANA registered port numbers for use with Docker
+	// see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker
+	DefaultHTTPPort = 2375 // Default HTTP Port
+	// DefaultTLSHTTPPort Default HTTP Port used when TLS enabled
+	DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port
+	// DefaultUnixSocket Path for the unix socket.
+	// Docker daemon by default always listens on the default unix socket
+	DefaultUnixSocket = "/var/run/docker.sock"
+	// DefaultTCPHost constant defines the default host string used by docker on Windows
+	DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
+	// DefaultTLSHost constant defines the default host string used by docker for TLS sockets
+	DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort)
+)
+
+// ValidateHost validates that the specified string is a valid host and returns it.
+func ValidateHost(val string) (string, error) {
+	_, err := parseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, "", val)
+	if err != nil {
+		return val, err
+	}
+	// Note: unlike most flag validators, we don't return the mutated value here
+	//       we need to know what the user entered later (using ParseHost) to adjust for tls
+	return val, nil
+}
+
+// ParseHost and set defaults for a Daemon host string
+func ParseHost(defaultHost, val string) (string, error) {
+	host, err := parseDockerDaemonHost(DefaultTCPHost, DefaultTLSHost, DefaultUnixSocket, defaultHost, val)
+	if err != nil {
+		return val, err
+	}
+	return host, nil
+}
+
+// parseDockerDaemonHost parses the specified address and returns an address that will be used as the host.
+// Depending of the address specified, will use the defaultTCPAddr or defaultUnixAddr
+// defaultUnixAddr must be a absolute file path (no `unix://` prefix)
+// defaultTCPAddr must be the full `tcp://host:port` form
+func parseDockerDaemonHost(defaultTCPAddr, defaultTLSHost, defaultUnixAddr, defaultAddr, addr string) (string, error) {
+	addr = strings.TrimSpace(addr)
+	if addr == "" {
+		if defaultAddr == defaultTLSHost {
+			return defaultTLSHost, nil
+		}
+		if runtime.GOOS != "windows" {
+			return fmt.Sprintf("unix://%s", defaultUnixAddr), nil
+		}
+		return defaultTCPAddr, nil
+	}
+	addrParts := strings.Split(addr, "://")
+	if len(addrParts) == 1 {
+		addrParts = []string{"tcp", addrParts[0]}
+	}
+
+	switch addrParts[0] {
+	case "tcp":
+		return parseTCPAddr(addrParts[1], defaultTCPAddr)
+	case "unix":
+		return parseUnixAddr(addrParts[1], defaultUnixAddr)
+	case "fd":
+		return addr, nil
+	default:
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
+	}
+}
+
+// parseUnixAddr parses and validates that the specified address is a valid UNIX
+// socket address. It returns a formatted UNIX socket address, either using the
+// address parsed from addr, or the contents of defaultAddr if addr is a blank
+// string.
+func parseUnixAddr(addr string, defaultAddr string) (string, error) {
+	addr = strings.TrimPrefix(addr, "unix://")
+	if strings.Contains(addr, "://") {
+		return "", fmt.Errorf("Invalid proto, expected unix: %s", addr)
+	}
+	if addr == "" {
+		addr = defaultAddr
+	}
+	return fmt.Sprintf("unix://%s", addr), nil
+}
+
+// parseTCPAddr parses and validates that the specified address is a valid TCP
+// address. It returns a formatted TCP address, either using the address parsed
+// from tryAddr, or the contents of defaultAddr if tryAddr is a blank string.
+// tryAddr is expected to have already been Trim()'d
+// defaultAddr must be in the full `tcp://host:port` form
+func parseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
+	if tryAddr == "" || tryAddr == "tcp://" {
+		return defaultAddr, nil
+	}
+	addr := strings.TrimPrefix(tryAddr, "tcp://")
+	if strings.Contains(addr, "://") || addr == "" {
+		return "", fmt.Errorf("Invalid proto, expected tcp: %s", tryAddr)
+	}
+
+	defaultAddr = strings.TrimPrefix(defaultAddr, "tcp://")
+	defaultHost, defaultPort, err := net.SplitHostPort(defaultAddr)
+	if err != nil {
+		return "", err
+	}
+	// url.Parse fails for trailing colon on IPv6 brackets on Go 1.5, but
+	// not 1.4. See https://github.com/golang/go/issues/12200 and
+	// https://github.com/golang/go/issues/6530.
+	if strings.HasSuffix(addr, "]:") {
+		addr += defaultPort
+	}
+
+	u, err := url.Parse("tcp://" + addr)
+	if err != nil {
+		return "", err
+	}
+
+	host, port, err := net.SplitHostPort(u.Host)
+	if err != nil {
+		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
+	}
+
+	if host == "" {
+		host = defaultHost
+	}
+	if port == "" {
+		port = defaultPort
+	}
+	p, err := strconv.Atoi(port)
+	if err != nil && p == 0 {
+		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
+	}
+
+	return fmt.Sprintf("tcp://%s%s", net.JoinHostPort(host, port), u.Path), nil
+}

+ 164 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_test.go

@@ -0,0 +1,164 @@
+package opts
+
+import (
+	"runtime"
+	"testing"
+)
+
+func TestParseHost(t *testing.T) {
+	invalid := map[string]string{
+		"anything":              "Invalid bind address format: anything",
+		"something with spaces": "Invalid bind address format: something with spaces",
+		"://":                "Invalid bind address format: ://",
+		"unknown://":         "Invalid bind address format: unknown://",
+		"tcp://:port":        "Invalid bind address format: :port",
+		"tcp://invalid":      "Invalid bind address format: invalid",
+		"tcp://invalid:port": "Invalid bind address format: invalid:port",
+	}
+	const defaultHTTPHost = "tcp://127.0.0.1:2375"
+	var defaultHOST = "unix:///var/run/docker.sock"
+
+	if runtime.GOOS == "windows" {
+		defaultHOST = defaultHTTPHost
+	}
+	valid := map[string]string{
+		"":                         defaultHOST,
+		"fd://":                    "fd://",
+		"fd://something":           "fd://something",
+		"tcp://host:":              "tcp://host:2375",
+		"tcp://":                   "tcp://localhost:2375",
+		"tcp://:2375":              "tcp://localhost:2375", // default ip address
+		"tcp://:2376":              "tcp://localhost:2376", // default ip address
+		"tcp://0.0.0.0:8080":       "tcp://0.0.0.0:8080",
+		"tcp://192.168.0.0:12000":  "tcp://192.168.0.0:12000",
+		"tcp://192.168:8080":       "tcp://192.168:8080",
+		"tcp://0.0.0.0:1234567890": "tcp://0.0.0.0:1234567890", // yeah it's valid :P
+		"tcp://docker.com:2375":    "tcp://docker.com:2375",
+		"unix://":                  "unix:///var/run/docker.sock", // default unix:// value
+		"unix://path/to/socket":    "unix://path/to/socket",
+	}
+
+	for value, errorMessage := range invalid {
+		if _, err := ParseHost(defaultHTTPHost, value); err == nil || err.Error() != errorMessage {
+			t.Fatalf("Expected an error for %v with [%v], got [%v]", value, errorMessage, err)
+		}
+	}
+	for value, expected := range valid {
+		if actual, err := ParseHost(defaultHTTPHost, value); err != nil || actual != expected {
+			t.Fatalf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err)
+		}
+	}
+}
+
+func TestParseDockerDaemonHost(t *testing.T) {
+	var (
+		defaultHTTPHost  = "tcp://localhost:2375"
+		defaultHTTPSHost = "tcp://localhost:2376"
+		defaultUnix      = "/var/run/docker.sock"
+		defaultHOST      = "unix:///var/run/docker.sock"
+	)
+	if runtime.GOOS == "windows" {
+		defaultHOST = defaultHTTPHost
+	}
+	invalids := map[string]string{
+		"0.0.0.0":                       "Invalid bind address format: 0.0.0.0",
+		"tcp:a.b.c.d":                   "Invalid bind address format: tcp:a.b.c.d",
+		"tcp:a.b.c.d/path":              "Invalid bind address format: tcp:a.b.c.d/path",
+		"udp://127.0.0.1":               "Invalid bind address format: udp://127.0.0.1",
+		"udp://127.0.0.1:2375":          "Invalid bind address format: udp://127.0.0.1:2375",
+		"tcp://unix:///run/docker.sock": "Invalid bind address format: unix",
+		"tcp":  "Invalid bind address format: tcp",
+		"unix": "Invalid bind address format: unix",
+		"fd":   "Invalid bind address format: fd",
+	}
+	valids := map[string]string{
+		"0.0.0.1:":                    "tcp://0.0.0.1:2375",
+		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
+		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
+		"[::1]:":                      "tcp://[::1]:2375",
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2375",
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
+		":6666":                   "tcp://localhost:6666",
+		":6666/path":              "tcp://localhost:6666/path",
+		"":                        defaultHOST,
+		" ":                       defaultHOST,
+		"  ":                      defaultHOST,
+		"tcp://":                  defaultHTTPHost,
+		"tcp://:7777":             "tcp://localhost:7777",
+		"tcp://:7777/path":        "tcp://localhost:7777/path",
+		" tcp://:7777/path ":      "tcp://localhost:7777/path",
+		"unix:///run/docker.sock": "unix:///run/docker.sock",
+		"unix://":                 "unix:///var/run/docker.sock",
+		"fd://":                   "fd://",
+		"fd://something":          "fd://something",
+		"localhost:":              "tcp://localhost:2375",
+		"localhost:5555":          "tcp://localhost:5555",
+		"localhost:5555/path":     "tcp://localhost:5555/path",
+	}
+	for invalidAddr, expectedError := range invalids {
+		if addr, err := parseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", invalidAddr); err == nil || err.Error() != expectedError {
+			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
+		}
+	}
+	for validAddr, expectedAddr := range valids {
+		if addr, err := parseDockerDaemonHost(defaultHTTPHost, defaultHTTPSHost, defaultUnix, "", validAddr); err != nil || addr != expectedAddr {
+			t.Errorf("%v -> expected %v, got (%v) addr (%v)", validAddr, expectedAddr, err, addr)
+		}
+	}
+}
+
+func TestParseTCP(t *testing.T) {
+	var (
+		defaultHTTPHost = "tcp://127.0.0.1:2376"
+	)
+	invalids := map[string]string{
+		"0.0.0.0":              "Invalid bind address format: 0.0.0.0",
+		"tcp:a.b.c.d":          "Invalid bind address format: tcp:a.b.c.d",
+		"tcp:a.b.c.d/path":     "Invalid bind address format: tcp:a.b.c.d/path",
+		"udp://127.0.0.1":      "Invalid proto, expected tcp: udp://127.0.0.1",
+		"udp://127.0.0.1:2375": "Invalid proto, expected tcp: udp://127.0.0.1:2375",
+	}
+	valids := map[string]string{
+		"":                            defaultHTTPHost,
+		"tcp://":                      defaultHTTPHost,
+		"0.0.0.1:":                    "tcp://0.0.0.1:2376",
+		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
+		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
+		":6666":                       "tcp://127.0.0.1:6666",
+		":6666/path":                  "tcp://127.0.0.1:6666/path",
+		"tcp://:7777":                 "tcp://127.0.0.1:7777",
+		"tcp://:7777/path":            "tcp://127.0.0.1:7777/path",
+		"[::1]:":                      "tcp://[::1]:2376",
+		"[::1]:5555":                  "tcp://[::1]:5555",
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2376",
+		"[0:0:0:0:0:0:0:1]:5555":      "tcp://[0:0:0:0:0:0:0:1]:5555",
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
+		"localhost:":                  "tcp://localhost:2376",
+		"localhost:5555":              "tcp://localhost:5555",
+		"localhost:5555/path":         "tcp://localhost:5555/path",
+	}
+	for invalidAddr, expectedError := range invalids {
+		if addr, err := parseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError {
+			t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
+		}
+	}
+	for validAddr, expectedAddr := range valids {
+		if addr, err := parseTCPAddr(validAddr, defaultHTTPHost); err != nil || addr != expectedAddr {
+			t.Errorf("%v -> expected %v, got %v and addr %v", validAddr, expectedAddr, err, addr)
+		}
+	}
+}
+
+func TestParseInvalidUnixAddrInvalid(t *testing.T) {
+	if _, err := parseUnixAddr("tcp://127.0.0.1", "unix:///var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
+		t.Fatalf("Expected an error, got %v", err)
+	}
+	if _, err := parseUnixAddr("unix://tcp://127.0.0.1", "/var/run/docker.sock"); err == nil || err.Error() != "Invalid proto, expected unix: tcp://127.0.0.1" {
+		t.Fatalf("Expected an error, got %v", err)
+	}
+	if v, err := parseUnixAddr("", "/var/run/docker.sock"); err != nil || v != "unix:///var/run/docker.sock" {
+		t.Fatalf("Expected an %v, got %v", v, "unix:///var/run/docker.sock")
+	}
+}

+ 8 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_unix.go

@@ -0,0 +1,8 @@
+// +build !windows
+
+package opts
+
+import "fmt"
+
+// DefaultHost constant defines the default host string used by docker on other hosts than Windows
+var DefaultHost = fmt.Sprintf("unix://%s", DefaultUnixSocket)

+ 6 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts_windows.go

@@ -0,0 +1,6 @@
+// +build windows
+
+package opts
+
+// DefaultHost constant defines the default host string used by docker on Windows
+var DefaultHost = DefaultTCPHost

+ 42 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ip.go

@@ -0,0 +1,42 @@
+package opts
+
+import (
+	"fmt"
+	"net"
+)
+
+// IPOpt holds an IP. It is used to store values from CLI flags.
+type IPOpt struct {
+	*net.IP
+}
+
+// NewIPOpt creates a new IPOpt from a reference net.IP and a
+// string representation of an IP. If the string is not a valid
+// IP it will fallback to the specified reference.
+func NewIPOpt(ref *net.IP, defaultVal string) *IPOpt {
+	o := &IPOpt{
+		IP: ref,
+	}
+	o.Set(defaultVal)
+	return o
+}
+
+// Set sets an IPv4 or IPv6 address from a given string. If the given
+// string is not parseable as an IP address it returns an error.
+func (o *IPOpt) Set(val string) error {
+	ip := net.ParseIP(val)
+	if ip == nil {
+		return fmt.Errorf("%s is not an ip address", val)
+	}
+	*o.IP = ip
+	return nil
+}
+
+// String returns the IP address stored in the IPOpt. If stored IP is a
+// nil pointer, it returns an empty string.
+func (o *IPOpt) String() string {
+	if *o.IP == nil {
+		return ""
+	}
+	return o.IP.String()
+}

+ 54 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ip_test.go

@@ -0,0 +1,54 @@
+package opts
+
+import (
+	"net"
+	"testing"
+)
+
+func TestIpOptString(t *testing.T) {
+	addresses := []string{"", "0.0.0.0"}
+	var ip net.IP
+
+	for _, address := range addresses {
+		stringAddress := NewIPOpt(&ip, address).String()
+		if stringAddress != address {
+			t.Fatalf("IpOpt string should be `%s`, not `%s`", address, stringAddress)
+		}
+	}
+}
+
+func TestNewIpOptInvalidDefaultVal(t *testing.T) {
+	ip := net.IPv4(127, 0, 0, 1)
+	defaultVal := "Not an ip"
+
+	ipOpt := NewIPOpt(&ip, defaultVal)
+
+	expected := "127.0.0.1"
+	if ipOpt.String() != expected {
+		t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String())
+	}
+}
+
+func TestNewIpOptValidDefaultVal(t *testing.T) {
+	ip := net.IPv4(127, 0, 0, 1)
+	defaultVal := "192.168.1.1"
+
+	ipOpt := NewIPOpt(&ip, defaultVal)
+
+	expected := "192.168.1.1"
+	if ipOpt.String() != expected {
+		t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String())
+	}
+}
+
+func TestIpOptSetInvalidVal(t *testing.T) {
+	ip := net.IPv4(127, 0, 0, 1)
+	ipOpt := &IPOpt{IP: &ip}
+
+	invalidIP := "invalid ip"
+	expectedError := "invalid ip is not an ip address"
+	err := ipOpt.Set(invalidIP)
+	if err == nil || err.Error() != expectedError {
+		t.Fatalf("Expected an Error with [%v], got [%v]", expectedError, err.Error())
+	}
+}

+ 331 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts.go

@@ -0,0 +1,331 @@
+package opts
+
+import (
+	"fmt"
+	"net"
+	"os"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/docker/docker/api/types/blkiodev"
+	"github.com/docker/go-units"
+)
+
+var (
+	alphaRegexp  = regexp.MustCompile(`[a-zA-Z]`)
+	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
+)
+
+// ListOpts holds a list of values and a validation function.
+type ListOpts struct {
+	values    *[]string
+	validator ValidatorFctType
+}
+
+// NewListOpts creates a new ListOpts with the specified validator.
+func NewListOpts(validator ValidatorFctType) ListOpts {
+	var values []string
+	return *NewListOptsRef(&values, validator)
+}
+
+// NewListOptsRef creates a new ListOpts with the specified values and validator.
+func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
+	return &ListOpts{
+		values:    values,
+		validator: validator,
+	}
+}
+
+func (opts *ListOpts) String() string {
+	return fmt.Sprintf("%v", []string((*opts.values)))
+}
+
+// Set validates if needed the input value and add it to the
+// internal slice.
+func (opts *ListOpts) Set(value string) error {
+	if opts.validator != nil {
+		v, err := opts.validator(value)
+		if err != nil {
+			return err
+		}
+		value = v
+	}
+	(*opts.values) = append((*opts.values), value)
+	return nil
+}
+
+// Delete removes the specified element from the slice.
+func (opts *ListOpts) Delete(key string) {
+	for i, k := range *opts.values {
+		if k == key {
+			(*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...)
+			return
+		}
+	}
+}
+
+// GetMap returns the content of values in a map in order to avoid
+// duplicates.
+func (opts *ListOpts) GetMap() map[string]struct{} {
+	ret := make(map[string]struct{})
+	for _, k := range *opts.values {
+		ret[k] = struct{}{}
+	}
+	return ret
+}
+
+// GetAll returns the values of slice.
+func (opts *ListOpts) GetAll() []string {
+	return (*opts.values)
+}
+
+// GetAllOrEmpty returns the values of the slice
+// or an empty slice when there are no values.
+func (opts *ListOpts) GetAllOrEmpty() []string {
+	v := *opts.values
+	if v == nil {
+		return make([]string, 0)
+	}
+	return v
+}
+
+// Get checks the existence of the specified key.
+func (opts *ListOpts) Get(key string) bool {
+	for _, k := range *opts.values {
+		if k == key {
+			return true
+		}
+	}
+	return false
+}
+
+// Len returns the amount of element in the slice.
+func (opts *ListOpts) Len() int {
+	return len((*opts.values))
+}
+
+//MapOpts holds a map of values and a validation function.
+type MapOpts struct {
+	values    map[string]string
+	validator ValidatorFctType
+}
+
+// Set validates if needed the input value and add it to the
+// internal map, by splitting on '='.
+func (opts *MapOpts) Set(value string) error {
+	if opts.validator != nil {
+		v, err := opts.validator(value)
+		if err != nil {
+			return err
+		}
+		value = v
+	}
+	vals := strings.SplitN(value, "=", 2)
+	if len(vals) == 1 {
+		(opts.values)[vals[0]] = ""
+	} else {
+		(opts.values)[vals[0]] = vals[1]
+	}
+	return nil
+}
+
+// GetAll returns the values of MapOpts as a map.
+func (opts *MapOpts) GetAll() map[string]string {
+	return opts.values
+}
+
+func (opts *MapOpts) String() string {
+	return fmt.Sprintf("%v", map[string]string((opts.values)))
+}
+
+// NewMapOpts creates a new MapOpts with the specified map of values and a validator.
+func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
+	if values == nil {
+		values = make(map[string]string)
+	}
+	return &MapOpts{
+		values:    values,
+		validator: validator,
+	}
+}
+
+// ValidatorFctType defines a validator function that returns a validated string and/or an error.
+type ValidatorFctType func(val string) (string, error)
+
+// ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error.
+type ValidatorWeightFctType func(val string) (*blkiodev.WeightDevice, error)
+
+// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error.
+type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error)
+
+// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
+type ValidatorFctListType func(val string) ([]string, error)
+
+// ValidateAttach validates that the specified string is a valid attach option.
+func ValidateAttach(val string) (string, error) {
+	s := strings.ToLower(val)
+	for _, str := range []string{"stdin", "stdout", "stderr"} {
+		if s == str {
+			return s, nil
+		}
+	}
+	return val, fmt.Errorf("valid streams are STDIN, STDOUT and STDERR")
+}
+
+// ValidateWeightDevice validates that the specified string has a valid device-weight format.
+func ValidateWeightDevice(val string) (*blkiodev.WeightDevice, error) {
+	split := strings.SplitN(val, ":", 2)
+	if len(split) != 2 {
+		return nil, fmt.Errorf("bad format: %s", val)
+	}
+	if !strings.HasPrefix(split[0], "/dev/") {
+		return nil, fmt.Errorf("bad format for device path: %s", val)
+	}
+	weight, err := strconv.ParseUint(split[1], 10, 0)
+	if err != nil {
+		return nil, fmt.Errorf("invalid weight for device: %s", val)
+	}
+	if weight > 0 && (weight < 10 || weight > 1000) {
+		return nil, fmt.Errorf("invalid weight for device: %s", val)
+	}
+
+	return &blkiodev.WeightDevice{
+		Path:   split[0],
+		Weight: uint16(weight),
+	}, nil
+}
+
+// ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format.
+func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
+	split := strings.SplitN(val, ":", 2)
+	if len(split) != 2 {
+		return nil, fmt.Errorf("bad format: %s", val)
+	}
+	if !strings.HasPrefix(split[0], "/dev/") {
+		return nil, fmt.Errorf("bad format for device path: %s", val)
+	}
+	rate, err := units.RAMInBytes(split[1])
+	if err != nil {
+		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
+	}
+	if rate < 0 {
+		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
+	}
+
+	return &blkiodev.ThrottleDevice{
+		Path: split[0],
+		Rate: uint64(rate),
+	}, nil
+}
+
+// ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format.
+func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
+	split := strings.SplitN(val, ":", 2)
+	if len(split) != 2 {
+		return nil, fmt.Errorf("bad format: %s", val)
+	}
+	if !strings.HasPrefix(split[0], "/dev/") {
+		return nil, fmt.Errorf("bad format for device path: %s", val)
+	}
+	rate, err := strconv.ParseUint(split[1], 10, 64)
+	if err != nil {
+		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
+	}
+	if rate < 0 {
+		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
+	}
+
+	return &blkiodev.ThrottleDevice{
+		Path: split[0],
+		Rate: uint64(rate),
+	}, nil
+}
+
+// ValidateEnv validates an environment variable and returns it.
+// If no value is specified, it returns the current value using os.Getenv.
+//
+// As on ParseEnvFile and related to #16585, environment variable names
+// are not validate what so ever, it's up to application inside docker
+// to validate them or not.
+func ValidateEnv(val string) (string, error) {
+	arr := strings.Split(val, "=")
+	if len(arr) > 1 {
+		return val, nil
+	}
+	if !doesEnvExist(val) {
+		return val, nil
+	}
+	return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
+}
+
+// ValidateIPAddress validates an Ip address.
+func ValidateIPAddress(val string) (string, error) {
+	var ip = net.ParseIP(strings.TrimSpace(val))
+	if ip != nil {
+		return ip.String(), nil
+	}
+	return "", fmt.Errorf("%s is not an ip address", val)
+}
+
+// ValidateMACAddress validates a MAC address.
+func ValidateMACAddress(val string) (string, error) {
+	_, err := net.ParseMAC(strings.TrimSpace(val))
+	if err != nil {
+		return "", err
+	}
+	return val, nil
+}
+
+// ValidateDNSSearch validates domain for resolvconf search configuration.
+// A zero length domain is represented by a dot (.).
+func ValidateDNSSearch(val string) (string, error) {
+	if val = strings.Trim(val, " "); val == "." {
+		return val, nil
+	}
+	return validateDomain(val)
+}
+
+func validateDomain(val string) (string, error) {
+	if alphaRegexp.FindString(val) == "" {
+		return "", fmt.Errorf("%s is not a valid domain", val)
+	}
+	ns := domainRegexp.FindSubmatch([]byte(val))
+	if len(ns) > 0 && len(ns[1]) < 255 {
+		return string(ns[1]), nil
+	}
+	return "", fmt.Errorf("%s is not a valid domain", val)
+}
+
+// ValidateExtraHost validates that the specified string is a valid extrahost and returns it.
+// ExtraHost are in the form of name:ip where the ip has to be a valid ip (ipv4 or ipv6).
+func ValidateExtraHost(val string) (string, error) {
+	// allow for IPv6 addresses in extra hosts by only splitting on first ":"
+	arr := strings.SplitN(val, ":", 2)
+	if len(arr) != 2 || len(arr[0]) == 0 {
+		return "", fmt.Errorf("bad format for add-host: %q", val)
+	}
+	if _, err := ValidateIPAddress(arr[1]); err != nil {
+		return "", fmt.Errorf("invalid IP address in add-host: %q", arr[1])
+	}
+	return val, nil
+}
+
+// ValidateLabel validates that the specified string is a valid label, and returns it.
+// Labels are in the form on key=value.
+func ValidateLabel(val string) (string, error) {
+	if strings.Count(val, "=") < 1 {
+		return "", fmt.Errorf("bad attribute format: %s", val)
+	}
+	return val, nil
+}
+
+func doesEnvExist(name string) bool {
+	for _, entry := range os.Environ() {
+		parts := strings.SplitN(entry, "=", 2)
+		if parts[0] == name {
+			return true
+		}
+	}
+	return false
+}

+ 301 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_test.go

@@ -0,0 +1,301 @@
+package opts
+
+import (
+	"fmt"
+	"os"
+	"strings"
+	"testing"
+)
+
+func TestValidateIPAddress(t *testing.T) {
+	if ret, err := ValidateIPAddress(`1.2.3.4`); err != nil || ret == "" {
+		t.Fatalf("ValidateIPAddress(`1.2.3.4`) got %s %s", ret, err)
+	}
+
+	if ret, err := ValidateIPAddress(`127.0.0.1`); err != nil || ret == "" {
+		t.Fatalf("ValidateIPAddress(`127.0.0.1`) got %s %s", ret, err)
+	}
+
+	if ret, err := ValidateIPAddress(`::1`); err != nil || ret == "" {
+		t.Fatalf("ValidateIPAddress(`::1`) got %s %s", ret, err)
+	}
+
+	if ret, err := ValidateIPAddress(`127`); err == nil || ret != "" {
+		t.Fatalf("ValidateIPAddress(`127`) got %s %s", ret, err)
+	}
+
+	if ret, err := ValidateIPAddress(`random invalid string`); err == nil || ret != "" {
+		t.Fatalf("ValidateIPAddress(`random invalid string`) got %s %s", ret, err)
+	}
+
+}
+
+func TestMapOpts(t *testing.T) {
+	tmpMap := make(map[string]string)
+	o := NewMapOpts(tmpMap, logOptsValidator)
+	o.Set("max-size=1")
+	if o.String() != "map[max-size:1]" {
+		t.Errorf("%s != [map[max-size:1]", o.String())
+	}
+
+	o.Set("max-file=2")
+	if len(tmpMap) != 2 {
+		t.Errorf("map length %d != 2", len(tmpMap))
+	}
+
+	if tmpMap["max-file"] != "2" {
+		t.Errorf("max-file = %s != 2", tmpMap["max-file"])
+	}
+
+	if tmpMap["max-size"] != "1" {
+		t.Errorf("max-size = %s != 1", tmpMap["max-size"])
+	}
+	if o.Set("dummy-val=3") == nil {
+		t.Errorf("validator is not being called")
+	}
+}
+
+func TestValidateMACAddress(t *testing.T) {
+	if _, err := ValidateMACAddress(`92:d0:c6:0a:29:33`); err != nil {
+		t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:29:33`) got %s", err)
+	}
+
+	if _, err := ValidateMACAddress(`92:d0:c6:0a:33`); err == nil {
+		t.Fatalf("ValidateMACAddress(`92:d0:c6:0a:33`) succeeded; expected failure on invalid MAC")
+	}
+
+	if _, err := ValidateMACAddress(`random invalid string`); err == nil {
+		t.Fatalf("ValidateMACAddress(`random invalid string`) succeeded; expected failure on invalid MAC")
+	}
+}
+
+func TestListOptsWithoutValidator(t *testing.T) {
+	o := NewListOpts(nil)
+	o.Set("foo")
+	if o.String() != "[foo]" {
+		t.Errorf("%s != [foo]", o.String())
+	}
+	o.Set("bar")
+	if o.Len() != 2 {
+		t.Errorf("%d != 2", o.Len())
+	}
+	o.Set("bar")
+	if o.Len() != 3 {
+		t.Errorf("%d != 3", o.Len())
+	}
+	if !o.Get("bar") {
+		t.Error("o.Get(\"bar\") == false")
+	}
+	if o.Get("baz") {
+		t.Error("o.Get(\"baz\") == true")
+	}
+	o.Delete("foo")
+	if o.String() != "[bar bar]" {
+		t.Errorf("%s != [bar bar]", o.String())
+	}
+	listOpts := o.GetAll()
+	if len(listOpts) != 2 || listOpts[0] != "bar" || listOpts[1] != "bar" {
+		t.Errorf("Expected [[bar bar]], got [%v]", listOpts)
+	}
+	mapListOpts := o.GetMap()
+	if len(mapListOpts) != 1 {
+		t.Errorf("Expected [map[bar:{}]], got [%v]", mapListOpts)
+	}
+
+}
+
+func TestListOptsWithValidator(t *testing.T) {
+	// Re-using logOptsvalidator (used by MapOpts)
+	o := NewListOpts(logOptsValidator)
+	o.Set("foo")
+	if o.String() != "[]" {
+		t.Errorf("%s != []", o.String())
+	}
+	o.Set("foo=bar")
+	if o.String() != "[]" {
+		t.Errorf("%s != []", o.String())
+	}
+	o.Set("max-file=2")
+	if o.Len() != 1 {
+		t.Errorf("%d != 1", o.Len())
+	}
+	if !o.Get("max-file=2") {
+		t.Error("o.Get(\"max-file=2\") == false")
+	}
+	if o.Get("baz") {
+		t.Error("o.Get(\"baz\") == true")
+	}
+	o.Delete("max-file=2")
+	if o.String() != "[]" {
+		t.Errorf("%s != []", o.String())
+	}
+}
+
+func TestValidateDNSSearch(t *testing.T) {
+	valid := []string{
+		`.`,
+		`a`,
+		`a.`,
+		`1.foo`,
+		`17.foo`,
+		`foo.bar`,
+		`foo.bar.baz`,
+		`foo.bar.`,
+		`foo.bar.baz`,
+		`foo1.bar2`,
+		`foo1.bar2.baz`,
+		`1foo.2bar.`,
+		`1foo.2bar.baz`,
+		`foo-1.bar-2`,
+		`foo-1.bar-2.baz`,
+		`foo-1.bar-2.`,
+		`foo-1.bar-2.baz`,
+		`1-foo.2-bar`,
+		`1-foo.2-bar.baz`,
+		`1-foo.2-bar.`,
+		`1-foo.2-bar.baz`,
+	}
+
+	invalid := []string{
+		``,
+		` `,
+		`  `,
+		`17`,
+		`17.`,
+		`.17`,
+		`17-.`,
+		`17-.foo`,
+		`.foo`,
+		`foo-.bar`,
+		`-foo.bar`,
+		`foo.bar-`,
+		`foo.bar-.baz`,
+		`foo.-bar`,
+		`foo.-bar.baz`,
+		`foo.bar.baz.this.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbethis.should.fail.on.long.name.beause.it.is.longer.thanisshouldbe`,
+	}
+
+	for _, domain := range valid {
+		if ret, err := ValidateDNSSearch(domain); err != nil || ret == "" {
+			t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
+		}
+	}
+
+	for _, domain := range invalid {
+		if ret, err := ValidateDNSSearch(domain); err == nil || ret != "" {
+			t.Fatalf("ValidateDNSSearch(`"+domain+"`) got %s %s", ret, err)
+		}
+	}
+}
+
+func TestValidateExtraHosts(t *testing.T) {
+	valid := []string{
+		`myhost:192.168.0.1`,
+		`thathost:10.0.2.1`,
+		`anipv6host:2003:ab34:e::1`,
+		`ipv6local:::1`,
+	}
+
+	invalid := map[string]string{
+		`myhost:192.notanipaddress.1`:  `invalid IP`,
+		`thathost-nosemicolon10.0.0.1`: `bad format`,
+		`anipv6host:::::1`:             `invalid IP`,
+		`ipv6local:::0::`:              `invalid IP`,
+	}
+
+	for _, extrahost := range valid {
+		if _, err := ValidateExtraHost(extrahost); err != nil {
+			t.Fatalf("ValidateExtraHost(`"+extrahost+"`) should succeed: error %v", err)
+		}
+	}
+
+	for extraHost, expectedError := range invalid {
+		if _, err := ValidateExtraHost(extraHost); err == nil {
+			t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost)
+		} else {
+			if !strings.Contains(err.Error(), expectedError) {
+				t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError)
+			}
+		}
+	}
+}
+
+func TestValidateAttach(t *testing.T) {
+	valid := []string{
+		"stdin",
+		"stdout",
+		"stderr",
+		"STDIN",
+		"STDOUT",
+		"STDERR",
+	}
+	if _, err := ValidateAttach("invalid"); err == nil {
+		t.Fatalf("Expected error with [valid streams are STDIN, STDOUT and STDERR], got nothing")
+	}
+
+	for _, attach := range valid {
+		value, err := ValidateAttach(attach)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if value != strings.ToLower(attach) {
+			t.Fatalf("Expected [%v], got [%v]", attach, value)
+		}
+	}
+}
+
+func TestValidateEnv(t *testing.T) {
+	valids := map[string]string{
+		"a":                   "a",
+		"something":           "something",
+		"_=a":                 "_=a",
+		"env1=value1":         "env1=value1",
+		"_env1=value1":        "_env1=value1",
+		"env2=value2=value3":  "env2=value2=value3",
+		"env3=abc!qwe":        "env3=abc!qwe",
+		"env_4=value 4":       "env_4=value 4",
+		"PATH":                fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
+		"PATH=something":      "PATH=something",
+		"asd!qwe":             "asd!qwe",
+		"1asd":                "1asd",
+		"123":                 "123",
+		"some space":          "some space",
+		"  some space before": "  some space before",
+		"some space after  ":  "some space after  ",
+	}
+	for value, expected := range valids {
+		actual, err := ValidateEnv(value)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if actual != expected {
+			t.Fatalf("Expected [%v], got [%v]", expected, actual)
+		}
+	}
+}
+
+func TestValidateLabel(t *testing.T) {
+	if _, err := ValidateLabel("label"); err == nil || err.Error() != "bad attribute format: label" {
+		t.Fatalf("Expected an error [bad attribute format: label], go %v", err)
+	}
+	if actual, err := ValidateLabel("key1=value1"); err != nil || actual != "key1=value1" {
+		t.Fatalf("Expected [key1=value1], got [%v,%v]", actual, err)
+	}
+	// Validate it's working with more than one =
+	if actual, err := ValidateLabel("key1=value1=value2"); err != nil {
+		t.Fatalf("Expected [key1=value1=value2], got [%v,%v]", actual, err)
+	}
+	// Validate it's working with one more
+	if actual, err := ValidateLabel("key1=value1=value2=value3"); err != nil {
+		t.Fatalf("Expected [key1=value1=value2=value2], got [%v,%v]", actual, err)
+	}
+}
+
+func logOptsValidator(val string) (string, error) {
+	allowedKeys := map[string]string{"max-size": "1", "max-file": "2"}
+	vals := strings.Split(val, "=")
+	if allowedKeys[vals[0]] != "" {
+		return val, nil
+	}
+	return "", fmt.Errorf("invalid key %s", vals[0])
+}

+ 6 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_unix.go

@@ -0,0 +1,6 @@
+// +build !windows
+
+package opts
+
+// DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080
+const DefaultHTTPHost = "localhost"

+ 56 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts_windows.go

@@ -0,0 +1,56 @@
+package opts
+
+// TODO Windows. Identify bug in GOLang 1.5.1 and/or Windows Server 2016 TP4.
+// @jhowardmsft, @swernli.
+//
+// On Windows, this mitigates a problem with the default options of running
+// a docker client against a local docker daemon on TP4.
+//
+// What was found that if the default host is "localhost", even if the client
+// (and daemon as this is local) is not physically on a network, and the DNS
+// cache is flushed (ipconfig /flushdns), then the client will pause for
+// exactly one second when connecting to the daemon for calls. For example
+// using docker run windowsservercore cmd, the CLI will send a create followed
+// by an attach. You see the delay between the attach finishing and the attach
+// being seen by the daemon.
+//
+// Here's some daemon debug logs with additional debug spew put in. The
+// AfterWriteJSON log is the very last thing the daemon does as part of the
+// create call. The POST /attach is the second CLI call. Notice the second
+// time gap.
+//
+// time="2015-11-06T13:38:37.259627400-08:00" level=debug msg="After createRootfs"
+// time="2015-11-06T13:38:37.263626300-08:00" level=debug msg="After setHostConfig"
+// time="2015-11-06T13:38:37.267631200-08:00" level=debug msg="before createContainerPl...."
+// time="2015-11-06T13:38:37.271629500-08:00" level=debug msg=ToDiskLocking....
+// time="2015-11-06T13:38:37.275643200-08:00" level=debug msg="loggin event...."
+// time="2015-11-06T13:38:37.277627600-08:00" level=debug msg="logged event...."
+// time="2015-11-06T13:38:37.279631800-08:00" level=debug msg="In defer func"
+// time="2015-11-06T13:38:37.282628100-08:00" level=debug msg="After daemon.create"
+// time="2015-11-06T13:38:37.286651700-08:00" level=debug msg="return 2"
+// time="2015-11-06T13:38:37.289629500-08:00" level=debug msg="Returned from daemon.ContainerCreate"
+// time="2015-11-06T13:38:37.311629100-08:00" level=debug msg="After WriteJSON"
+// ... 1 second gap here....
+// time="2015-11-06T13:38:38.317866200-08:00" level=debug msg="Calling POST /v1.22/containers/984758282b842f779e805664b2c95d563adc9a979c8a3973e68c807843ee4757/attach"
+// time="2015-11-06T13:38:38.326882500-08:00" level=info msg="POST /v1.22/containers/984758282b842f779e805664b2c95d563adc9a979c8a3973e68c807843ee4757/attach?stderr=1&stdin=1&stdout=1&stream=1"
+//
+// We suspect this is either a bug introduced in GOLang 1.5.1, or that a change
+// in GOLang 1.5.1 (from 1.4.3) is exposing a bug in Windows TP4. In theory,
+// the Windows networking stack is supposed to resolve "localhost" internally,
+// without hitting DNS, or even reading the hosts file (which is why localhost
+// is commented out in the hosts file on Windows).
+//
+// We have validated that working around this using the actual IPv4 localhost
+// address does not cause the delay.
+//
+// This does not occur with the docker client built with 1.4.3 on the same
+// Windows TP4 build, regardless of whether the daemon is built using 1.5.1
+// or 1.4.3. It does not occur on Linux. We also verified we see the same thing
+// on a cross-compiled Windows binary (from Linux).
+//
+// Final note: This is a mitigation, not a 'real' fix. It is still susceptible
+// to the delay in TP4 if a user were to do 'docker run -H=tcp://localhost:2375...'
+// explicitly.
+
+// DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080
+const DefaultHTTPHost = "127.0.0.1"

+ 56 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/throttledevice.go

@@ -0,0 +1,56 @@
+package opts
+
+import (
+	"fmt"
+
+	"github.com/docker/docker/api/types/blkiodev"
+)
+
+// ThrottledeviceOpt defines a map of ThrottleDevices
+type ThrottledeviceOpt struct {
+	values    []*blkiodev.ThrottleDevice
+	validator ValidatorThrottleFctType
+}
+
+// NewThrottledeviceOpt creates a new ThrottledeviceOpt
+func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt {
+	values := []*blkiodev.ThrottleDevice{}
+	return ThrottledeviceOpt{
+		values:    values,
+		validator: validator,
+	}
+}
+
+// Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt
+func (opt *ThrottledeviceOpt) Set(val string) error {
+	var value *blkiodev.ThrottleDevice
+	if opt.validator != nil {
+		v, err := opt.validator(val)
+		if err != nil {
+			return err
+		}
+		value = v
+	}
+	(opt.values) = append((opt.values), value)
+	return nil
+}
+
+// String returns ThrottledeviceOpt values as a string.
+func (opt *ThrottledeviceOpt) String() string {
+	var out []string
+	for _, v := range opt.values {
+		out = append(out, v.String())
+	}
+
+	return fmt.Sprintf("%v", out)
+}
+
+// GetList returns a slice of pointers to ThrottleDevices.
+func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice {
+	var throttledevice []*blkiodev.ThrottleDevice
+	for _, v := range opt.values {
+		throttledevice = append(throttledevice, v)
+	}
+
+	return throttledevice
+}

+ 52 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ulimit.go

@@ -0,0 +1,52 @@
+package opts
+
+import (
+	"fmt"
+
+	"github.com/docker/docker/pkg/ulimit"
+)
+
+// UlimitOpt defines a map of Ulimits
+type UlimitOpt struct {
+	values *map[string]*ulimit.Ulimit
+}
+
+// NewUlimitOpt creates a new UlimitOpt
+func NewUlimitOpt(ref *map[string]*ulimit.Ulimit) *UlimitOpt {
+	if ref == nil {
+		ref = &map[string]*ulimit.Ulimit{}
+	}
+	return &UlimitOpt{ref}
+}
+
+// Set validates a Ulimit and sets its name as a key in UlimitOpt
+func (o *UlimitOpt) Set(val string) error {
+	l, err := ulimit.Parse(val)
+	if err != nil {
+		return err
+	}
+
+	(*o.values)[l.Name] = l
+
+	return nil
+}
+
+// String returns Ulimit values as a string.
+func (o *UlimitOpt) String() string {
+	var out []string
+	for _, v := range *o.values {
+		out = append(out, v.String())
+	}
+
+	return fmt.Sprintf("%v", out)
+}
+
+// GetList returns a slice of pointers to Ulimits.
+func (o *UlimitOpt) GetList() []*ulimit.Ulimit {
+	var ulimits []*ulimit.Ulimit
+	for _, v := range *o.values {
+		ulimits = append(ulimits, v)
+	}
+
+	return ulimits
+}

+ 42 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ulimit_test.go

@@ -0,0 +1,42 @@
+package opts
+
+import (
+	"testing"
+
+	"github.com/docker/docker/pkg/ulimit"
+)
+
+func TestUlimitOpt(t *testing.T) {
+	ulimitMap := map[string]*ulimit.Ulimit{
+		"nofile": {"nofile", 1024, 512},
+	}
+
+	ulimitOpt := NewUlimitOpt(&ulimitMap)
+
+	expected := "[nofile=512:1024]"
+	if ulimitOpt.String() != expected {
+		t.Fatalf("Expected %v, got %v", expected, ulimitOpt)
+	}
+
+	// Valid ulimit append to opts
+	if err := ulimitOpt.Set("core=1024:1024"); err != nil {
+		t.Fatal(err)
+	}
+
+	// Invalid ulimit type returns an error and do not append to opts
+	if err := ulimitOpt.Set("notavalidtype=1024:1024"); err == nil {
+		t.Fatalf("Expected error on invalid ulimit type")
+	}
+	expected = "[nofile=512:1024 core=1024:1024]"
+	expected2 := "[core=1024:1024 nofile=512:1024]"
+	result := ulimitOpt.String()
+	if result != expected && result != expected2 {
+		t.Fatalf("Expected %v or %v, got %v", expected, expected2, ulimitOpt)
+	}
+
+	// And test GetList
+	ulimits := ulimitOpt.GetList()
+	if len(ulimits) != 2 {
+		t.Fatalf("Expected a ulimit list of 2, got %v", ulimits)
+	}
+}

+ 56 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/weightdevice.go

@@ -0,0 +1,56 @@
+package opts
+
+import (
+	"fmt"
+
+	"github.com/docker/docker/api/types/blkiodev"
+)
+
+// WeightdeviceOpt defines a map of WeightDevices
+type WeightdeviceOpt struct {
+	values    []*blkiodev.WeightDevice
+	validator ValidatorWeightFctType
+}
+
+// NewWeightdeviceOpt creates a new WeightdeviceOpt
+func NewWeightdeviceOpt(validator ValidatorWeightFctType) WeightdeviceOpt {
+	values := []*blkiodev.WeightDevice{}
+	return WeightdeviceOpt{
+		values:    values,
+		validator: validator,
+	}
+}
+
+// Set validates a WeightDevice and sets its name as a key in WeightdeviceOpt
+func (opt *WeightdeviceOpt) Set(val string) error {
+	var value *blkiodev.WeightDevice
+	if opt.validator != nil {
+		v, err := opt.validator(val)
+		if err != nil {
+			return err
+		}
+		value = v
+	}
+	(opt.values) = append((opt.values), value)
+	return nil
+}
+
+// String returns WeightdeviceOpt values as a string.
+func (opt *WeightdeviceOpt) String() string {
+	var out []string
+	for _, v := range opt.values {
+		out = append(out, v.String())
+	}
+
+	return fmt.Sprintf("%v", out)
+}
+
+// GetList returns a slice of pointers to WeightDevices.
+func (opt *WeightdeviceOpt) GetList() []*blkiodev.WeightDevice {
+	var weightdevice []*blkiodev.WeightDevice
+	for _, v := range opt.values {
+		weightdevice = append(weightdevice, v)
+	}
+
+	return weightdevice
+}

+ 6 - 6
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/README.md

@@ -13,29 +13,29 @@ Docker comes with multiple Discovery backends.
 ### Using etcd
 
 Point your Docker Engine instances to a common etcd instance. You can specify
-the address Docker uses to advertise the node using the `--discovery-address`
+the address Docker uses to advertise the node using the `--cluster-advertise`
 flag.
 
 ```bash
-$ docker daemon -H=<node_ip:2376> --discovery-address=<node_ip:2376> --discovery-backend etcd://<etcd_ip>/<path>
+$ docker daemon -H=<node_ip:2376> --cluster-advertise=<node_ip:2376> --cluster-store etcd://<etcd_ip1>,<etcd_ip2>/<path>
 ```
 
 ### Using consul
 
 Point your Docker Engine instances to a common Consul instance. You can specify
-the address Docker uses to advertise the node using the `--discovery-address`
+the address Docker uses to advertise the node using the `--cluster-advertise`
 flag.
 
 ```bash
-$ docker daemon -H=<node_ip:2376> --discovery-address=<node_ip:2376> --discovery-backend consul://<consul_ip>/<path>
+$ docker daemon -H=<node_ip:2376> --cluster-advertise=<node_ip:2376> --cluster-store consul://<consul_ip>/<path>
 ```
 
 ### Using zookeeper
 
 Point your Docker Engine instances to a common Zookeeper instance. You can specify
-the address Docker uses to advertise the node using the `--discovery-address`
+the address Docker uses to advertise the node using the `--cluster-advertise`
 flag.
 
 ```bash
-$ docker daemon -H=<node_ip:2376> --discovery-address=<node_ip:2376> --discovery-backend zk://<zk_addr1>,<zk_addr2>>/<path>
+$ docker daemon -H=<node_ip:2376> --cluster-advertise=<node_ip:2376> --cluster-store zk://<zk_addr1>,<zk_addr2>/<path>
 ```

+ 60 - 2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/backends.go

@@ -2,6 +2,7 @@ package discovery
 
 import (
 	"fmt"
+	"net"
 	"strings"
 	"time"
 
@@ -39,13 +40,70 @@ func parse(rawurl string) (string, string) {
 	return parts[0], parts[1]
 }
 
+// ParseAdvertise parses the --cluster-advertise daemon config which accepts
+// <ip-address>:<port> or <interface-name>:<port>
+func ParseAdvertise(store, advertise string) (string, error) {
+	var (
+		iface *net.Interface
+		addrs []net.Addr
+		err   error
+	)
+
+	addr, port, err := net.SplitHostPort(advertise)
+
+	if err != nil {
+		return "", fmt.Errorf("invalid --cluster-advertise configuration: %s: %v", advertise, err)
+	}
+
+	ip := net.ParseIP(addr)
+	// If it is a valid ip-address, use it as is
+	if ip != nil {
+		return advertise, nil
+	}
+
+	// If advertise is a valid interface name, get the valid ipv4 address and use it to advertise
+	ifaceName := addr
+	iface, err = net.InterfaceByName(ifaceName)
+	if err != nil {
+		return "", fmt.Errorf("invalid cluster advertise IP address or interface name (%s) : %v", advertise, err)
+	}
+
+	addrs, err = iface.Addrs()
+	if err != nil {
+		return "", fmt.Errorf("unable to get advertise IP address from interface (%s) : %v", advertise, err)
+	}
+
+	if addrs == nil || len(addrs) == 0 {
+		return "", fmt.Errorf("no available advertise IP address in interface (%s)", advertise)
+	}
+
+	addr = ""
+	for _, a := range addrs {
+		ip, _, err := net.ParseCIDR(a.String())
+		if err != nil {
+			return "", fmt.Errorf("error deriving advertise ip-address in interface (%s) : %v", advertise, err)
+		}
+		if ip.To4() == nil || ip.IsLoopback() {
+			continue
+		}
+		addr = ip.String()
+		break
+	}
+	if addr == "" {
+		return "", fmt.Errorf("couldnt find a valid ip-address in interface %s", advertise)
+	}
+
+	addr = fmt.Sprintf("%s:%s", addr, port)
+	return addr, nil
+}
+
 // New returns a new Discovery given a URL, heartbeat and ttl settings.
 // Returns an error if the URL scheme is not supported.
-func New(rawurl string, heartbeat time.Duration, ttl time.Duration) (Backend, error) {
+func New(rawurl string, heartbeat time.Duration, ttl time.Duration, clusterOpts map[string]string) (Backend, error) {
 	scheme, uri := parse(rawurl)
 	if backend, exists := backends[scheme]; exists {
 		log.WithFields(log.Fields{"name": scheme, "uri": uri}).Debug("Initializing discovery service")
-		err := backend.Initialize(uri, heartbeat, ttl)
+		err := backend.Initialize(uri, heartbeat, ttl, clusterOpts)
 		return backend, err
 	}
 

+ 2 - 2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/discovery.go

@@ -27,8 +27,8 @@ type Backend interface {
 	// Watcher must be provided by every backend.
 	Watcher
 
-	// Initialize the discovery with URIs, a heartbeat and a ttl.
-	Initialize(string, time.Duration, time.Duration) error
+	// Initialize the discovery with URIs, a heartbeat, a ttl and optional settings.
+	Initialize(string, time.Duration, time.Duration, map[string]string) error
 
 	// Register to the discovery.
 	Register(string) error

+ 58 - 47
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/discovery_test.go

@@ -3,92 +3,103 @@ package discovery
 import (
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	"github.com/go-check/check"
 )
 
-func TestNewEntry(t *testing.T) {
+// Hook up gocheck into the "go test" runner.
+func Test(t *testing.T) { check.TestingT(t) }
+
+type DiscoverySuite struct{}
+
+var _ = check.Suite(&DiscoverySuite{})
+
+func (s *DiscoverySuite) TestNewEntry(c *check.C) {
 	entry, err := NewEntry("127.0.0.1:2375")
-	assert.NoError(t, err)
-	assert.True(t, entry.Equals(&Entry{Host: "127.0.0.1", Port: "2375"}))
-	assert.Equal(t, entry.String(), "127.0.0.1:2375")
+	c.Assert(err, check.IsNil)
+	c.Assert(entry.Equals(&Entry{Host: "127.0.0.1", Port: "2375"}), check.Equals, true)
+	c.Assert(entry.String(), check.Equals, "127.0.0.1:2375")
 
 	_, err = NewEntry("127.0.0.1")
-	assert.Error(t, err)
+	c.Assert(err, check.NotNil)
 }
 
-func TestParse(t *testing.T) {
+func (s *DiscoverySuite) TestParse(c *check.C) {
 	scheme, uri := parse("127.0.0.1:2375")
-	assert.Equal(t, scheme, "nodes")
-	assert.Equal(t, uri, "127.0.0.1:2375")
+	c.Assert(scheme, check.Equals, "nodes")
+	c.Assert(uri, check.Equals, "127.0.0.1:2375")
 
 	scheme, uri = parse("localhost:2375")
-	assert.Equal(t, scheme, "nodes")
-	assert.Equal(t, uri, "localhost:2375")
+	c.Assert(scheme, check.Equals, "nodes")
+	c.Assert(uri, check.Equals, "localhost:2375")
 
 	scheme, uri = parse("scheme://127.0.0.1:2375")
-	assert.Equal(t, scheme, "scheme")
-	assert.Equal(t, uri, "127.0.0.1:2375")
+	c.Assert(scheme, check.Equals, "scheme")
+	c.Assert(uri, check.Equals, "127.0.0.1:2375")
 
 	scheme, uri = parse("scheme://localhost:2375")
-	assert.Equal(t, scheme, "scheme")
-	assert.Equal(t, uri, "localhost:2375")
+	c.Assert(scheme, check.Equals, "scheme")
+	c.Assert(uri, check.Equals, "localhost:2375")
 
 	scheme, uri = parse("")
-	assert.Equal(t, scheme, "nodes")
-	assert.Equal(t, uri, "")
+	c.Assert(scheme, check.Equals, "nodes")
+	c.Assert(uri, check.Equals, "")
 }
 
-func TestCreateEntries(t *testing.T) {
+func (s *DiscoverySuite) TestCreateEntries(c *check.C) {
 	entries, err := CreateEntries(nil)
-	assert.Equal(t, entries, Entries{})
-	assert.NoError(t, err)
+	c.Assert(entries, check.DeepEquals, Entries{})
+	c.Assert(err, check.IsNil)
 
 	entries, err = CreateEntries([]string{"127.0.0.1:2375", "127.0.0.2:2375", ""})
-	assert.NoError(t, err)
+	c.Assert(err, check.IsNil)
 	expected := Entries{
 		&Entry{Host: "127.0.0.1", Port: "2375"},
 		&Entry{Host: "127.0.0.2", Port: "2375"},
 	}
-	assert.True(t, entries.Equals(expected))
+	c.Assert(entries.Equals(expected), check.Equals, true)
 
 	_, err = CreateEntries([]string{"127.0.0.1", "127.0.0.2"})
-	assert.Error(t, err)
+	c.Assert(err, check.NotNil)
 }
 
-func TestContainsEntry(t *testing.T) {
+func (s *DiscoverySuite) TestContainsEntry(c *check.C) {
 	entries, err := CreateEntries([]string{"127.0.0.1:2375", "127.0.0.2:2375", ""})
-	assert.NoError(t, err)
-	assert.True(t, entries.Contains(&Entry{Host: "127.0.0.1", Port: "2375"}))
-	assert.False(t, entries.Contains(&Entry{Host: "127.0.0.3", Port: "2375"}))
+	c.Assert(err, check.IsNil)
+	c.Assert(entries.Contains(&Entry{Host: "127.0.0.1", Port: "2375"}), check.Equals, true)
+	c.Assert(entries.Contains(&Entry{Host: "127.0.0.3", Port: "2375"}), check.Equals, false)
 }
 
-func TestEntriesEquality(t *testing.T) {
+func (s *DiscoverySuite) TestEntriesEquality(c *check.C) {
 	entries := Entries{
 		&Entry{Host: "127.0.0.1", Port: "2375"},
 		&Entry{Host: "127.0.0.2", Port: "2375"},
 	}
 
 	// Same
-	assert.True(t, entries.Equals(Entries{
+	c.Assert(entries.Equals(Entries{
 		&Entry{Host: "127.0.0.1", Port: "2375"},
 		&Entry{Host: "127.0.0.2", Port: "2375"},
-	}))
+	}), check.
+		Equals, true)
 
 	// Different size
-	assert.False(t, entries.Equals(Entries{
+	c.Assert(entries.Equals(Entries{
 		&Entry{Host: "127.0.0.1", Port: "2375"},
 		&Entry{Host: "127.0.0.2", Port: "2375"},
 		&Entry{Host: "127.0.0.3", Port: "2375"},
-	}))
+	}), check.
+		Equals, false)
 
 	// Different content
-	assert.False(t, entries.Equals(Entries{
+	c.Assert(entries.Equals(Entries{
 		&Entry{Host: "127.0.0.1", Port: "2375"},
 		&Entry{Host: "127.0.0.42", Port: "2375"},
-	}))
+	}), check.
+		Equals, false)
+
 }
 
-func TestEntriesDiff(t *testing.T) {
+func (s *DiscoverySuite) TestEntriesDiff(c *check.C) {
 	entry1 := &Entry{Host: "1.1.1.1", Port: "1111"}
 	entry2 := &Entry{Host: "2.2.2.2", Port: "2222"}
 	entry3 := &Entry{Host: "3.3.3.3", Port: "3333"}
@@ -96,25 +107,25 @@ func TestEntriesDiff(t *testing.T) {
 
 	// No diff
 	added, removed := entries.Diff(Entries{entry2, entry1})
-	assert.Empty(t, added)
-	assert.Empty(t, removed)
+	c.Assert(added, check.HasLen, 0)
+	c.Assert(removed, check.HasLen, 0)
 
 	// Add
 	added, removed = entries.Diff(Entries{entry2, entry3, entry1})
-	assert.Len(t, added, 1)
-	assert.True(t, added.Contains(entry3))
-	assert.Empty(t, removed)
+	c.Assert(added, check.HasLen, 1)
+	c.Assert(added.Contains(entry3), check.Equals, true)
+	c.Assert(removed, check.HasLen, 0)
 
 	// Remove
 	added, removed = entries.Diff(Entries{entry2})
-	assert.Empty(t, added)
-	assert.Len(t, removed, 1)
-	assert.True(t, removed.Contains(entry1))
+	c.Assert(added, check.HasLen, 0)
+	c.Assert(removed, check.HasLen, 1)
+	c.Assert(removed.Contains(entry1), check.Equals, true)
 
 	// Add and remove
 	added, removed = entries.Diff(Entries{entry1, entry3})
-	assert.Len(t, added, 1)
-	assert.True(t, added.Contains(entry3))
-	assert.Len(t, removed, 1)
-	assert.True(t, removed.Contains(entry2))
+	c.Assert(added, check.HasLen, 1)
+	c.Assert(added.Contains(entry3), check.Equals, true)
+	c.Assert(removed, check.HasLen, 1)
+	c.Assert(removed.Contains(entry2), check.Equals, true)
 }

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/file/file.go

@@ -25,7 +25,7 @@ func Init() {
 }
 
 // Initialize is exported
-func (s *Discovery) Initialize(path string, heartbeat time.Duration, ttl time.Duration) error {
+func (s *Discovery) Initialize(path string, heartbeat time.Duration, ttl time.Duration, _ map[string]string) error {
 	s.path = path
 	s.heartbeat = heartbeat
 	return nil

+ 43 - 35
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/file/file_test.go

@@ -6,41 +6,49 @@ import (
 	"testing"
 
 	"github.com/docker/docker/pkg/discovery"
-	"github.com/stretchr/testify/assert"
+
+	"github.com/go-check/check"
 )
 
-func TestInitialize(t *testing.T) {
+// Hook up gocheck into the "go test" runner.
+func Test(t *testing.T) { check.TestingT(t) }
+
+type DiscoverySuite struct{}
+
+var _ = check.Suite(&DiscoverySuite{})
+
+func (s *DiscoverySuite) TestInitialize(c *check.C) {
 	d := &Discovery{}
-	d.Initialize("/path/to/file", 1000, 0)
-	assert.Equal(t, d.path, "/path/to/file")
+	d.Initialize("/path/to/file", 1000, 0, nil)
+	c.Assert(d.path, check.Equals, "/path/to/file")
 }
 
-func TestNew(t *testing.T) {
-	d, err := discovery.New("file:///path/to/file", 0, 0)
-	assert.NoError(t, err)
-	assert.Equal(t, d.(*Discovery).path, "/path/to/file")
+func (s *DiscoverySuite) TestNew(c *check.C) {
+	d, err := discovery.New("file:///path/to/file", 0, 0, nil)
+	c.Assert(err, check.IsNil)
+	c.Assert(d.(*Discovery).path, check.Equals, "/path/to/file")
 }
 
-func TestContent(t *testing.T) {
+func (s *DiscoverySuite) TestContent(c *check.C) {
 	data := `
 1.1.1.[1:2]:1111
 2.2.2.[2:4]:2222
 `
 	ips := parseFileContent([]byte(data))
-	assert.Len(t, ips, 5)
-	assert.Equal(t, ips[0], "1.1.1.1:1111")
-	assert.Equal(t, ips[1], "1.1.1.2:1111")
-	assert.Equal(t, ips[2], "2.2.2.2:2222")
-	assert.Equal(t, ips[3], "2.2.2.3:2222")
-	assert.Equal(t, ips[4], "2.2.2.4:2222")
+	c.Assert(ips, check.HasLen, 5)
+	c.Assert(ips[0], check.Equals, "1.1.1.1:1111")
+	c.Assert(ips[1], check.Equals, "1.1.1.2:1111")
+	c.Assert(ips[2], check.Equals, "2.2.2.2:2222")
+	c.Assert(ips[3], check.Equals, "2.2.2.3:2222")
+	c.Assert(ips[4], check.Equals, "2.2.2.4:2222")
 }
 
-func TestRegister(t *testing.T) {
+func (s *DiscoverySuite) TestRegister(c *check.C) {
 	discovery := &Discovery{path: "/path/to/file"}
-	assert.Error(t, discovery.Register("0.0.0.0"))
+	c.Assert(discovery.Register("0.0.0.0"), check.NotNil)
 }
 
-func TestParsingContentsWithComments(t *testing.T) {
+func (s *DiscoverySuite) TestParsingContentsWithComments(c *check.C) {
 	data := `
 ### test ###
 1.1.1.1:1111 # inline comment
@@ -50,12 +58,12 @@ func TestParsingContentsWithComments(t *testing.T) {
 ### test ###
 `
 	ips := parseFileContent([]byte(data))
-	assert.Len(t, ips, 2)
-	assert.Equal(t, "1.1.1.1:1111", ips[0])
-	assert.Equal(t, "3.3.3.3:3333", ips[1])
+	c.Assert(ips, check.HasLen, 2)
+	c.Assert("1.1.1.1:1111", check.Equals, ips[0])
+	c.Assert("3.3.3.3:3333", check.Equals, ips[1])
 }
 
-func TestWatch(t *testing.T) {
+func (s *DiscoverySuite) TestWatch(c *check.C) {
 	data := `
 1.1.1.1:1111
 2.2.2.2:2222
@@ -67,18 +75,18 @@ func TestWatch(t *testing.T) {
 
 	// Create a temporary file and remove it.
 	tmp, err := ioutil.TempFile(os.TempDir(), "discovery-file-test")
-	assert.NoError(t, err)
-	assert.NoError(t, tmp.Close())
-	assert.NoError(t, os.Remove(tmp.Name()))
+	c.Assert(err, check.IsNil)
+	c.Assert(tmp.Close(), check.IsNil)
+	c.Assert(os.Remove(tmp.Name()), check.IsNil)
 
 	// Set up file discovery.
 	d := &Discovery{}
-	d.Initialize(tmp.Name(), 1000, 0)
+	d.Initialize(tmp.Name(), 1000, 0, nil)
 	stopCh := make(chan struct{})
 	ch, errCh := d.Watch(stopCh)
 
 	// Make sure it fires errors since the file doesn't exist.
-	assert.Error(t, <-errCh)
+	c.Assert(<-errCh, check.NotNil)
 	// We have to drain the error channel otherwise Watch will get stuck.
 	go func() {
 		for range errCh {
@@ -86,21 +94,21 @@ func TestWatch(t *testing.T) {
 	}()
 
 	// Write the file and make sure we get the expected value back.
-	assert.NoError(t, ioutil.WriteFile(tmp.Name(), []byte(data), 0600))
-	assert.Equal(t, expected, <-ch)
+	c.Assert(ioutil.WriteFile(tmp.Name(), []byte(data), 0600), check.IsNil)
+	c.Assert(<-ch, check.DeepEquals, expected)
 
 	// Add a new entry and look it up.
 	expected = append(expected, &discovery.Entry{Host: "3.3.3.3", Port: "3333"})
 	f, err := os.OpenFile(tmp.Name(), os.O_APPEND|os.O_WRONLY, 0600)
-	assert.NoError(t, err)
-	assert.NotNil(t, f)
+	c.Assert(err, check.IsNil)
+	c.Assert(f, check.NotNil)
 	_, err = f.WriteString("\n3.3.3.3:3333\n")
-	assert.NoError(t, err)
+	c.Assert(err, check.IsNil)
 	f.Close()
-	assert.Equal(t, expected, <-ch)
+	c.Assert(<-ch, check.DeepEquals, expected)
 
 	// Stop and make sure it closes all channels.
 	close(stopCh)
-	assert.Nil(t, <-ch)
-	assert.Nil(t, <-errCh)
+	c.Assert(<-ch, check.IsNil)
+	c.Assert(<-errCh, check.IsNil)
 }

+ 29 - 31
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/generator_test.go

@@ -1,55 +1,53 @@
 package discovery
 
 import (
-	"testing"
-
-	"github.com/stretchr/testify/assert"
+	"github.com/go-check/check"
 )
 
-func TestGeneratorNotGenerate(t *testing.T) {
+func (s *DiscoverySuite) TestGeneratorNotGenerate(c *check.C) {
 	ips := Generate("127.0.0.1")
-	assert.Equal(t, len(ips), 1)
-	assert.Equal(t, ips[0], "127.0.0.1")
+	c.Assert(len(ips), check.Equals, 1)
+	c.Assert(ips[0], check.Equals, "127.0.0.1")
 }
 
-func TestGeneratorWithPortNotGenerate(t *testing.T) {
+func (s *DiscoverySuite) TestGeneratorWithPortNotGenerate(c *check.C) {
 	ips := Generate("127.0.0.1:8080")
-	assert.Equal(t, len(ips), 1)
-	assert.Equal(t, ips[0], "127.0.0.1:8080")
+	c.Assert(len(ips), check.Equals, 1)
+	c.Assert(ips[0], check.Equals, "127.0.0.1:8080")
 }
 
-func TestGeneratorMatchFailedNotGenerate(t *testing.T) {
+func (s *DiscoverySuite) TestGeneratorMatchFailedNotGenerate(c *check.C) {
 	ips := Generate("127.0.0.[1]")
-	assert.Equal(t, len(ips), 1)
-	assert.Equal(t, ips[0], "127.0.0.[1]")
+	c.Assert(len(ips), check.Equals, 1)
+	c.Assert(ips[0], check.Equals, "127.0.0.[1]")
 }
 
-func TestGeneratorWithPort(t *testing.T) {
+func (s *DiscoverySuite) TestGeneratorWithPort(c *check.C) {
 	ips := Generate("127.0.0.[1:11]:2375")
-	assert.Equal(t, len(ips), 11)
-	assert.Equal(t, ips[0], "127.0.0.1:2375")
-	assert.Equal(t, ips[1], "127.0.0.2:2375")
-	assert.Equal(t, ips[2], "127.0.0.3:2375")
-	assert.Equal(t, ips[3], "127.0.0.4:2375")
-	assert.Equal(t, ips[4], "127.0.0.5:2375")
-	assert.Equal(t, ips[5], "127.0.0.6:2375")
-	assert.Equal(t, ips[6], "127.0.0.7:2375")
-	assert.Equal(t, ips[7], "127.0.0.8:2375")
-	assert.Equal(t, ips[8], "127.0.0.9:2375")
-	assert.Equal(t, ips[9], "127.0.0.10:2375")
-	assert.Equal(t, ips[10], "127.0.0.11:2375")
+	c.Assert(len(ips), check.Equals, 11)
+	c.Assert(ips[0], check.Equals, "127.0.0.1:2375")
+	c.Assert(ips[1], check.Equals, "127.0.0.2:2375")
+	c.Assert(ips[2], check.Equals, "127.0.0.3:2375")
+	c.Assert(ips[3], check.Equals, "127.0.0.4:2375")
+	c.Assert(ips[4], check.Equals, "127.0.0.5:2375")
+	c.Assert(ips[5], check.Equals, "127.0.0.6:2375")
+	c.Assert(ips[6], check.Equals, "127.0.0.7:2375")
+	c.Assert(ips[7], check.Equals, "127.0.0.8:2375")
+	c.Assert(ips[8], check.Equals, "127.0.0.9:2375")
+	c.Assert(ips[9], check.Equals, "127.0.0.10:2375")
+	c.Assert(ips[10], check.Equals, "127.0.0.11:2375")
 }
 
-func TestGenerateWithMalformedInputAtRangeStart(t *testing.T) {
+func (s *DiscoverySuite) TestGenerateWithMalformedInputAtRangeStart(c *check.C) {
 	malformedInput := "127.0.0.[x:11]:2375"
 	ips := Generate(malformedInput)
-	assert.Equal(t, len(ips), 1)
-	assert.Equal(t, ips[0], malformedInput)
+	c.Assert(len(ips), check.Equals, 1)
+	c.Assert(ips[0], check.Equals, malformedInput)
 }
 
-func TestGenerateWithMalformedInputAtRangeEnd(t *testing.T) {
+func (s *DiscoverySuite) TestGenerateWithMalformedInputAtRangeEnd(c *check.C) {
 	malformedInput := "127.0.0.[1:x]:2375"
 	ips := Generate(malformedInput)
-	assert.Equal(t, len(ips), 1)
-	assert.Equal(t, ips[0], malformedInput)
+	c.Assert(len(ips), check.Equals, 1)
+	c.Assert(ips[0], check.Equals, malformedInput)
 }

+ 28 - 2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv.go

@@ -8,6 +8,7 @@ import (
 
 	log "github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
+	"github.com/docker/docker/pkg/tlsconfig"
 	"github.com/docker/libkv"
 	"github.com/docker/libkv/store"
 	"github.com/docker/libkv/store/consul"
@@ -47,7 +48,7 @@ func Init() {
 }
 
 // Initialize is exported
-func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration) error {
+func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration, clusterOpts map[string]string) error {
 	var (
 		parts = strings.SplitN(uris, "/", 2)
 		addrs = strings.Split(parts[0], ",")
@@ -63,9 +64,34 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
 	s.ttl = ttl
 	s.path = path.Join(s.prefix, discoveryPath)
 
+	var config *store.Config
+	if clusterOpts["kv.cacertfile"] != "" && clusterOpts["kv.certfile"] != "" && clusterOpts["kv.keyfile"] != "" {
+		log.Info("Initializing discovery with TLS")
+		tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
+			CAFile:   clusterOpts["kv.cacertfile"],
+			CertFile: clusterOpts["kv.certfile"],
+			KeyFile:  clusterOpts["kv.keyfile"],
+		})
+		if err != nil {
+			return err
+		}
+		config = &store.Config{
+			// Set ClientTLS to trigger https (bug in libkv/etcd)
+			ClientTLS: &store.ClientTLSConfig{
+				CACertFile: clusterOpts["kv.cacertfile"],
+				CertFile:   clusterOpts["kv.certfile"],
+				KeyFile:    clusterOpts["kv.keyfile"],
+			},
+			// The actual TLS config that will be used
+			TLS: tlsConfig,
+		}
+	} else {
+		log.Info("Initializing discovery without TLS")
+	}
+
 	// Creates a new store, will ignore options given
 	// if not supported by the chosen store
-	s.store, err = libkv.NewStore(s.backend, addrs, nil)
+	s.store, err = libkv.NewStore(s.backend, addrs, config)
 	return err
 }
 

+ 259 - 54
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv_test.go

@@ -2,77 +2,223 @@ package kv
 
 import (
 	"errors"
+	"io/ioutil"
+	"os"
 	"path"
 	"testing"
 	"time"
 
 	"github.com/docker/docker/pkg/discovery"
+	"github.com/docker/libkv"
 	"github.com/docker/libkv/store"
-	libkvmock "github.com/docker/libkv/store/mock"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/mock"
+
+	"github.com/go-check/check"
 )
 
-func TestInitialize(t *testing.T) {
-	storeMock, err := libkvmock.New([]string{"127.0.0.1"}, nil)
-	assert.NotNil(t, storeMock)
-	assert.NoError(t, err)
+// Hook up gocheck into the "go test" runner.
+func Test(t *testing.T) { check.TestingT(t) }
+
+type DiscoverySuite struct{}
+
+var _ = check.Suite(&DiscoverySuite{})
 
+func (ds *DiscoverySuite) TestInitialize(c *check.C) {
+	storeMock := &FakeStore{
+		Endpoints: []string{"127.0.0.1"},
+	}
 	d := &Discovery{backend: store.CONSUL}
-	d.Initialize("127.0.0.1", 0, 0)
+	d.Initialize("127.0.0.1", 0, 0, nil)
 	d.store = storeMock
 
-	s := d.store.(*libkvmock.Mock)
-	assert.Len(t, s.Endpoints, 1)
-	assert.Equal(t, s.Endpoints[0], "127.0.0.1")
-	assert.Equal(t, d.path, discoveryPath)
-
-	storeMock, err = libkvmock.New([]string{"127.0.0.1:1234"}, nil)
-	assert.NotNil(t, storeMock)
-	assert.NoError(t, err)
+	s := d.store.(*FakeStore)
+	c.Assert(s.Endpoints, check.HasLen, 1)
+	c.Assert(s.Endpoints[0], check.Equals, "127.0.0.1")
+	c.Assert(d.path, check.Equals, discoveryPath)
 
+	storeMock = &FakeStore{
+		Endpoints: []string{"127.0.0.1:1234"},
+	}
 	d = &Discovery{backend: store.CONSUL}
-	d.Initialize("127.0.0.1:1234/path", 0, 0)
+	d.Initialize("127.0.0.1:1234/path", 0, 0, nil)
 	d.store = storeMock
 
-	s = d.store.(*libkvmock.Mock)
-	assert.Len(t, s.Endpoints, 1)
-	assert.Equal(t, s.Endpoints[0], "127.0.0.1:1234")
-	assert.Equal(t, d.path, "path/"+discoveryPath)
-
-	storeMock, err = libkvmock.New([]string{"127.0.0.1:1234", "127.0.0.2:1234", "127.0.0.3:1234"}, nil)
-	assert.NotNil(t, storeMock)
-	assert.NoError(t, err)
+	s = d.store.(*FakeStore)
+	c.Assert(s.Endpoints, check.HasLen, 1)
+	c.Assert(s.Endpoints[0], check.Equals, "127.0.0.1:1234")
+	c.Assert(d.path, check.Equals, "path/"+discoveryPath)
 
+	storeMock = &FakeStore{
+		Endpoints: []string{"127.0.0.1:1234", "127.0.0.2:1234", "127.0.0.3:1234"},
+	}
 	d = &Discovery{backend: store.CONSUL}
-	d.Initialize("127.0.0.1:1234,127.0.0.2:1234,127.0.0.3:1234/path", 0, 0)
+	d.Initialize("127.0.0.1:1234,127.0.0.2:1234,127.0.0.3:1234/path", 0, 0, nil)
 	d.store = storeMock
 
-	s = d.store.(*libkvmock.Mock)
-	if assert.Len(t, s.Endpoints, 3) {
-		assert.Equal(t, s.Endpoints[0], "127.0.0.1:1234")
-		assert.Equal(t, s.Endpoints[1], "127.0.0.2:1234")
-		assert.Equal(t, s.Endpoints[2], "127.0.0.3:1234")
-	}
-	assert.Equal(t, d.path, "path/"+discoveryPath)
+	s = d.store.(*FakeStore)
+	c.Assert(s.Endpoints, check.HasLen, 3)
+	c.Assert(s.Endpoints[0], check.Equals, "127.0.0.1:1234")
+	c.Assert(s.Endpoints[1], check.Equals, "127.0.0.2:1234")
+	c.Assert(s.Endpoints[2], check.Equals, "127.0.0.3:1234")
+
+	c.Assert(d.path, check.Equals, "path/"+discoveryPath)
 }
 
-func TestWatch(t *testing.T) {
-	storeMock, err := libkvmock.New([]string{"127.0.0.1:1234"}, nil)
-	assert.NotNil(t, storeMock)
-	assert.NoError(t, err)
+// Extremely limited mock store so we can test initialization
+type Mock struct {
+	// Endpoints passed to InitializeMock
+	Endpoints []string
 
-	d := &Discovery{backend: store.CONSUL}
-	d.Initialize("127.0.0.1:1234/path", 0, 0)
-	d.store = storeMock
+	// Options passed to InitializeMock
+	Options *store.Config
+}
+
+func NewMock(endpoints []string, options *store.Config) (store.Store, error) {
+	s := &Mock{}
+	s.Endpoints = endpoints
+	s.Options = options
+	return s, nil
+}
+func (s *Mock) Put(key string, value []byte, opts *store.WriteOptions) error {
+	return errors.New("Put not supported")
+}
+func (s *Mock) Get(key string) (*store.KVPair, error) {
+	return nil, errors.New("Get not supported")
+}
+func (s *Mock) Delete(key string) error {
+	return errors.New("Delete not supported")
+}
+
+// Exists mock
+func (s *Mock) Exists(key string) (bool, error) {
+	return false, errors.New("Exists not supported")
+}
+
+// Watch mock
+func (s *Mock) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) {
+	return nil, errors.New("Watch not supported")
+}
+
+// WatchTree mock
+func (s *Mock) WatchTree(prefix string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) {
+	return nil, errors.New("WatchTree not supported")
+}
+
+// NewLock mock
+func (s *Mock) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
+	return nil, errors.New("NewLock not supported")
+}
+
+// List mock
+func (s *Mock) List(prefix string) ([]*store.KVPair, error) {
+	return nil, errors.New("List not supported")
+}
+
+// DeleteTree mock
+func (s *Mock) DeleteTree(prefix string) error {
+	return errors.New("DeleteTree not supported")
+}
+
+// AtomicPut mock
+func (s *Mock) AtomicPut(key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error) {
+	return false, nil, errors.New("AtomicPut not supported")
+}
+
+// AtomicDelete mock
+func (s *Mock) AtomicDelete(key string, previous *store.KVPair) (bool, error) {
+	return false, errors.New("AtomicDelete not supported")
+}
+
+// Close mock
+func (s *Mock) Close() {
+	return
+}
 
-	s := d.store.(*libkvmock.Mock)
+func (ds *DiscoverySuite) TestInitializeWithCerts(c *check.C) {
+	cert := `-----BEGIN CERTIFICATE-----
+MIIDCDCCAfKgAwIBAgIICifG7YeiQOEwCwYJKoZIhvcNAQELMBIxEDAOBgNVBAMT
+B1Rlc3QgQ0EwHhcNMTUxMDAxMjMwMDAwWhcNMjAwOTI5MjMwMDAwWjASMRAwDgYD
+VQQDEwdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wRC
+O+flnLTK5ImjTurNRHwSejuqGbc4CAvpB0hS+z0QlSs4+zE9h80aC4hz+6caRpds
++J908Q+RvAittMHbpc7VjbZP72G6fiXk7yPPl6C10HhRSoSi3nY+B7F2E8cuz14q
+V2e+ejhWhSrBb/keyXpcyjoW1BOAAJ2TIclRRkICSCZrpXUyXxAvzXfpFXo1RhSb
+UywN11pfiCQzDUN7sPww9UzFHuAHZHoyfTr27XnJYVUerVYrCPq8vqfn//01qz55
+Xs0hvzGdlTFXhuabFtQnKFH5SNwo/fcznhB7rePOwHojxOpXTBepUCIJLbtNnWFT
+V44t9gh5IqIWtoBReQIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAAYwEgYDVR0TAQH/
+BAgwBgEB/wIBAjAdBgNVHQ4EFgQUZKUI8IIjIww7X/6hvwggQK4bD24wHwYDVR0j
+BBgwFoAUZKUI8IIjIww7X/6hvwggQK4bD24wCwYJKoZIhvcNAQELA4IBAQDES2cz
+7sCQfDCxCIWH7X8kpi/JWExzUyQEJ0rBzN1m3/x8ySRxtXyGekimBqQwQdFqlwMI
+xzAQKkh3ue8tNSzRbwqMSyH14N1KrSxYS9e9szJHfUasoTpQGPmDmGIoRJuq1h6M
+ej5x1SCJ7GWCR6xEXKUIE9OftXm9TdFzWa7Ja3OHz/mXteii8VXDuZ5ACq6EE5bY
+8sP4gcICfJ5fTrpTlk9FIqEWWQrCGa5wk95PGEj+GJpNogjXQ97wVoo/Y3p1brEn
+t5zjN9PAq4H1fuCMdNNA+p1DHNwd+ELTxcMAnb2ajwHvV6lKPXutrTFc4umJToBX
+FpTxDmJHEV4bzUzh
+-----END CERTIFICATE-----
+`
+	key := `-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA1wRCO+flnLTK5ImjTurNRHwSejuqGbc4CAvpB0hS+z0QlSs4
++zE9h80aC4hz+6caRpds+J908Q+RvAittMHbpc7VjbZP72G6fiXk7yPPl6C10HhR
+SoSi3nY+B7F2E8cuz14qV2e+ejhWhSrBb/keyXpcyjoW1BOAAJ2TIclRRkICSCZr
+pXUyXxAvzXfpFXo1RhSbUywN11pfiCQzDUN7sPww9UzFHuAHZHoyfTr27XnJYVUe
+rVYrCPq8vqfn//01qz55Xs0hvzGdlTFXhuabFtQnKFH5SNwo/fcznhB7rePOwHoj
+xOpXTBepUCIJLbtNnWFTV44t9gh5IqIWtoBReQIDAQABAoIBAHSWipORGp/uKFXj
+i/mut776x8ofsAxhnLBARQr93ID+i49W8H7EJGkOfaDjTICYC1dbpGrri61qk8sx
+qX7p3v/5NzKwOIfEpirgwVIqSNYe/ncbxnhxkx6tXtUtFKmEx40JskvSpSYAhmmO
+1XSx0E/PWaEN/nLgX/f1eWJIlxlQkk3QeqL+FGbCXI48DEtlJ9+MzMu4pAwZTpj5
+5qtXo5JJ0jRGfJVPAOznRsYqv864AhMdMIWguzk6EGnbaCWwPcfcn+h9a5LMdony
+MDHfBS7bb5tkF3+AfnVY3IBMVx7YlsD9eAyajlgiKu4zLbwTRHjXgShy+4Oussz0
+ugNGnkECgYEA/hi+McrZC8C4gg6XqK8+9joD8tnyDZDz88BQB7CZqABUSwvjDqlP
+L8hcwo/lzvjBNYGkqaFPUICGWKjeCtd8pPS2DCVXxDQX4aHF1vUur0uYNncJiV3N
+XQz4Iemsa6wnKf6M67b5vMXICw7dw0HZCdIHD1hnhdtDz0uVpeevLZ8CgYEA2KCT
+Y43lorjrbCgMqtlefkr3GJA9dey+hTzCiWEOOqn9RqGoEGUday0sKhiLofOgmN2B
+LEukpKIey8s+Q/cb6lReajDVPDsMweX8i7hz3Wa4Ugp4Xa5BpHqu8qIAE2JUZ7bU
+t88aQAYE58pUF+/Lq1QzAQdrjjzQBx6SrBxieecCgYEAvukoPZEC8mmiN1VvbTX+
+QFHmlZha3QaDxChB+QUe7bMRojEUL/fVnzkTOLuVFqSfxevaI/km9n0ac5KtAchV
+xjp2bTnBb5EUQFqjopYktWA+xO07JRJtMfSEmjZPbbay1kKC7rdTfBm961EIHaRj
+xZUf6M+rOE8964oGrdgdLlECgYEA046GQmx6fh7/82FtdZDRQp9tj3SWQUtSiQZc
+qhO59Lq8mjUXz+MgBuJXxkiwXRpzlbaFB0Bca1fUoYw8o915SrDYf/Zu2OKGQ/qa
+V81sgiVmDuEgycR7YOlbX6OsVUHrUlpwhY3hgfMe6UtkMvhBvHF/WhroBEIJm1pV
+PXZ/CbMCgYEApNWVktFBjOaYfY6SNn4iSts1jgsQbbpglg3kT7PLKjCAhI6lNsbk
+dyT7ut01PL6RaW4SeQWtrJIVQaM6vF3pprMKqlc5XihOGAmVqH7rQx9rtQB5TicL
+BFrwkQE4HQtQBV60hYQUzzlSk44VFDz+jxIEtacRHaomDRh2FtOTz+I=
+-----END RSA PRIVATE KEY-----
+`
+	certFile, err := ioutil.TempFile("", "cert")
+	c.Assert(err, check.IsNil)
+	defer os.Remove(certFile.Name())
+	certFile.Write([]byte(cert))
+	certFile.Close()
+	keyFile, err := ioutil.TempFile("", "key")
+	c.Assert(err, check.IsNil)
+	defer os.Remove(keyFile.Name())
+	keyFile.Write([]byte(key))
+	keyFile.Close()
+
+	libkv.AddStore("mock", NewMock)
+	d := &Discovery{backend: "mock"}
+	err = d.Initialize("127.0.0.3:1234", 0, 0, map[string]string{
+		"kv.cacertfile": certFile.Name(),
+		"kv.certfile":   certFile.Name(),
+		"kv.keyfile":    keyFile.Name(),
+	})
+	c.Assert(err, check.IsNil)
+	s := d.store.(*Mock)
+	c.Assert(s.Options.TLS, check.NotNil)
+	c.Assert(s.Options.TLS.RootCAs, check.NotNil)
+	c.Assert(s.Options.TLS.Certificates, check.HasLen, 1)
+}
+
+func (ds *DiscoverySuite) TestWatch(c *check.C) {
 	mockCh := make(chan []*store.KVPair)
 
-	// The first watch will fail.
-	s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, errors.New("test error")).Once()
-	// The second one will succeed.
-	s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, nil).Once()
+	storeMock := &FakeStore{
+		Endpoints:  []string{"127.0.0.1:1234"},
+		mockKVChan: mockCh,
+	}
+
+	d := &Discovery{backend: store.CONSUL}
+	d.Initialize("127.0.0.1:1234/path", 0, 0, nil)
+	d.store = storeMock
+
 	expected := discovery.Entries{
 		&discovery.Entry{Host: "1.1.1.1", Port: "1111"},
 		&discovery.Entry{Host: "2.2.2.2", Port: "2222"},
@@ -86,7 +232,7 @@ func TestWatch(t *testing.T) {
 	ch, errCh := d.Watch(stopCh)
 
 	// It should fire an error since the first WatchTree call failed.
-	assert.EqualError(t, <-errCh, "test error")
+	c.Assert(<-errCh, check.ErrorMatches, "test error")
 	// We have to drain the error channel otherwise Watch will get stuck.
 	go func() {
 		for range errCh {
@@ -95,25 +241,84 @@ func TestWatch(t *testing.T) {
 
 	// Push the entries into the store channel and make sure discovery emits.
 	mockCh <- kvs
-	assert.Equal(t, <-ch, expected)
+	c.Assert(<-ch, check.DeepEquals, expected)
 
 	// Add a new entry.
 	expected = append(expected, &discovery.Entry{Host: "3.3.3.3", Port: "3333"})
 	kvs = append(kvs, &store.KVPair{Key: path.Join("path", discoveryPath, "3.3.3.3"), Value: []byte("3.3.3.3:3333")})
 	mockCh <- kvs
-	assert.Equal(t, <-ch, expected)
+	c.Assert(<-ch, check.DeepEquals, expected)
 
-	// Make sure that if an error occurs it retries.
-	// This third call to WatchTree will be checked later by AssertExpectations.
-	s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, nil)
 	close(mockCh)
 	// Give it enough time to call WatchTree.
 	time.Sleep(3)
 
 	// Stop and make sure it closes all channels.
 	close(stopCh)
-	assert.Nil(t, <-ch)
-	assert.Nil(t, <-errCh)
+	c.Assert(<-ch, check.IsNil)
+	c.Assert(<-errCh, check.IsNil)
+}
+
+// FakeStore implements store.Store methods. It mocks all store
+// function in a simple, naive way.
+type FakeStore struct {
+	Endpoints  []string
+	Options    *store.Config
+	mockKVChan <-chan []*store.KVPair
+
+	watchTreeCallCount int
+}
+
+func (s *FakeStore) Put(key string, value []byte, options *store.WriteOptions) error {
+	return nil
+}
+
+func (s *FakeStore) Get(key string) (*store.KVPair, error) {
+	return nil, nil
+}
+
+func (s *FakeStore) Delete(key string) error {
+	return nil
+}
+
+func (s *FakeStore) Exists(key string) (bool, error) {
+	return true, nil
+}
+
+func (s *FakeStore) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) {
+	return nil, nil
+}
+
+// WatchTree will fail the first time, and return the mockKVchan afterwards.
+// This is the behavior we need for testing.. If we need 'moar', should update this.
+func (s *FakeStore) WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) {
+	if s.watchTreeCallCount == 0 {
+		s.watchTreeCallCount = 1
+		return nil, errors.New("test error")
+	}
+	// First calls error
+	return s.mockKVChan, nil
+}
+
+func (s *FakeStore) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
+	return nil, nil
+}
+
+func (s *FakeStore) List(directory string) ([]*store.KVPair, error) {
+	return []*store.KVPair{}, nil
+}
+
+func (s *FakeStore) DeleteTree(directory string) error {
+	return nil
+}
+
+func (s *FakeStore) AtomicPut(key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) {
+	return true, nil, nil
+}
+
+func (s *FakeStore) AtomicDelete(key string, previous *store.KVPair) (bool, error) {
+	return true, nil
+}
 
-	s.AssertExpectations(t)
+func (s *FakeStore) Close() {
 }

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/nodes/nodes.go

@@ -23,7 +23,7 @@ func Init() {
 }
 
 // Initialize is exported
-func (s *Discovery) Initialize(uris string, _ time.Duration, _ time.Duration) error {
+func (s *Discovery) Initialize(uris string, _ time.Duration, _ time.Duration, _ map[string]string) error {
 	for _, input := range strings.Split(uris, ",") {
 		for _, ip := range discovery.Generate(input) {
 			entry, err := discovery.NewEntry(ip)

+ 27 - 19
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/nodes/nodes_test.go

@@ -4,40 +4,48 @@ import (
 	"testing"
 
 	"github.com/docker/docker/pkg/discovery"
-	"github.com/stretchr/testify/assert"
+
+	"github.com/go-check/check"
 )
 
-func TestInitialize(t *testing.T) {
+// Hook up gocheck into the "go test" runner.
+func Test(t *testing.T) { check.TestingT(t) }
+
+type DiscoverySuite struct{}
+
+var _ = check.Suite(&DiscoverySuite{})
+
+func (s *DiscoverySuite) TestInitialize(c *check.C) {
 	d := &Discovery{}
-	d.Initialize("1.1.1.1:1111,2.2.2.2:2222", 0, 0)
-	assert.Equal(t, len(d.entries), 2)
-	assert.Equal(t, d.entries[0].String(), "1.1.1.1:1111")
-	assert.Equal(t, d.entries[1].String(), "2.2.2.2:2222")
+	d.Initialize("1.1.1.1:1111,2.2.2.2:2222", 0, 0, nil)
+	c.Assert(len(d.entries), check.Equals, 2)
+	c.Assert(d.entries[0].String(), check.Equals, "1.1.1.1:1111")
+	c.Assert(d.entries[1].String(), check.Equals, "2.2.2.2:2222")
 }
 
-func TestInitializeWithPattern(t *testing.T) {
+func (s *DiscoverySuite) TestInitializeWithPattern(c *check.C) {
 	d := &Discovery{}
-	d.Initialize("1.1.1.[1:2]:1111,2.2.2.[2:4]:2222", 0, 0)
-	assert.Equal(t, len(d.entries), 5)
-	assert.Equal(t, d.entries[0].String(), "1.1.1.1:1111")
-	assert.Equal(t, d.entries[1].String(), "1.1.1.2:1111")
-	assert.Equal(t, d.entries[2].String(), "2.2.2.2:2222")
-	assert.Equal(t, d.entries[3].String(), "2.2.2.3:2222")
-	assert.Equal(t, d.entries[4].String(), "2.2.2.4:2222")
+	d.Initialize("1.1.1.[1:2]:1111,2.2.2.[2:4]:2222", 0, 0, nil)
+	c.Assert(len(d.entries), check.Equals, 5)
+	c.Assert(d.entries[0].String(), check.Equals, "1.1.1.1:1111")
+	c.Assert(d.entries[1].String(), check.Equals, "1.1.1.2:1111")
+	c.Assert(d.entries[2].String(), check.Equals, "2.2.2.2:2222")
+	c.Assert(d.entries[3].String(), check.Equals, "2.2.2.3:2222")
+	c.Assert(d.entries[4].String(), check.Equals, "2.2.2.4:2222")
 }
 
-func TestWatch(t *testing.T) {
+func (s *DiscoverySuite) TestWatch(c *check.C) {
 	d := &Discovery{}
-	d.Initialize("1.1.1.1:1111,2.2.2.2:2222", 0, 0)
+	d.Initialize("1.1.1.1:1111,2.2.2.2:2222", 0, 0, nil)
 	expected := discovery.Entries{
 		&discovery.Entry{Host: "1.1.1.1", Port: "1111"},
 		&discovery.Entry{Host: "2.2.2.2", Port: "2222"},
 	}
 	ch, _ := d.Watch(nil)
-	assert.True(t, expected.Equals(<-ch))
+	c.Assert(expected.Equals(<-ch), check.Equals, true)
 }
 
-func TestRegister(t *testing.T) {
+func (s *DiscoverySuite) TestRegister(c *check.C) {
 	d := &Discovery{}
-	assert.Error(t, d.Register("0.0.0.0"))
+	c.Assert(d.Register("0.0.0.0"), check.NotNil)
 }

+ 72 - 9
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe.go

@@ -1,16 +1,32 @@
 package ioutils
 
+import (
+	"errors"
+	"io"
+	"sync"
+)
+
+// maxCap is the highest capacity to use in byte slices that buffer data.
 const maxCap = 1e6
 
-// BytesPipe is io.ReadWriter which works similarly to pipe(queue).
-// All written data could be read only once. Also BytesPipe is allocating
-// and releasing new byte slices to adjust to current needs, so there won't be
-// overgrown buffer after high load peak.
-// BytesPipe isn't goroutine-safe, caller must synchronize it if needed.
+// blockThreshold is the minimum number of bytes in the buffer which will cause
+// a write to BytesPipe to block when allocating a new slice.
+const blockThreshold = 1e6
+
+// ErrClosed is returned when Write is called on a closed BytesPipe.
+var ErrClosed = errors.New("write to closed BytesPipe")
+
+// BytesPipe is io.ReadWriteCloser which works similarly to pipe(queue).
+// All written data may be read at most once. Also, BytesPipe allocates
+// and releases new byte slices to adjust to current needs, so the buffer
+// won't be overgrown after peak loads.
 type BytesPipe struct {
+	mu       sync.Mutex
+	wait     *sync.Cond
 	buf      [][]byte // slice of byte-slices of buffered data
 	lastRead int      // index in the first slice to a read point
 	bufLen   int      // length of data buffered over the slices
+	closeErr error    // error to return from next Read. set to nil if not closed.
 }
 
 // NewBytesPipe creates new BytesPipe, initialized by specified slice.
@@ -20,15 +36,23 @@ func NewBytesPipe(buf []byte) *BytesPipe {
 	if cap(buf) == 0 {
 		buf = make([]byte, 0, 64)
 	}
-	return &BytesPipe{
+	bp := &BytesPipe{
 		buf: [][]byte{buf[:0]},
 	}
+	bp.wait = sync.NewCond(&bp.mu)
+	return bp
 }
 
 // Write writes p to BytesPipe.
 // It can allocate new []byte slices in a process of writing.
-func (bp *BytesPipe) Write(p []byte) (n int, err error) {
+func (bp *BytesPipe) Write(p []byte) (int, error) {
+	bp.mu.Lock()
+	defer bp.mu.Unlock()
+	written := 0
 	for {
+		if bp.closeErr != nil {
+			return written, ErrClosed
+		}
 		// write data to the last buffer
 		b := bp.buf[len(bp.buf)-1]
 		// copy data to the current empty allocated area
@@ -38,6 +62,8 @@ func (bp *BytesPipe) Write(p []byte) (n int, err error) {
 		// include written data in last buffer
 		bp.buf[len(bp.buf)-1] = b[:len(b)+n]
 
+		written += n
+
 		// if there was enough room to write all then break
 		if len(p) == n {
 			break
@@ -45,15 +71,40 @@ func (bp *BytesPipe) Write(p []byte) (n int, err error) {
 
 		// more data: write to the next slice
 		p = p[n:]
+
+		// block if too much data is still in the buffer
+		for bp.bufLen >= blockThreshold {
+			bp.wait.Wait()
+		}
+
 		// allocate slice that has twice the size of the last unless maximum reached
 		nextCap := 2 * cap(bp.buf[len(bp.buf)-1])
-		if maxCap < nextCap {
+		if nextCap > maxCap {
 			nextCap = maxCap
 		}
 		// add new byte slice to the buffers slice and continue writing
 		bp.buf = append(bp.buf, make([]byte, 0, nextCap))
 	}
-	return
+	bp.wait.Broadcast()
+	return written, nil
+}
+
+// CloseWithError causes further reads from a BytesPipe to return immediately.
+func (bp *BytesPipe) CloseWithError(err error) error {
+	bp.mu.Lock()
+	if err != nil {
+		bp.closeErr = err
+	} else {
+		bp.closeErr = io.EOF
+	}
+	bp.wait.Broadcast()
+	bp.mu.Unlock()
+	return nil
+}
+
+// Close causes further reads from a BytesPipe to return immediately.
+func (bp *BytesPipe) Close() error {
+	return bp.CloseWithError(nil)
 }
 
 func (bp *BytesPipe) len() int {
@@ -63,6 +114,17 @@ func (bp *BytesPipe) len() int {
 // Read reads bytes from BytesPipe.
 // Data could be read only once.
 func (bp *BytesPipe) Read(p []byte) (n int, err error) {
+	bp.mu.Lock()
+	defer bp.mu.Unlock()
+	if bp.len() == 0 {
+		if bp.closeErr != nil {
+			return 0, bp.closeErr
+		}
+		bp.wait.Wait()
+		if bp.len() == 0 && bp.closeErr != nil {
+			return 0, bp.closeErr
+		}
+	}
 	for {
 		read := copy(p, bp.buf[0][bp.lastRead:])
 		n += read
@@ -85,5 +147,6 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) {
 		bp.buf[0] = nil     // throw away old slice
 		bp.buf = bp.buf[1:] // switch to next
 	}
+	bp.wait.Broadcast()
 	return
 }

+ 34 - 17
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe_test.go

@@ -3,7 +3,9 @@ package ioutils
 import (
 	"crypto/sha1"
 	"encoding/hex"
+	"math/rand"
 	"testing"
+	"time"
 )
 
 func TestBytesPipeRead(t *testing.T) {
@@ -86,25 +88,32 @@ func TestBytesPipeWriteRandomChunks(t *testing.T) {
 		// write/read through buffer
 		buf := NewBytesPipe(nil)
 		hash.Reset()
-		for i := 0; i < c.iterations; i++ {
-			for w := 0; w < c.writesPerLoop; w++ {
-				buf.Write(testMessage[:writeChunks[(i*c.writesPerLoop+w)%len(writeChunks)]])
-			}
-			for r := 0; r < c.readsPerLoop; r++ {
-				p := make([]byte, readChunks[(i*c.readsPerLoop+r)%len(readChunks)])
+
+		done := make(chan struct{})
+
+		go func() {
+			// random delay before read starts
+			<-time.After(time.Duration(rand.Intn(10)) * time.Millisecond)
+			for i := 0; ; i++ {
+				p := make([]byte, readChunks[(c.iterations*c.readsPerLoop+i)%len(readChunks)])
 				n, _ := buf.Read(p)
+				if n == 0 {
+					break
+				}
 				hash.Write(p[:n])
 			}
-		}
-		// read rest of the data from buffer
-		for i := 0; ; i++ {
-			p := make([]byte, readChunks[(c.iterations*c.readsPerLoop+i)%len(readChunks)])
-			n, _ := buf.Read(p)
-			if n == 0 {
-				break
+
+			close(done)
+		}()
+
+		for i := 0; i < c.iterations; i++ {
+			for w := 0; w < c.writesPerLoop; w++ {
+				buf.Write(testMessage[:writeChunks[(i*c.writesPerLoop+w)%len(writeChunks)]])
 			}
-			hash.Write(p[:n])
 		}
+		buf.Close()
+		<-done
+
 		actual := hex.EncodeToString(hash.Sum(nil))
 
 		if expected != actual {
@@ -116,24 +125,32 @@ func TestBytesPipeWriteRandomChunks(t *testing.T) {
 
 func BenchmarkBytesPipeWrite(b *testing.B) {
 	for i := 0; i < b.N; i++ {
+		readBuf := make([]byte, 1024)
 		buf := NewBytesPipe(nil)
+		go func() {
+			var err error
+			for err == nil {
+				_, err = buf.Read(readBuf)
+			}
+		}()
 		for j := 0; j < 1000; j++ {
 			buf.Write([]byte("pretty short line, because why not?"))
 		}
+		buf.Close()
 	}
 }
 
 func BenchmarkBytesPipeRead(b *testing.B) {
-	rd := make([]byte, 1024)
+	rd := make([]byte, 512)
 	for i := 0; i < b.N; i++ {
 		b.StopTimer()
 		buf := NewBytesPipe(nil)
-		for j := 0; j < 1000; j++ {
+		for j := 0; j < 500; j++ {
 			buf.Write(make([]byte, 1024))
 		}
 		b.StartTimer()
 		for j := 0; j < 1000; j++ {
-			if n, _ := buf.Read(rd); n != 1024 {
+			if n, _ := buf.Read(rd); n != 512 {
 				b.Fatalf("Wrong number of bytes: %d", n)
 			}
 		}

+ 71 - 87
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go

@@ -4,7 +4,8 @@ import (
 	"crypto/sha256"
 	"encoding/hex"
 	"io"
-	"sync"
+
+	"golang.org/x/net/context"
 )
 
 type readCloserWrapper struct {
@@ -45,92 +46,6 @@ func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
 	}
 }
 
-// bufReader allows the underlying reader to continue to produce
-// output by pre-emptively reading from the wrapped reader.
-// This is achieved by buffering this data in bufReader's
-// expanding buffer.
-type bufReader struct {
-	sync.Mutex
-	buf      io.ReadWriter
-	reader   io.Reader
-	err      error
-	wait     sync.Cond
-	drainBuf []byte
-}
-
-// NewBufReader returns a new bufReader.
-func NewBufReader(r io.Reader) io.ReadCloser {
-	reader := &bufReader{
-		buf:      NewBytesPipe(nil),
-		reader:   r,
-		drainBuf: make([]byte, 1024),
-	}
-	reader.wait.L = &reader.Mutex
-	go reader.drain()
-	return reader
-}
-
-// NewBufReaderWithDrainbufAndBuffer returns a BufReader with drainBuffer and buffer.
-func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer io.ReadWriter) io.ReadCloser {
-	reader := &bufReader{
-		buf:      buffer,
-		drainBuf: drainBuffer,
-		reader:   r,
-	}
-	reader.wait.L = &reader.Mutex
-	go reader.drain()
-	return reader
-}
-
-func (r *bufReader) drain() {
-	for {
-		//Call to scheduler is made to yield from this goroutine.
-		//This avoids goroutine looping here when n=0,err=nil, fixes code hangs when run with GCC Go.
-		callSchedulerIfNecessary()
-		n, err := r.reader.Read(r.drainBuf)
-		r.Lock()
-		if err != nil {
-			r.err = err
-		} else {
-			if n == 0 {
-				// nothing written, no need to signal
-				r.Unlock()
-				continue
-			}
-			r.buf.Write(r.drainBuf[:n])
-		}
-		r.wait.Signal()
-		r.Unlock()
-		if err != nil {
-			break
-		}
-	}
-}
-
-func (r *bufReader) Read(p []byte) (n int, err error) {
-	r.Lock()
-	defer r.Unlock()
-	for {
-		n, err = r.buf.Read(p)
-		if n > 0 {
-			return n, err
-		}
-		if r.err != nil {
-			return 0, r.err
-		}
-		r.wait.Wait()
-	}
-}
-
-// Close closes the bufReader
-func (r *bufReader) Close() error {
-	closer, ok := r.reader.(io.ReadCloser)
-	if !ok {
-		return nil
-	}
-	return closer.Close()
-}
-
 // HashData returns the sha256 sum of src.
 func HashData(src io.Reader) (string, error) {
 	h := sha256.New()
@@ -168,3 +83,72 @@ func (r *OnEOFReader) runFunc() {
 		r.Fn = nil
 	}
 }
+
+// cancelReadCloser wraps an io.ReadCloser with a context for cancelling read
+// operations.
+type cancelReadCloser struct {
+	cancel func()
+	pR     *io.PipeReader // Stream to read from
+	pW     *io.PipeWriter
+}
+
+// NewCancelReadCloser creates a wrapper that closes the ReadCloser when the
+// context is cancelled. The returned io.ReadCloser must be closed when it is
+// no longer needed.
+func NewCancelReadCloser(ctx context.Context, in io.ReadCloser) io.ReadCloser {
+	pR, pW := io.Pipe()
+
+	// Create a context used to signal when the pipe is closed
+	doneCtx, cancel := context.WithCancel(context.Background())
+
+	p := &cancelReadCloser{
+		cancel: cancel,
+		pR:     pR,
+		pW:     pW,
+	}
+
+	go func() {
+		_, err := io.Copy(pW, in)
+		select {
+		case <-ctx.Done():
+			// If the context was closed, p.closeWithError
+			// was already called. Calling it again would
+			// change the error that Read returns.
+		default:
+			p.closeWithError(err)
+		}
+		in.Close()
+	}()
+	go func() {
+		for {
+			select {
+			case <-ctx.Done():
+				p.closeWithError(ctx.Err())
+			case <-doneCtx.Done():
+				return
+			}
+		}
+	}()
+
+	return p
+}
+
+// Read wraps the Read method of the pipe that provides data from the wrapped
+// ReadCloser.
+func (p *cancelReadCloser) Read(buf []byte) (n int, err error) {
+	return p.pR.Read(buf)
+}
+
+// closeWithError closes the wrapper and its underlying reader. It will
+// cause future calls to Read to return err.
+func (p *cancelReadCloser) closeWithError(err error) {
+	p.pW.CloseWithError(err)
+	p.cancel()
+}
+
+// Close closes the wrapper its underlying reader. It will cause
+// future calls to Read to return io.EOF.
+func (p *cancelReadCloser) Close() error {
+	p.closeWithError(io.EOF)
+	return nil
+}

+ 18 - 148
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go

@@ -1,13 +1,13 @@
 package ioutils
 
 import (
-	"bytes"
 	"fmt"
-	"io"
 	"io/ioutil"
 	"strings"
 	"testing"
 	"time"
+
+	"golang.org/x/net/context"
 )
 
 // Implement io.Reader
@@ -58,101 +58,6 @@ func TestReaderErrWrapperRead(t *testing.T) {
 	}
 }
 
-func TestNewBufReaderWithDrainbufAndBuffer(t *testing.T) {
-	reader, writer := io.Pipe()
-
-	drainBuffer := make([]byte, 1024)
-	buffer := NewBytesPipe(nil)
-	bufreader := NewBufReaderWithDrainbufAndBuffer(reader, drainBuffer, buffer)
-
-	// Write everything down to a Pipe
-	// Usually, a pipe should block but because of the buffered reader,
-	// the writes will go through
-	done := make(chan bool)
-	go func() {
-		writer.Write([]byte("hello world"))
-		writer.Close()
-		done <- true
-	}()
-
-	// Drain the reader *after* everything has been written, just to verify
-	// it is indeed buffering
-	select {
-	case <-done:
-	case <-time.After(1 * time.Second):
-		t.Fatal("timeout")
-	}
-
-	output, err := ioutil.ReadAll(bufreader)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(output, []byte("hello world")) {
-		t.Error(string(output))
-	}
-}
-
-func TestBufReader(t *testing.T) {
-	reader, writer := io.Pipe()
-	bufreader := NewBufReader(reader)
-
-	// Write everything down to a Pipe
-	// Usually, a pipe should block but because of the buffered reader,
-	// the writes will go through
-	done := make(chan bool)
-	go func() {
-		writer.Write([]byte("hello world"))
-		writer.Close()
-		done <- true
-	}()
-
-	// Drain the reader *after* everything has been written, just to verify
-	// it is indeed buffering
-	<-done
-	output, err := ioutil.ReadAll(bufreader)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(output, []byte("hello world")) {
-		t.Error(string(output))
-	}
-}
-
-func TestBufReaderCloseWithNonReaderCloser(t *testing.T) {
-	reader := strings.NewReader("buffer")
-	bufreader := NewBufReader(reader)
-
-	if err := bufreader.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-}
-
-// implements io.ReadCloser
-type simpleReaderCloser struct {
-	err error
-}
-
-func (r *simpleReaderCloser) Read(p []byte) (n int, err error) {
-	return 0, r.err
-}
-
-func (r *simpleReaderCloser) Close() error {
-	r.err = io.EOF
-	return nil
-}
-
-func TestBufReaderCloseWithReaderCloser(t *testing.T) {
-	reader := &simpleReaderCloser{}
-	bufreader := NewBufReader(reader)
-
-	err := bufreader.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-}
-
 func TestHashData(t *testing.T) {
 	reader := strings.NewReader("hash-me")
 	actual, err := HashData(reader)
@@ -165,60 +70,25 @@ func TestHashData(t *testing.T) {
 	}
 }
 
-type repeatedReader struct {
-	readCount int
-	maxReads  int
-	data      []byte
-}
-
-func newRepeatedReader(max int, data []byte) *repeatedReader {
-	return &repeatedReader{0, max, data}
-}
-
-func (r *repeatedReader) Read(p []byte) (int, error) {
-	if r.readCount >= r.maxReads {
-		return 0, io.EOF
-	}
-	r.readCount++
-	n := copy(p, r.data)
-	return n, nil
-}
-
-func testWithData(data []byte, reads int) {
-	reader := newRepeatedReader(reads, data)
-	bufReader := NewBufReader(reader)
-	io.Copy(ioutil.Discard, bufReader)
-}
-
-func Benchmark1M10BytesReads(b *testing.B) {
-	reads := 1000000
-	readSize := int64(10)
-	data := make([]byte, readSize)
-	b.SetBytes(readSize * int64(reads))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		testWithData(data, reads)
-	}
-}
+type perpetualReader struct{}
 
-func Benchmark1M1024BytesReads(b *testing.B) {
-	reads := 1000000
-	readSize := int64(1024)
-	data := make([]byte, readSize)
-	b.SetBytes(readSize * int64(reads))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		testWithData(data, reads)
+func (p *perpetualReader) Read(buf []byte) (n int, err error) {
+	for i := 0; i != len(buf); i++ {
+		buf[i] = 'a'
 	}
+	return len(buf), nil
 }
 
-func Benchmark10k32KBytesReads(b *testing.B) {
-	reads := 10000
-	readSize := int64(32 * 1024)
-	data := make([]byte, readSize)
-	b.SetBytes(readSize * int64(reads))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		testWithData(data, reads)
+func TestCancelReadCloser(t *testing.T) {
+	ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
+	cancelReadCloser := NewCancelReadCloser(ctx, ioutil.NopCloser(&perpetualReader{}))
+	for {
+		var buf [128]byte
+		_, err := cancelReadCloser.Read(buf[:])
+		if err == context.DeadlineExceeded {
+			break
+		} else if err != nil {
+			t.Fatalf("got unexpected error: %v", err)
+		}
 	}
 }

+ 10 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/temp_unix.go

@@ -0,0 +1,10 @@
+// +build !windows
+
+package ioutils
+
+import "io/ioutil"
+
+// TempDir on Unix systems is equivalent to ioutil.TempDir.
+func TempDir(dir, prefix string) (string, error) {
+	return ioutil.TempDir(dir, prefix)
+}

+ 18 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/temp_windows.go

@@ -0,0 +1,18 @@
+// +build windows
+
+package ioutils
+
+import (
+	"io/ioutil"
+
+	"github.com/docker/docker/pkg/longpath"
+)
+
+// TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format.
+func TempDir(dir, prefix string) (string, error) {
+	tempDir, err := ioutil.TempDir(dir, prefix)
+	if err != nil {
+		return "", err
+	}
+	return longpath.AddPrefix(tempDir), nil
+}

+ 51 - 10
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writeflusher.go

@@ -1,32 +1,54 @@
 package ioutils
 
 import (
+	"errors"
 	"io"
 	"net/http"
 	"sync"
 )
 
-// WriteFlusher wraps the Write and Flush operation.
+// WriteFlusher wraps the Write and Flush operation ensuring that every write
+// is a flush. In addition, the Close method can be called to intercept
+// Read/Write calls if the targets lifecycle has already ended.
 type WriteFlusher struct {
-	sync.Mutex
+	mu      sync.Mutex
 	w       io.Writer
 	flusher http.Flusher
 	flushed bool
+	closed  error
+
+	// TODO(stevvooe): Use channel for closed instead, remove mutex. Using a
+	// channel will allow one to properly order the operations.
 }
 
+var errWriteFlusherClosed = errors.New("writeflusher: closed")
+
 func (wf *WriteFlusher) Write(b []byte) (n int, err error) {
-	wf.Lock()
-	defer wf.Unlock()
+	wf.mu.Lock()
+	defer wf.mu.Unlock()
+	if wf.closed != nil {
+		return 0, wf.closed
+	}
+
 	n, err = wf.w.Write(b)
-	wf.flushed = true
-	wf.flusher.Flush()
+	wf.flush() // every write is a flush.
 	return n, err
 }
 
 // Flush the stream immediately.
 func (wf *WriteFlusher) Flush() {
-	wf.Lock()
-	defer wf.Unlock()
+	wf.mu.Lock()
+	defer wf.mu.Unlock()
+
+	wf.flush()
+}
+
+// flush the stream immediately without taking a lock. Used internally.
+func (wf *WriteFlusher) flush() {
+	if wf.closed != nil {
+		return
+	}
+
 	wf.flushed = true
 	wf.flusher.Flush()
 }
@@ -34,11 +56,30 @@ func (wf *WriteFlusher) Flush() {
 // Flushed returns the state of flushed.
 // If it's flushed, return true, or else it return false.
 func (wf *WriteFlusher) Flushed() bool {
-	wf.Lock()
-	defer wf.Unlock()
+	// BUG(stevvooe): Remove this method. Its use is inherently racy. Seems to
+	// be used to detect whether or a response code has been issued or not.
+	// Another hook should be used instead.
+	wf.mu.Lock()
+	defer wf.mu.Unlock()
+
 	return wf.flushed
 }
 
+// Close closes the write flusher, disallowing any further writes to the
+// target. After the flusher is closed, all calls to write or flush will
+// result in an error.
+func (wf *WriteFlusher) Close() error {
+	wf.mu.Lock()
+	defer wf.mu.Unlock()
+
+	if wf.closed != nil {
+		return wf.closed
+	}
+
+	wf.closed = errWriteFlusherClosed
+	return nil
+}
+
 // NewWriteFlusher returns a new WriteFlusher.
 func NewWriteFlusher(w io.Writer) *WriteFlusher {
 	var flusher http.Flusher

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go

@@ -20,7 +20,7 @@ func NopWriteCloser(w io.Writer) io.WriteCloser {
 	return &nopWriteCloser{w}
 }
 
-// NopFlusher represents a type which flush opetatin is nop.
+// NopFlusher represents a type which flush operation is nop.
 type NopFlusher struct{}
 
 // Flush is a nop operation.

+ 68 - 5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mflag/flag.go

@@ -200,6 +200,24 @@ func (i *uint64Value) Get() interface{} { return uint64(*i) }
 
 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
 
+// -- uint16 Value
+type uint16Value uint16
+
+func newUint16Value(val uint16, p *uint16) *uint16Value {
+	*p = val
+	return (*uint16Value)(p)
+}
+
+func (i *uint16Value) Set(s string) error {
+	v, err := strconv.ParseUint(s, 0, 16)
+	*i = uint16Value(v)
+	return err
+}
+
+func (i *uint16Value) Get() interface{} { return uint16(*i) }
+
+func (i *uint16Value) String() string { return fmt.Sprintf("%v", *i) }
+
 // -- string Value
 type stringValue string
 
@@ -502,6 +520,20 @@ func Set(name, value string) error {
 	return CommandLine.Set(name, value)
 }
 
+// isZeroValue guesses whether the string represents the zero
+// value for a flag. It is not accurate but in practice works OK.
+func isZeroValue(value string) bool {
+	switch value {
+	case "false":
+		return true
+	case "":
+		return true
+	case "0":
+		return true
+	}
+	return false
+}
+
 // PrintDefaults prints, to standard error unless configured
 // otherwise, the default values of all defined flags in the set.
 func (fs *FlagSet) PrintDefaults() {
@@ -519,7 +551,6 @@ func (fs *FlagSet) PrintDefaults() {
 	}
 
 	fs.VisitAll(func(flag *Flag) {
-		format := "  -%s=%s"
 		names := []string{}
 		for _, name := range flag.Names {
 			if name[0] != '#' {
@@ -533,7 +564,13 @@ func (fs *FlagSet) PrintDefaults() {
 				val = homedir.GetShortcutString() + val[len(home):]
 			}
 
-			fmt.Fprintf(writer, format, strings.Join(names, ", -"), val)
+			if isZeroValue(val) {
+				format := "  -%s"
+				fmt.Fprintf(writer, format, strings.Join(names, ", -"))
+			} else {
+				format := "  -%s=%s"
+				fmt.Fprintf(writer, format, strings.Join(names, ", -"), val)
+			}
 			for i, line := range strings.Split(flag.Usage, "\n") {
 				if i != 0 {
 					line = "  " + line
@@ -571,7 +608,7 @@ var Usage = func() {
 	PrintDefaults()
 }
 
-// Usage prints to standard error a usage message documenting the standard command layout
+// ShortUsage prints to standard error a usage message documenting the standard command layout
 // The function is a variable that may be changed to point to a custom function.
 var ShortUsage = func() {
 	fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0])
@@ -757,6 +794,32 @@ func Uint64(names []string, value uint64, usage string) *uint64 {
 	return CommandLine.Uint64(names, value, usage)
 }
 
+// Uint16Var defines a uint16 flag with specified name, default value, and usage string.
+// The argument p points to a uint16 variable in which to store the value of the flag.
+func (fs *FlagSet) Uint16Var(p *uint16, names []string, value uint16, usage string) {
+	fs.Var(newUint16Value(value, p), names, usage)
+}
+
+// Uint16Var defines a uint16 flag with specified name, default value, and usage string.
+// The argument p points to a uint16 variable in which to store the value of the flag.
+func Uint16Var(p *uint16, names []string, value uint16, usage string) {
+	CommandLine.Var(newUint16Value(value, p), names, usage)
+}
+
+// Uint16 defines a uint16 flag with specified name, default value, and usage string.
+// The return value is the address of a uint16 variable that stores the value of the flag.
+func (fs *FlagSet) Uint16(names []string, value uint16, usage string) *uint16 {
+	p := new(uint16)
+	fs.Uint16Var(p, names, value, usage)
+	return p
+}
+
+// Uint16 defines a uint16 flag with specified name, default value, and usage string.
+// The return value is the address of a uint16 variable that stores the value of the flag.
+func Uint16(names []string, value uint16, usage string) *uint16 {
+	return CommandLine.Uint16(names, value, usage)
+}
+
 // StringVar defines a string flag with specified name, default value, and usage string.
 // The argument p points to a string variable in which to store the value of the flag.
 func (fs *FlagSet) StringVar(p *string, names []string, value string, usage string) {
@@ -1058,7 +1121,7 @@ func (fs *FlagSet) Parse(arguments []string) error {
 		case ContinueOnError:
 			return err
 		case ExitOnError:
-			os.Exit(2)
+			os.Exit(125)
 		case PanicOnError:
 			panic(err)
 		}
@@ -1165,7 +1228,7 @@ func (v mergeVal) IsBoolFlag() bool {
 
 // Merge is an helper function that merges n FlagSets into a single dest FlagSet
 // In case of name collision between the flagsets it will apply
-// the destination FlagSet's errorHandling behaviour.
+// the destination FlagSet's errorHandling behavior.
 func Merge(dest *FlagSet, flagsets ...*FlagSet) error {
 	for _, fset := range flagsets {
 		for k, f := range fset.formal {

+ 23 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go

@@ -1,6 +1,7 @@
 package mount
 
 import (
+	"fmt"
 	"strings"
 )
 
@@ -67,3 +68,25 @@ func parseOptions(options string) (int, string) {
 	}
 	return flag, strings.Join(data, ",")
 }
+
+// ParseTmpfsOptions parse fstab type mount options into flags and data
+func ParseTmpfsOptions(options string) (int, string, error) {
+	flags, data := parseOptions(options)
+	validFlags := map[string]bool{
+		"":          true,
+		"size":      true,
+		"mode":      true,
+		"uid":       true,
+		"gid":       true,
+		"nr_inodes": true,
+		"nr_blocks": true,
+		"mpol":      true,
+	}
+	for _, o := range strings.Split(data, ",") {
+		opt := strings.SplitN(o, "=", 2)
+		if !validFlags[opt[0]] {
+			return 0, "", fmt.Errorf("Invalid tmpfs option %q", opt)
+		}
+	}
+	return flags, data, nil
+}

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags_linux.go

@@ -23,7 +23,7 @@ const (
 	SYNCHRONOUS = syscall.MS_SYNCHRONOUS
 
 	// DIRSYNC will force all directory updates within the file system to be done
-	// synchronously. This affects the following system calls: creat, link,
+	// synchronously. This affects the following system calls: create, link,
 	// unlink, symlink, mkdir, rmdir, mknod and rename.
 	DIRSYNC = syscall.MS_DIRSYNC
 

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/sharedsubtree_linux_test.go

@@ -168,7 +168,7 @@ func TestSubtreeShared(t *testing.T) {
 		}
 	}()
 
-	// NOW, check that the file from the outside directory is avaible in the source directory
+	// NOW, check that the file from the outside directory is available in the source directory
 	if _, err := os.Stat(sourceCheckPath); err != nil {
 		t.Fatal(err)
 	}

+ 0 - 116
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse.go

@@ -1,116 +0,0 @@
-package filters
-
-import (
-	"encoding/json"
-	"errors"
-	"regexp"
-	"strings"
-)
-
-type Args map[string][]string
-
-// Parse the argument to the filter flag. Like
-//
-//   `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
-//
-// If prev map is provided, then it is appended to, and returned. By default a new
-// map is created.
-func ParseFlag(arg string, prev Args) (Args, error) {
-	var filters Args = prev
-	if prev == nil {
-		filters = Args{}
-	}
-	if len(arg) == 0 {
-		return filters, nil
-	}
-
-	if !strings.Contains(arg, "=") {
-		return filters, ErrorBadFormat
-	}
-
-	f := strings.SplitN(arg, "=", 2)
-	name := strings.ToLower(strings.TrimSpace(f[0]))
-	value := strings.TrimSpace(f[1])
-	filters[name] = append(filters[name], value)
-
-	return filters, nil
-}
-
-var ErrorBadFormat = errors.New("bad format of filter (expected name=value)")
-
-// packs the Args into an string for easy transport from client to server
-func ToParam(a Args) (string, error) {
-	// this way we don't URL encode {}, just empty space
-	if len(a) == 0 {
-		return "", nil
-	}
-
-	buf, err := json.Marshal(a)
-	if err != nil {
-		return "", err
-	}
-	return string(buf), nil
-}
-
-// unpacks the filter Args
-func FromParam(p string) (Args, error) {
-	args := Args{}
-	if len(p) == 0 {
-		return args, nil
-	}
-	if err := json.NewDecoder(strings.NewReader(p)).Decode(&args); err != nil {
-		return nil, err
-	}
-	return args, nil
-}
-
-func (filters Args) MatchKVList(field string, sources map[string]string) bool {
-	fieldValues := filters[field]
-
-	//do not filter if there is no filter set or cannot determine filter
-	if len(fieldValues) == 0 {
-		return true
-	}
-
-	if sources == nil || len(sources) == 0 {
-		return false
-	}
-
-outer:
-	for _, name2match := range fieldValues {
-		testKV := strings.SplitN(name2match, "=", 2)
-
-		for k, v := range sources {
-			if len(testKV) == 1 {
-				if k == testKV[0] {
-					continue outer
-				}
-			} else if k == testKV[0] && v == testKV[1] {
-				continue outer
-			}
-		}
-
-		return false
-	}
-
-	return true
-}
-
-func (filters Args) Match(field, source string) bool {
-	fieldValues := filters[field]
-
-	//do not filter if there is no filter set or cannot determine filter
-	if len(fieldValues) == 0 {
-		return true
-	}
-	for _, name2match := range fieldValues {
-		match, err := regexp.MatchString(name2match, source)
-		if err != nil {
-			continue
-		}
-		if match {
-			return true
-		}
-	}
-	return false
-}

+ 0 - 78
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/filters/parse_test.go

@@ -1,78 +0,0 @@
-package filters
-
-import (
-	"sort"
-	"testing"
-)
-
-func TestParseArgs(t *testing.T) {
-	// equivalent of `docker ps -f 'created=today' -f 'image.name=ubuntu*' -f 'image.name=*untu'`
-	flagArgs := []string{
-		"created=today",
-		"image.name=ubuntu*",
-		"image.name=*untu",
-	}
-	var (
-		args = Args{}
-		err  error
-	)
-	for i := range flagArgs {
-		args, err = ParseFlag(flagArgs[i], args)
-		if err != nil {
-			t.Errorf("failed to parse %s: %s", flagArgs[i], err)
-		}
-	}
-	if len(args["created"]) != 1 {
-		t.Errorf("failed to set this arg")
-	}
-	if len(args["image.name"]) != 2 {
-		t.Errorf("the args should have collapsed")
-	}
-}
-
-func TestParam(t *testing.T) {
-	a := Args{
-		"created":    []string{"today"},
-		"image.name": []string{"ubuntu*", "*untu"},
-	}
-
-	v, err := ToParam(a)
-	if err != nil {
-		t.Errorf("failed to marshal the filters: %s", err)
-	}
-	v1, err := FromParam(v)
-	if err != nil {
-		t.Errorf("%s", err)
-	}
-	for key, vals := range v1 {
-		if _, ok := a[key]; !ok {
-			t.Errorf("could not find key %s in original set", key)
-		}
-		sort.Strings(vals)
-		sort.Strings(a[key])
-		if len(vals) != len(a[key]) {
-			t.Errorf("value lengths ought to match")
-			continue
-		}
-		for i := range vals {
-			if vals[i] != a[key][i] {
-				t.Errorf("expected %s, but got %s", a[key][i], vals[i])
-			}
-		}
-	}
-}
-
-func TestEmpty(t *testing.T) {
-	a := Args{}
-	v, err := ToParam(a)
-	if err != nil {
-		t.Errorf("failed to marshal the filters: %s", err)
-	}
-	v1, err := FromParam(v)
-	if err != nil {
-		t.Errorf("%s", err)
-	}
-	if len(a) != len(v1) {
-		t.Errorf("these should both be empty sets")
-	}
-}

+ 16 - 11
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go

@@ -1,5 +1,7 @@
 // +build !windows
 
+// Package kernel provides helper function to get, parse and compare kernel
+// versions for different platforms.
 package kernel
 
 import (
@@ -8,20 +10,21 @@ import (
 	"fmt"
 )
 
-type KernelVersionInfo struct {
-	Kernel int
-	Major  int
-	Minor  int
-	Flavor string
+// VersionInfo holds information about the kernel.
+type VersionInfo struct {
+	Kernel int    // Version of the kernel (e.g. 4.1.2-generic -> 4)
+	Major  int    // Major part of the kernel version (e.g. 4.1.2-generic -> 1)
+	Minor  int    // Minor part of the kernel version (e.g. 4.1.2-generic -> 2)
+	Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic)
 }
 
-func (k *KernelVersionInfo) String() string {
+func (k *VersionInfo) String() string {
 	return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
 }
 
-// Compare two KernelVersionInfo struct.
+// CompareKernelVersion compares two kernel.VersionInfo structs.
 // Returns -1 if a < b, 0 if a == b, 1 it a > b
-func CompareKernelVersion(a, b *KernelVersionInfo) int {
+func CompareKernelVersion(a, b VersionInfo) int {
 	if a.Kernel < b.Kernel {
 		return -1
 	} else if a.Kernel > b.Kernel {
@@ -43,7 +46,8 @@ func CompareKernelVersion(a, b *KernelVersionInfo) int {
 	return 0
 }
 
-func GetKernelVersion() (*KernelVersionInfo, error) {
+// GetKernelVersion gets the current kernel version.
+func GetKernelVersion() (*VersionInfo, error) {
 	var (
 		err error
 	)
@@ -67,7 +71,8 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
 	return ParseRelease(string(release))
 }
 
-func ParseRelease(release string) (*KernelVersionInfo, error) {
+// ParseRelease parses a string and creates a VersionInfo based on it.
+func ParseRelease(release string) (*VersionInfo, error) {
 	var (
 		kernel, major, minor, parsed int
 		flavor, partial              string
@@ -86,7 +91,7 @@ func ParseRelease(release string) (*KernelVersionInfo, error) {
 		flavor = partial
 	}
 
-	return &KernelVersionInfo{
+	return &VersionInfo{
 		Kernel: kernel,
 		Major:  major,
 		Minor:  minor,

+ 0 - 61
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_test.go

@@ -1,61 +0,0 @@
-package kernel
-
-import (
-	"testing"
-)
-
-func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
-	var (
-		a *KernelVersionInfo
-	)
-	a, _ = ParseRelease(release)
-
-	if r := CompareKernelVersion(a, b); r != result {
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
-	}
-	if a.Flavor != b.Flavor {
-		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
-	}
-}
-
-func TestParseRelease(t *testing.T) {
-	assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
-	assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
-	assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
-	assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
-}
-
-func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
-	if r := CompareKernelVersion(a, b); r != result {
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
-	}
-}
-
-func TestCompareKernelVersion(t *testing.T) {
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		0)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		-1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
-		1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		0)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		-1)
-}

+ 96 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_unix_test.go

@@ -0,0 +1,96 @@
+// +build !windows
+
+package kernel
+
+import (
+	"fmt"
+	"testing"
+)
+
+func assertParseRelease(t *testing.T, release string, b *VersionInfo, result int) {
+	var (
+		a *VersionInfo
+	)
+	a, _ = ParseRelease(release)
+
+	if r := CompareKernelVersion(*a, *b); r != result {
+		t.Fatalf("Unexpected kernel version comparison result for (%v,%v). Found %d, expected %d", release, b, r, result)
+	}
+	if a.Flavor != b.Flavor {
+		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
+	}
+}
+
+// TestParseRelease tests the ParseRelease() function
+func TestParseRelease(t *testing.T) {
+	assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
+	assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
+	assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
+	assertParseRelease(t, "3.8.0-19-generic", &VersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
+	assertParseRelease(t, "3.12.8tag", &VersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
+	assertParseRelease(t, "3.12-1-amd64", &VersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
+	assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 4, Major: 8, Minor: 0}, -1)
+	// Errors
+	invalids := []string{
+		"3",
+		"a",
+		"a.a",
+		"a.a.a-a",
+	}
+	for _, invalid := range invalids {
+		expectedMessage := fmt.Sprintf("Can't parse kernel version %v", invalid)
+		if _, err := ParseRelease(invalid); err == nil || err.Error() != expectedMessage {
+
+		}
+	}
+}
+
+func assertKernelVersion(t *testing.T, a, b VersionInfo, result int) {
+	if r := CompareKernelVersion(a, b); r != result {
+		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
+	}
+}
+
+// TestCompareKernelVersion tests the CompareKernelVersion() function
+func TestCompareKernelVersion(t *testing.T) {
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		0)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 2, Major: 6, Minor: 0},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		-1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		VersionInfo{Kernel: 2, Major: 6, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		0)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 5},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 0, Minor: 20},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		-1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 7, Minor: 20},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		-1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 20},
+		VersionInfo{Kernel: 3, Major: 7, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 20},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		VersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		VersionInfo{Kernel: 3, Major: 8, Minor: 20},
+		-1)
+}

+ 10 - 8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go

@@ -6,18 +6,20 @@ import (
 	"unsafe"
 )
 
-type KernelVersionInfo struct {
-	kvi   string
-	major int
-	minor int
-	build int
+// VersionInfo holds information about the kernel.
+type VersionInfo struct {
+	kvi   string // Version of the kernel (e.g. 6.1.7601.17592 -> 6)
+	major int    // Major part of the kernel version (e.g. 6.1.7601.17592 -> 1)
+	minor int    // Minor part of the kernel version (e.g. 6.1.7601.17592 -> 7601)
+	build int    // Build number of the kernel version (e.g. 6.1.7601.17592 -> 17592)
 }
 
-func (k *KernelVersionInfo) String() string {
+func (k *VersionInfo) String() string {
 	return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
 }
 
-func GetKernelVersion() (*KernelVersionInfo, error) {
+// GetKernelVersion gets the current kernel version.
+func GetKernelVersion() (*VersionInfo, error) {
 
 	var (
 		h         syscall.Handle
@@ -25,7 +27,7 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
 		err       error
 	)
 
-	KVI := &KernelVersionInfo{"Unknown", 0, 0, 0}
+	KVI := &VersionInfo{"Unknown", 0, 0, 0}
 
 	if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
 		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),

+ 3 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_linux.go

@@ -4,6 +4,9 @@ import (
 	"syscall"
 )
 
+// Utsname represents the system name structure.
+// It is passthgrouh for syscall.Utsname in order to make it portable with
+// other platforms where it is not available.
 type Utsname syscall.Utsname
 
 func uname() (*syscall.Utsname, error) {

+ 3 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/uname_unsupported.go

@@ -6,6 +6,9 @@ import (
 	"errors"
 )
 
+// Utsname represents the system name structure.
+// It is defined here to make it portable as it is available on linux but not
+// on windows.
 type Utsname struct {
 	Release [65]byte
 }

+ 0 - 40
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_linux.go

@@ -1,40 +0,0 @@
-package operatingsystem
-
-import (
-	"bytes"
-	"errors"
-	"io/ioutil"
-)
-
-var (
-	// file to use to detect if the daemon is running in a container
-	proc1Cgroup = "/proc/1/cgroup"
-
-	// file to check to determine Operating System
-	etcOsRelease = "/etc/os-release"
-)
-
-func GetOperatingSystem() (string, error) {
-	b, err := ioutil.ReadFile(etcOsRelease)
-	if err != nil {
-		return "", err
-	}
-	if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 {
-		b = b[i+13:]
-		return string(b[:bytes.IndexByte(b, '"')]), nil
-	}
-	return "", errors.New("PRETTY_NAME not found")
-}
-
-func IsContainerized() (bool, error) {
-	b, err := ioutil.ReadFile(proc1Cgroup)
-	if err != nil {
-		return false, err
-	}
-	for _, line := range bytes.Split(b, []byte{'\n'}) {
-		if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) {
-			return true, nil
-		}
-	}
-	return false, nil
-}

+ 0 - 124
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_test.go

@@ -1,124 +0,0 @@
-package operatingsystem
-
-import (
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"testing"
-)
-
-func TestGetOperatingSystem(t *testing.T) {
-	var (
-		backup       = etcOsRelease
-		ubuntuTrusty = []byte(`NAME="Ubuntu"
-VERSION="14.04, Trusty Tahr"
-ID=ubuntu
-ID_LIKE=debian
-PRETTY_NAME="Ubuntu 14.04 LTS"
-VERSION_ID="14.04"
-HOME_URL="http://www.ubuntu.com/"
-SUPPORT_URL="http://help.ubuntu.com/"
-BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`)
-		gentoo = []byte(`NAME=Gentoo
-ID=gentoo
-PRETTY_NAME="Gentoo/Linux"
-ANSI_COLOR="1;32"
-HOME_URL="http://www.gentoo.org/"
-SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
-BUG_REPORT_URL="https://bugs.gentoo.org/"
-`)
-		noPrettyName = []byte(`NAME="Ubuntu"
-VERSION="14.04, Trusty Tahr"
-ID=ubuntu
-ID_LIKE=debian
-VERSION_ID="14.04"
-HOME_URL="http://www.ubuntu.com/"
-SUPPORT_URL="http://help.ubuntu.com/"
-BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`)
-	)
-
-	dir := os.TempDir()
-	etcOsRelease = filepath.Join(dir, "etcOsRelease")
-
-	defer func() {
-		os.Remove(etcOsRelease)
-		etcOsRelease = backup
-	}()
-
-	for expect, osRelease := range map[string][]byte{
-		"Ubuntu 14.04 LTS": ubuntuTrusty,
-		"Gentoo/Linux":     gentoo,
-		"":                 noPrettyName,
-	} {
-		if err := ioutil.WriteFile(etcOsRelease, osRelease, 0600); err != nil {
-			t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
-		}
-		s, err := GetOperatingSystem()
-		if s != expect {
-			if expect == "" {
-				t.Fatalf("Expected error 'PRETTY_NAME not found', but got %v", err)
-			} else {
-				t.Fatalf("Expected '%s', but got '%s'. Err=%v", expect, s, err)
-			}
-		}
-	}
-}
-
-func TestIsContainerized(t *testing.T) {
-	var (
-		backup                      = proc1Cgroup
-		nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/
-13:hugetlb:/
-12:net_prio:/
-11:perf_event:/
-10:bfqio:/
-9:blkio:/
-8:net_cls:/
-7:freezer:/
-6:devices:/
-5:memory:/
-4:cpuacct:/
-3:cpu:/
-2:cpuset:/
-`)
-		containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-8:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-7:net_cls:/
-6:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-5:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-4:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-3:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-2:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
-1:cpuset:/`)
-	)
-
-	dir := os.TempDir()
-	proc1Cgroup = filepath.Join(dir, "proc1Cgroup")
-
-	defer func() {
-		os.Remove(proc1Cgroup)
-		proc1Cgroup = backup
-	}()
-
-	if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil {
-		t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
-	}
-	inContainer, err := IsContainerized()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if inContainer {
-		t.Fatal("Wrongly assuming containerized")
-	}
-
-	if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil {
-		t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
-	}
-	inContainer, err = IsContainerized()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !inContainer {
-		t.Fatal("Wrongly assuming non-containerized")
-	}
-}

+ 0 - 47
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/operatingsystem/operatingsystem_windows.go

@@ -1,47 +0,0 @@
-package operatingsystem
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-// See https://code.google.com/p/go/source/browse/src/pkg/mime/type_windows.go?r=d14520ac25bf6940785aabb71f5be453a286f58c
-// for a similar sample
-
-func GetOperatingSystem() (string, error) {
-
-	var h syscall.Handle
-
-	// Default return value
-	ret := "Unknown Operating System"
-
-	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
-		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
-		0,
-		syscall.KEY_READ,
-		&h); err != nil {
-		return ret, err
-	}
-	defer syscall.RegCloseKey(h)
-
-	var buf [1 << 10]uint16
-	var typ uint32
-	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
-
-	if err := syscall.RegQueryValueEx(h,
-		syscall.StringToUTF16Ptr("ProductName"),
-		nil,
-		&typ,
-		(*byte)(unsafe.Pointer(&buf[0])),
-		&n); err != nil {
-		return ret, err
-	}
-	ret = syscall.UTF16ToString(buf[:])
-
-	return ret, nil
-}
-
-// No-op on Windows
-func IsContainerized() (bool, error) {
-	return false, nil
-}

+ 0 - 157
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers.go

@@ -1,157 +0,0 @@
-package parsers
-
-import (
-	"fmt"
-	"runtime"
-	"strconv"
-	"strings"
-)
-
-// FIXME: Change this not to receive default value as parameter
-func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) {
-	addr = strings.TrimSpace(addr)
-	if addr == "" {
-		if runtime.GOOS != "windows" {
-			addr = fmt.Sprintf("unix://%s", defaultUnixAddr)
-		} else {
-			// Note - defaultTCPAddr already includes tcp:// prefix
-			addr = fmt.Sprintf("%s", defaultTCPAddr)
-		}
-	}
-	addrParts := strings.Split(addr, "://")
-	if len(addrParts) == 1 {
-		addrParts = []string{"tcp", addrParts[0]}
-	}
-
-	switch addrParts[0] {
-	case "tcp":
-		return ParseTCPAddr(addrParts[1], defaultTCPAddr)
-	case "unix":
-		return ParseUnixAddr(addrParts[1], defaultUnixAddr)
-	case "fd":
-		return addr, nil
-	default:
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
-	}
-}
-
-func ParseUnixAddr(addr string, defaultAddr string) (string, error) {
-	addr = strings.TrimPrefix(addr, "unix://")
-	if strings.Contains(addr, "://") {
-		return "", fmt.Errorf("Invalid proto, expected unix: %s", addr)
-	}
-	if addr == "" {
-		addr = defaultAddr
-	}
-	return fmt.Sprintf("unix://%s", addr), nil
-}
-
-func ParseTCPAddr(addr string, defaultAddr string) (string, error) {
-	addr = strings.TrimPrefix(addr, "tcp://")
-	if strings.Contains(addr, "://") || addr == "" {
-		return "", fmt.Errorf("Invalid proto, expected tcp: %s", addr)
-	}
-
-	hostParts := strings.Split(addr, ":")
-	if len(hostParts) != 2 {
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
-	}
-	host := hostParts[0]
-	if host == "" {
-		host = defaultAddr
-	}
-
-	p, err := strconv.Atoi(hostParts[1])
-	if err != nil && p == 0 {
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
-	}
-	return fmt.Sprintf("tcp://%s:%d", host, p), nil
-}
-
-// Get a repos name and returns the right reposName + tag|digest
-// The tag can be confusing because of a port in a repository name.
-//     Ex: localhost.localdomain:5000/samalba/hipache:latest
-//     Digest ex: localhost:5000/foo/bar@sha256:bc8813ea7b3603864987522f02a76101c17ad122e1c46d790efc0fca78ca7bfb
-func ParseRepositoryTag(repos string) (string, string) {
-	n := strings.Index(repos, "@")
-	if n >= 0 {
-		parts := strings.Split(repos, "@")
-		return parts[0], parts[1]
-	}
-	n = strings.LastIndex(repos, ":")
-	if n < 0 {
-		return repos, ""
-	}
-	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
-		return repos[:n], tag
-	}
-	return repos, ""
-}
-
-func PartParser(template, data string) (map[string]string, error) {
-	// ip:public:private
-	var (
-		templateParts = strings.Split(template, ":")
-		parts         = strings.Split(data, ":")
-		out           = make(map[string]string, len(templateParts))
-	)
-	if len(parts) != len(templateParts) {
-		return nil, fmt.Errorf("Invalid format to parse.  %s should match template %s", data, template)
-	}
-
-	for i, t := range templateParts {
-		value := ""
-		if len(parts) > i {
-			value = parts[i]
-		}
-		out[t] = value
-	}
-	return out, nil
-}
-
-func ParseKeyValueOpt(opt string) (string, string, error) {
-	parts := strings.SplitN(opt, "=", 2)
-	if len(parts) != 2 {
-		return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
-	}
-	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
-}
-
-func ParsePortRange(ports string) (uint64, uint64, error) {
-	if ports == "" {
-		return 0, 0, fmt.Errorf("Empty string specified for ports.")
-	}
-	if !strings.Contains(ports, "-") {
-		start, err := strconv.ParseUint(ports, 10, 16)
-		end := start
-		return start, end, err
-	}
-
-	parts := strings.Split(ports, "-")
-	start, err := strconv.ParseUint(parts[0], 10, 16)
-	if err != nil {
-		return 0, 0, err
-	}
-	end, err := strconv.ParseUint(parts[1], 10, 16)
-	if err != nil {
-		return 0, 0, err
-	}
-	if end < start {
-		return 0, 0, fmt.Errorf("Invalid range specified for the Port: %s", ports)
-	}
-	return start, end, nil
-}
-
-func ParseLink(val string) (string, string, error) {
-	if val == "" {
-		return "", "", fmt.Errorf("empty string specified for links")
-	}
-	arr := strings.Split(val, ":")
-	if len(arr) > 2 {
-		return "", "", fmt.Errorf("bad format for links: %s", val)
-	}
-	if len(arr) == 1 {
-		return val, val, nil
-	}
-	return arr[0], arr[1], nil
-}

+ 0 - 157
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/parsers_test.go

@@ -1,157 +0,0 @@
-package parsers
-
-import (
-	"strings"
-	"testing"
-)
-
-func TestParseHost(t *testing.T) {
-	var (
-		defaultHttpHost = "127.0.0.1"
-		defaultUnix     = "/var/run/docker.sock"
-	)
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil {
-		t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil {
-		t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" {
-		t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" {
-		t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" {
-		t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil {
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil {
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
-	}
-}
-
-func TestParseRepositoryTag(t *testing.T) {
-	if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag)
-	}
-	if repo, digest := ParseRepositoryTag("root@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "root" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {
-		t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "root", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest)
-	}
-	if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag)
-	}
-	if repo, digest := ParseRepositoryTag("user/repo@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "user/repo" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {
-		t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "user/repo", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest)
-	}
-	if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag)
-	}
-	if repo, digest := ParseRepositoryTag("url:5000/repo@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); repo != "url:5000/repo" || digest != "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {
-		t.Errorf("Expected repo: '%s' and digest: '%s', got '%s' and '%s'", "url:5000/repo", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", repo, digest)
-	}
-}
-
-func TestParsePortMapping(t *testing.T) {
-	data, err := PartParser("ip:public:private", "192.168.1.1:80:8080")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if len(data) != 3 {
-		t.FailNow()
-	}
-	if data["ip"] != "192.168.1.1" {
-		t.Fail()
-	}
-	if data["public"] != "80" {
-		t.Fail()
-	}
-	if data["private"] != "8080" {
-		t.Fail()
-	}
-}
-
-func TestParsePortRange(t *testing.T) {
-	if start, end, err := ParsePortRange("8000-8080"); err != nil || start != 8000 || end != 8080 {
-		t.Fatalf("Error: %s or Expecting {start,end} values {8000,8080} but found {%d,%d}.", err, start, end)
-	}
-}
-
-func TestParsePortRangeIncorrectRange(t *testing.T) {
-	if _, _, err := ParsePortRange("9000-8080"); err == nil || !strings.Contains(err.Error(), "Invalid range specified for the Port") {
-		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
-	}
-}
-
-func TestParsePortRangeIncorrectEndRange(t *testing.T) {
-	if _, _, err := ParsePortRange("8000-a"); err == nil || !strings.Contains(err.Error(), "invalid syntax") {
-		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
-	}
-
-	if _, _, err := ParsePortRange("8000-30a"); err == nil || !strings.Contains(err.Error(), "invalid syntax") {
-		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
-	}
-}
-
-func TestParsePortRangeIncorrectStartRange(t *testing.T) {
-	if _, _, err := ParsePortRange("a-8000"); err == nil || !strings.Contains(err.Error(), "invalid syntax") {
-		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
-	}
-
-	if _, _, err := ParsePortRange("30a-8000"); err == nil || !strings.Contains(err.Error(), "invalid syntax") {
-		t.Fatalf("Expecting error 'Invalid range specified for the Port' but received %s.", err)
-	}
-}
-
-func TestParseLink(t *testing.T) {
-	name, alias, err := ParseLink("name:alias")
-	if err != nil {
-		t.Fatalf("Expected not to error out on a valid name:alias format but got: %v", err)
-	}
-	if name != "name" {
-		t.Fatalf("Link name should have been name, got %s instead", name)
-	}
-	if alias != "alias" {
-		t.Fatalf("Link alias should have been alias, got %s instead", alias)
-	}
-	// short format definition
-	name, alias, err = ParseLink("name")
-	if err != nil {
-		t.Fatalf("Expected not to error out on a valid name only format but got: %v", err)
-	}
-	if name != "name" {
-		t.Fatalf("Link name should have been name, got %s instead", name)
-	}
-	if alias != "name" {
-		t.Fatalf("Link alias should have been name, got %s instead", alias)
-	}
-	// empty string link definition is not allowed
-	if _, _, err := ParseLink(""); err == nil || !strings.Contains(err.Error(), "empty string specified for links") {
-		t.Fatalf("Expected error 'empty string specified for links' but got: %v", err)
-	}
-	// more than two colons are not allowed
-	if _, _, err := ParseLink("link:alias:wrong"); err == nil || !strings.Contains(err.Error(), "bad format for links: link:alias:wrong") {
-		t.Fatalf("Expected error 'bad format for links: link:alias:wrong' but got: %v", err)
-	}
-}

+ 60 - 21
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"net/http"
 	"strings"
@@ -19,15 +20,6 @@ const (
 	defaultTimeOut  = 30
 )
 
-type remoteError struct {
-	method string
-	err    string
-}
-
-func (e *remoteError) Error() string {
-	return fmt.Sprintf("Plugin Error: %s, %s", e.err, e.method)
-}
-
 // NewClient creates a new plugin client (http).
 func NewClient(addr string, tlsConfig tlsconfig.Options) (*Client, error) {
 	tr := &http.Transport{}
@@ -58,19 +50,53 @@ type Client struct {
 // Call calls the specified method with the specified arguments for the plugin.
 // It will retry for 30 seconds if a failure occurs when calling.
 func (c *Client) Call(serviceMethod string, args interface{}, ret interface{}) error {
-	return c.callWithRetry(serviceMethod, args, ret, true)
+	var buf bytes.Buffer
+	if args != nil {
+		if err := json.NewEncoder(&buf).Encode(args); err != nil {
+			return err
+		}
+	}
+	body, err := c.callWithRetry(serviceMethod, &buf, true)
+	if err != nil {
+		return err
+	}
+	defer body.Close()
+	if ret != nil {
+		if err := json.NewDecoder(body).Decode(&ret); err != nil {
+			logrus.Errorf("%s: error reading plugin resp: %v", serviceMethod, err)
+			return err
+		}
+	}
+	return nil
 }
 
-func (c *Client) callWithRetry(serviceMethod string, args interface{}, ret interface{}, retry bool) error {
+// Stream calls the specified method with the specified arguments for the plugin and returns the response body
+func (c *Client) Stream(serviceMethod string, args interface{}) (io.ReadCloser, error) {
 	var buf bytes.Buffer
 	if err := json.NewEncoder(&buf).Encode(args); err != nil {
-		return err
+		return nil, err
 	}
+	return c.callWithRetry(serviceMethod, &buf, true)
+}
 
-	req, err := http.NewRequest("POST", "/"+serviceMethod, &buf)
+// SendFile calls the specified method, and passes through the IO stream
+func (c *Client) SendFile(serviceMethod string, data io.Reader, ret interface{}) error {
+	body, err := c.callWithRetry(serviceMethod, data, true)
 	if err != nil {
 		return err
 	}
+	if err := json.NewDecoder(body).Decode(&ret); err != nil {
+		logrus.Errorf("%s: error reading plugin resp: %v", serviceMethod, err)
+		return err
+	}
+	return nil
+}
+
+func (c *Client) callWithRetry(serviceMethod string, data io.Reader, retry bool) (io.ReadCloser, error) {
+	req, err := http.NewRequest("POST", "/"+serviceMethod, data)
+	if err != nil {
+		return nil, err
+	}
 	req.Header.Add("Accept", versionMimetype)
 	req.URL.Scheme = c.scheme
 	req.URL.Host = c.addr
@@ -82,12 +108,12 @@ func (c *Client) callWithRetry(serviceMethod string, args interface{}, ret inter
 		resp, err := c.http.Do(req)
 		if err != nil {
 			if !retry {
-				return err
+				return nil, err
 			}
 
 			timeOff := backoff(retries)
 			if abort(start, timeOff) {
-				return err
+				return nil, err
 			}
 			retries++
 			logrus.Warnf("Unable to connect to plugin: %s, retrying in %v", c.addr, timeOff)
@@ -95,16 +121,29 @@ func (c *Client) callWithRetry(serviceMethod string, args interface{}, ret inter
 			continue
 		}
 
-		defer resp.Body.Close()
 		if resp.StatusCode != http.StatusOK {
-			remoteErr, err := ioutil.ReadAll(resp.Body)
+			b, err := ioutil.ReadAll(resp.Body)
 			if err != nil {
-				return &remoteError{err.Error(), serviceMethod}
+				return nil, fmt.Errorf("%s: %s", serviceMethod, err)
 			}
-			return &remoteError{string(remoteErr), serviceMethod}
-		}
 
-		return json.NewDecoder(resp.Body).Decode(&ret)
+			// Plugins' Response(s) should have an Err field indicating what went
+			// wrong. Try to unmarshal into ResponseErr. Otherwise fallback to just
+			// return the string(body)
+			type responseErr struct {
+				Err string
+			}
+			remoteErr := responseErr{}
+			if err := json.Unmarshal(b, &remoteErr); err != nil {
+				return nil, fmt.Errorf("%s: %s", serviceMethod, err)
+			}
+			if remoteErr.Err != "" {
+				return nil, fmt.Errorf("%s: %s", serviceMethod, remoteErr.Err)
+			}
+			// old way...
+			return nil, fmt.Errorf("%s: %s", serviceMethod, string(b))
+		}
+		return resp.Body, nil
 	}
 }
 

部分文件因为文件数量过多而无法显示