Browse Source

Merge pull request #1437 from mrjana/agent

Move engine-api to docker/docker/api
Santhosh Manohar 8 years ago
parent
commit
146551e922
59 changed files with 3164 additions and 453 deletions
  1. 56 47
      libnetwork/Godeps/Godeps.json
  2. 307 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/filters/parse.go
  3. 0 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/network/network.go
  4. 14 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/README.md
  5. 62 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/compare.go
  6. 8 5
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts.go
  7. 5 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/ip.go
  8. 49 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts.go
  9. 4 4
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/backends.go
  10. 4 4
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv.go
  11. 2 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe.go
  12. 10 3
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/fswriters.go
  13. 9 12
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/multireader.go
  14. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
  15. 106 49
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go
  16. 0 26
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go
  17. 56 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go
  18. 45 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go
  19. 2 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_windows.go
  20. 8 6
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go
  21. 4 5
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery.go
  22. 5 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_unix.go
  23. 8 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_windows.go
  24. 27 10
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/plugins.go
  25. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_linux.go
  26. 2 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_unix.go
  27. 2 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_unsupported.go
  28. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_windows.go
  29. 41 7
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/signal/trap.go
  30. 3 5
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/stringid/stringid.go
  31. 32 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_darwin.go
  32. 1 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_unsupported.go
  33. 0 8
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go
  34. 2 2
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_unsupported.go
  35. 19 5
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go
  36. 75 146
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go
  37. 5 1
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/ansi_reader.go
  38. 5 17
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/ansi_writer.go
  39. 0 62
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/console.go
  40. 28 0
      libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/windows.go
  41. 8 0
      libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/.travis.yml
  42. 47 0
      libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/README.md
  43. 134 0
      libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/shellwords.go
  44. 19 0
      libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_posix.go
  45. 17 0
      libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_windows.go
  46. 1 1
      libnetwork/client/client.go
  47. 27 0
      libnetwork/client/mflag/LICENSE
  48. 40 0
      libnetwork/client/mflag/README.md
  49. 36 0
      libnetwork/client/mflag/example/example.go
  50. 1280 0
      libnetwork/client/mflag/flag.go
  51. 529 0
      libnetwork/client/mflag/flag_test.go
  52. 1 1
      libnetwork/client/network.go
  53. 1 1
      libnetwork/client/service.go
  54. 1 1
      libnetwork/cluster/provider.go
  55. 1 1
      libnetwork/cmd/dnet/dnet.go
  56. 1 1
      libnetwork/cmd/dnet/dnet_linux.go
  57. 1 1
      libnetwork/cmd/dnet/dnet_windows.go
  58. 7 7
      libnetwork/drivers/remote/driver_test.go
  59. 4 4
      libnetwork/ipams/remote/remote_test.go

+ 56 - 47
libnetwork/Godeps/Godeps.json

@@ -1,7 +1,6 @@
 {
 	"ImportPath": "github.com/docker/libnetwork",
 	"GoVersion": "go1.5",
-	"GodepVersion": "v74",
 	"Packages": [
 		"./..."
 	],
@@ -81,105 +80,110 @@
 			"Comment": "v1-26-gef32fa3",
 			"Rev": "ef32fa3046d9f249d399f98ebaf9be944430fd1d"
 		},
+		{
+			"ImportPath": "github.com/docker/docker/api/types/filters",
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
+		},
+		{
+			"ImportPath": "github.com/docker/docker/api/types/network",
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
+		},
+		{
+			"ImportPath": "github.com/docker/docker/api/types/versions",
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
+		},
 		{
 			"ImportPath": "github.com/docker/docker/opts",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/discovery",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/discovery/kv",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/homedir",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/ioutils",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/longpath",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
-		},
-		{
-			"ImportPath": "github.com/docker/docker/pkg/mflag",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/mount",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/parsers/kernel",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/plugins",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/plugins/transport",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/random",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/reexec",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/signal",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/stringid",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/symlink",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/system",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/term",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/docker/pkg/term/windows",
-			"Comment": "v1.4.1-12227-g86a7632",
-			"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
-		},
-		{
-			"ImportPath": "github.com/docker/engine-api/types/network",
-			"Comment": "v0.3.1-210-g25941ec",
-			"Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba"
+			"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
+			"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
 		},
 		{
 			"ImportPath": "github.com/docker/go-connections/sockets",
@@ -289,6 +293,11 @@
 			"Comment": "v0.7.0-47-g598c548",
 			"Rev": "598c54895cc5a7b1a24a398d635e8c0ea0959870"
 		},
+		{
+			"ImportPath": "github.com/mattn/go-shellwords",
+			"Comment": "v1.0.0-1-g525bede",
+			"Rev": "525bedee691b5a8df547cb5cf9f86b7fb1883e24"
+		},
 		{
 			"ImportPath": "github.com/miekg/dns",
 			"Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02"

+ 307 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/filters/parse.go

@@ -0,0 +1,307 @@
+// Package filters provides helper function to parse and handle command line
+// filter, used for example in docker ps or docker images commands.
+package filters
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"regexp"
+	"strings"
+
+	"github.com/docker/docker/api/types/versions"
+)
+
+// Args stores filter arguments as map key:{map key: bool}.
+// It contains an aggregation of the map of arguments (which are in the form
+// of -f 'key=value') based on the key, and stores values for the same key
+// in a map with string keys and boolean values.
+// e.g given -f 'label=label1=1' -f 'label=label2=2' -f 'image.name=ubuntu'
+// the args will be {"image.name":{"ubuntu":true},"label":{"label1=1":true,"label2=2":true}}
+type Args struct {
+	fields map[string]map[string]bool
+}
+
+// NewArgs initializes a new Args struct.
+func NewArgs() Args {
+	return Args{fields: map[string]map[string]bool{}}
+}
+
+// ParseFlag parses 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) {
+	filters := prev
+	if len(arg) == 0 {
+		return filters, nil
+	}
+
+	if !strings.Contains(arg, "=") {
+		return filters, ErrBadFormat
+	}
+
+	f := strings.SplitN(arg, "=", 2)
+
+	name := strings.ToLower(strings.TrimSpace(f[0]))
+	value := strings.TrimSpace(f[1])
+
+	filters.Add(name, value)
+
+	return filters, nil
+}
+
+// ErrBadFormat is an error returned in case of bad format for a filter.
+var ErrBadFormat = errors.New("bad format of filter (expected name=value)")
+
+// ToParam packs the Args into a 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 a.Len() == 0 {
+		return "", nil
+	}
+
+	buf, err := json.Marshal(a.fields)
+	if err != nil {
+		return "", err
+	}
+	return string(buf), nil
+}
+
+// ToParamWithVersion packs the Args into a string for easy transport from client to server.
+// The generated string will depend on the specified version (corresponding to the API version).
+func ToParamWithVersion(version string, a Args) (string, error) {
+	// this way we don't URL encode {}, just empty space
+	if a.Len() == 0 {
+		return "", nil
+	}
+
+	// for daemons older than v1.10, filter must be of the form map[string][]string
+	buf := []byte{}
+	err := errors.New("")
+	if version != "" && versions.LessThan(version, "1.22") {
+		buf, err = json.Marshal(convertArgsToSlice(a.fields))
+	} else {
+		buf, err = json.Marshal(a.fields)
+	}
+	if err != nil {
+		return "", err
+	}
+	return string(buf), nil
+}
+
+// FromParam unpacks the filter Args.
+func FromParam(p string) (Args, error) {
+	if len(p) == 0 {
+		return NewArgs(), nil
+	}
+
+	r := strings.NewReader(p)
+	d := json.NewDecoder(r)
+
+	m := map[string]map[string]bool{}
+	if err := d.Decode(&m); err != nil {
+		r.Seek(0, 0)
+
+		// Allow parsing old arguments in slice format.
+		// Because other libraries might be sending them in this format.
+		deprecated := map[string][]string{}
+		if deprecatedErr := d.Decode(&deprecated); deprecatedErr == nil {
+			m = deprecatedArgs(deprecated)
+		} else {
+			return NewArgs(), err
+		}
+	}
+	return Args{m}, nil
+}
+
+// Get returns the list of values associates with a field.
+// It returns a slice of strings to keep backwards compatibility with old code.
+func (filters Args) Get(field string) []string {
+	values := filters.fields[field]
+	if values == nil {
+		return make([]string, 0)
+	}
+	slice := make([]string, 0, len(values))
+	for key := range values {
+		slice = append(slice, key)
+	}
+	return slice
+}
+
+// Add adds a new value to a filter field.
+func (filters Args) Add(name, value string) {
+	if _, ok := filters.fields[name]; ok {
+		filters.fields[name][value] = true
+	} else {
+		filters.fields[name] = map[string]bool{value: true}
+	}
+}
+
+// Del removes a value from a filter field.
+func (filters Args) Del(name, value string) {
+	if _, ok := filters.fields[name]; ok {
+		delete(filters.fields[name], value)
+	}
+}
+
+// Len returns the number of fields in the arguments.
+func (filters Args) Len() int {
+	return len(filters.fields)
+}
+
+// MatchKVList returns true if the values for the specified field matches the ones
+// from the sources.
+// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
+//      field is 'label' and sources are {'label1': '1', 'label2': '2'}
+//      it returns true.
+func (filters Args) MatchKVList(field string, sources map[string]string) bool {
+	fieldValues := filters.fields[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
+	}
+
+	for name2match := range fieldValues {
+		testKV := strings.SplitN(name2match, "=", 2)
+
+		v, ok := sources[testKV[0]]
+		if !ok {
+			return false
+		}
+		if len(testKV) == 2 && testKV[1] != v {
+			return false
+		}
+	}
+
+	return true
+}
+
+// Match returns true if the values for the specified field matches the source string
+// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
+//      field is 'image.name' and source is 'ubuntu'
+//      it returns true.
+func (filters Args) Match(field, source string) bool {
+	if filters.ExactMatch(field, source) {
+		return true
+	}
+
+	fieldValues := filters.fields[field]
+	for name2match := range fieldValues {
+		match, err := regexp.MatchString(name2match, source)
+		if err != nil {
+			continue
+		}
+		if match {
+			return true
+		}
+	}
+	return false
+}
+
+// ExactMatch returns true if the source matches exactly one of the filters.
+func (filters Args) ExactMatch(field, source string) bool {
+	fieldValues, ok := filters.fields[field]
+	//do not filter if there is no filter set or cannot determine filter
+	if !ok || len(fieldValues) == 0 {
+		return true
+	}
+
+	// try to match full name value to avoid O(N) regular expression matching
+	return fieldValues[source]
+}
+
+// UniqueExactMatch returns true if there is only one filter and the source matches exactly this one.
+func (filters Args) UniqueExactMatch(field, source string) bool {
+	fieldValues := filters.fields[field]
+	//do not filter if there is no filter set or cannot determine filter
+	if len(fieldValues) == 0 {
+		return true
+	}
+	if len(filters.fields[field]) != 1 {
+		return false
+	}
+
+	// try to match full name value to avoid O(N) regular expression matching
+	return fieldValues[source]
+}
+
+// FuzzyMatch returns true if the source matches exactly one of the filters,
+// or the source has one of the filters as a prefix.
+func (filters Args) FuzzyMatch(field, source string) bool {
+	if filters.ExactMatch(field, source) {
+		return true
+	}
+
+	fieldValues := filters.fields[field]
+	for prefix := range fieldValues {
+		if strings.HasPrefix(source, prefix) {
+			return true
+		}
+	}
+	return false
+}
+
+// Include returns true if the name of the field to filter is in the filters.
+func (filters Args) Include(field string) bool {
+	_, ok := filters.fields[field]
+	return ok
+}
+
+// Validate ensures that all the fields in the filter are valid.
+// It returns an error as soon as it finds an invalid field.
+func (filters Args) Validate(accepted map[string]bool) error {
+	for name := range filters.fields {
+		if !accepted[name] {
+			return fmt.Errorf("Invalid filter '%s'", name)
+		}
+	}
+	return nil
+}
+
+// WalkValues iterates over the list of filtered values for a field.
+// It stops the iteration if it finds an error and it returns that error.
+func (filters Args) WalkValues(field string, op func(value string) error) error {
+	if _, ok := filters.fields[field]; !ok {
+		return nil
+	}
+	for v := range filters.fields[field] {
+		if err := op(v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
+	m := map[string]map[string]bool{}
+	for k, v := range d {
+		values := map[string]bool{}
+		for _, vv := range v {
+			values[vv] = true
+		}
+		m[k] = values
+	}
+	return m
+}
+
+func convertArgsToSlice(f map[string]map[string]bool) map[string][]string {
+	m := map[string][]string{}
+	for k, v := range f {
+		values := []string{}
+		for kk := range v {
+			if v[kk] {
+				values = append(values, kk)
+			}
+		}
+		m[k] = values
+	}
+	return m
+}

+ 0 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/engine-api/types/network/network.go → libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/network/network.go


+ 14 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/README.md

@@ -0,0 +1,14 @@
+## Legacy API type versions
+
+This package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`.
+
+Consider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`.
+
+### Package name conventions
+
+The package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention:
+
+1. We cannot use `.` because it's interpreted by the language, think of `v1.20.CallFunction`.
+2. We cannot use `_` because golint complains about it. The code is actually valid, but it looks probably more weird: `v1_20.CallFunction`.
+
+For instance, if you want to modify a type that was available in the version `1.21` of the API but it will have different fields in the version `1.22`, you want to create a new package under `api/types/versions/v1p21`.

+ 62 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/compare.go

@@ -0,0 +1,62 @@
+package versions
+
+import (
+	"strconv"
+	"strings"
+)
+
+// compare compares two version strings
+// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise.
+func compare(v1, v2 string) int {
+	var (
+		currTab  = strings.Split(v1, ".")
+		otherTab = strings.Split(v2, ".")
+	)
+
+	max := len(currTab)
+	if len(otherTab) > max {
+		max = len(otherTab)
+	}
+	for i := 0; i < max; i++ {
+		var currInt, otherInt int
+
+		if len(currTab) > i {
+			currInt, _ = strconv.Atoi(currTab[i])
+		}
+		if len(otherTab) > i {
+			otherInt, _ = strconv.Atoi(otherTab[i])
+		}
+		if currInt > otherInt {
+			return 1
+		}
+		if otherInt > currInt {
+			return -1
+		}
+	}
+	return 0
+}
+
+// LessThan checks if a version is less than another
+func LessThan(v, other string) bool {
+	return compare(v, other) == -1
+}
+
+// LessThanOrEqualTo checks if a version is less than or equal to another
+func LessThanOrEqualTo(v, other string) bool {
+	return compare(v, other) <= 0
+}
+
+// GreaterThan checks if a version is greater than another
+func GreaterThan(v, other string) bool {
+	return compare(v, other) == 1
+}
+
+// GreaterThanOrEqualTo checks if a version is greater than or equal to another
+func GreaterThanOrEqualTo(v, other string) bool {
+	return compare(v, other) >= 0
+}
+
+// Equal checks if a version is equal to another
+func Equal(v, other string) bool {
+	return compare(v, other) == 0
+}

+ 8 - 5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/hosts.go

@@ -63,14 +63,14 @@ func ParseHost(defaultToTLS bool, val string) (string, error) {
 // parseDockerDaemonHost parses the specified address and returns an address that will be used as the host.
 // Depending of the address specified, this may return one of the global Default* strings defined in hosts.go.
 func parseDockerDaemonHost(addr string) (string, error) {
-	addrParts := strings.Split(addr, "://")
+	addrParts := strings.SplitN(addr, "://", 2)
 	if len(addrParts) == 1 && addrParts[0] != "" {
 		addrParts = []string{"tcp", addrParts[0]}
 	}
 
 	switch addrParts[0] {
 	case "tcp":
-		return parseTCPAddr(addrParts[1], DefaultTCPHost)
+		return ParseTCPAddr(addrParts[1], DefaultTCPHost)
 	case "unix":
 		return parseSimpleProtoAddr("unix", addrParts[1], DefaultUnixSocket)
 	case "npipe":
@@ -97,12 +97,12 @@ func parseSimpleProtoAddr(proto, addr, defaultAddr string) (string, error) {
 	return fmt.Sprintf("%s://%s", proto, addr), nil
 }
 
-// parseTCPAddr parses and validates that the specified address is a valid TCP
+// 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) {
+func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
 	if tryAddr == "" || tryAddr == "tcp://" {
 		return defaultAddr, nil
 	}
@@ -127,8 +127,11 @@ func parseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-
 	host, port, err := net.SplitHostPort(u.Host)
+	if err != nil {
+		// try port addition once
+		host, port, err = net.SplitHostPort(net.JoinHostPort(u.Host, defaultPort))
+	}
 	if err != nil {
 		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
 	}

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

@@ -40,3 +40,8 @@ func (o *IPOpt) String() string {
 	}
 	return o.IP.String()
 }
+
+// Type returns the type of the option
+func (o *IPOpt) Type() string {
+	return "ip"
+}

+ 49 - 2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/opts/opts.go

@@ -5,6 +5,8 @@ import (
 	"net"
 	"regexp"
 	"strings"
+
+	"github.com/docker/docker/api/types/filters"
 )
 
 var (
@@ -100,6 +102,11 @@ func (opts *ListOpts) Len() int {
 	return len((*opts.values))
 }
 
+// Type returns a string name for this Option type
+func (opts *ListOpts) Type() string {
+	return "list"
+}
+
 // NamedOption is an interface that list and map options
 // with names implement.
 type NamedOption interface {
@@ -129,7 +136,7 @@ func (o *NamedListOpts) Name() string {
 	return o.name
 }
 
-//MapOpts holds a map of values and a validation function.
+// MapOpts holds a map of values and a validation function.
 type MapOpts struct {
 	values    map[string]string
 	validator ValidatorFctType
@@ -163,6 +170,11 @@ func (opts *MapOpts) String() string {
 	return fmt.Sprintf("%v", map[string]string((opts.values)))
 }
 
+// Type returns a string name for this Option type
+func (opts *MapOpts) Type() string {
+	return "map"
+}
+
 // 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 {
@@ -241,7 +253,7 @@ func ValidateLabel(val string) (string, error) {
 	return val, nil
 }
 
-// ValidateSysctl validates an sysctl and returns it.
+// ValidateSysctl validates a sysctl and returns it.
 func ValidateSysctl(val string) (string, error) {
 	validSysctlMap := map[string]bool{
 		"kernel.msgmax":          true,
@@ -272,3 +284,38 @@ func ValidateSysctl(val string) (string, error) {
 	}
 	return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
 }
+
+// FilterOpt is a flag type for validating filters
+type FilterOpt struct {
+	filter filters.Args
+}
+
+// NewFilterOpt returns a new FilterOpt
+func NewFilterOpt() FilterOpt {
+	return FilterOpt{filter: filters.NewArgs()}
+}
+
+func (o *FilterOpt) String() string {
+	repr, err := filters.ToParam(o.filter)
+	if err != nil {
+		return "invalid filters"
+	}
+	return repr
+}
+
+// Set sets the value of the opt by parsing the command line value
+func (o *FilterOpt) Set(value string) error {
+	var err error
+	o.filter, err = filters.ParseFlag(value, o.filter)
+	return err
+}
+
+// Type returns the option type
+func (o *FilterOpt) Type() string {
+	return "filter"
+}
+
+// Value returns the value of this option
+func (o *FilterOpt) Value() filters.Args {
+	return o.filter
+}

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

@@ -6,7 +6,7 @@ import (
 	"strings"
 	"time"
 
-	log "github.com/Sirupsen/logrus"
+	"github.com/Sirupsen/logrus"
 )
 
 var (
@@ -21,7 +21,7 @@ func Register(scheme string, d Backend) error {
 	if _, exists := backends[scheme]; exists {
 		return fmt.Errorf("scheme already registered %s", scheme)
 	}
-	log.WithField("name", scheme).Debug("Registering discovery service")
+	logrus.WithField("name", scheme).Debugf("Registering discovery service")
 	backends[scheme] = d
 	return nil
 }
@@ -57,7 +57,7 @@ func ParseAdvertise(advertise string) (string, error) {
 		return advertise, nil
 	}
 
-	// If advertise is a valid interface name, get the valid ipv4 address and use it to advertise
+	// 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 {
@@ -98,7 +98,7 @@ func ParseAdvertise(advertise string) (string, 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")
+		logrus.WithFields(logrus.Fields{"name": scheme, "uri": uri}).Debugf("Initializing discovery service")
 		err := backend.Initialize(uri, heartbeat, ttl, clusterOpts)
 		return backend, err
 	}

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

@@ -6,7 +6,7 @@ import (
 	"strings"
 	"time"
 
-	log "github.com/Sirupsen/logrus"
+	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/libkv"
@@ -73,7 +73,7 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
 
 	var config *store.Config
 	if clusterOpts["kv.cacertfile"] != "" && clusterOpts["kv.certfile"] != "" && clusterOpts["kv.keyfile"] != "" {
-		log.Info("Initializing discovery with TLS")
+		logrus.Infof("Initializing discovery with TLS")
 		tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
 			CAFile:   clusterOpts["kv.cacertfile"],
 			CertFile: clusterOpts["kv.certfile"],
@@ -93,7 +93,7 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
 			TLS: tlsConfig,
 		}
 	} else {
-		log.Info("Initializing discovery without TLS")
+		logrus.Infof("Initializing discovery without TLS")
 	}
 
 	// Creates a new store, will ignore options given
@@ -112,7 +112,7 @@ func (s *Discovery) watchOnce(stopCh <-chan struct{}, watchCh <-chan []*store.KV
 				return true
 			}
 
-			log.WithField("discovery", s.backend).Debugf("Watch triggered with %d nodes", len(pairs))
+			logrus.WithField("discovery", s.backend).Debugf("Watch triggered with %d nodes", len(pairs))
 
 			// Convert `KVPair` into `discovery.Entry`.
 			addrs := make([]string, len(pairs))

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

@@ -133,8 +133,9 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) {
 		}
 		bp.wait.Wait()
 		if bp.bufLen == 0 && bp.closeErr != nil {
+			err := bp.closeErr
 			bp.mu.Unlock()
-			return 0, bp.closeErr
+			return 0, err
 		}
 	}
 

+ 10 - 3
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/fswriters.go

@@ -15,13 +15,15 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
 	if err != nil {
 		return nil, err
 	}
+
 	abspath, err := filepath.Abs(filename)
 	if err != nil {
 		return nil, err
 	}
 	return &atomicFileWriter{
-		f:  f,
-		fn: abspath,
+		f:    f,
+		fn:   abspath,
+		perm: perm,
 	}, nil
 }
 
@@ -34,6 +36,7 @@ func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
 	n, err := f.Write(data)
 	if err == nil && n < len(data) {
 		err = io.ErrShortWrite
+		f.(*atomicFileWriter).writeErr = err
 	}
 	if err1 := f.Close(); err == nil {
 		err = err1
@@ -45,6 +48,7 @@ type atomicFileWriter struct {
 	f        *os.File
 	fn       string
 	writeErr error
+	perm     os.FileMode
 }
 
 func (w *atomicFileWriter) Write(dt []byte) (int, error) {
@@ -57,7 +61,7 @@ func (w *atomicFileWriter) Write(dt []byte) (int, error) {
 
 func (w *atomicFileWriter) Close() (retErr error) {
 	defer func() {
-		if retErr != nil {
+		if retErr != nil || w.writeErr != nil {
 			os.Remove(w.f.Name())
 		}
 	}()
@@ -68,6 +72,9 @@ func (w *atomicFileWriter) Close() (retErr error) {
 	if err := w.f.Close(); err != nil {
 		return err
 	}
+	if err := os.Chmod(w.f.Name(), w.perm); err != nil {
+		return err
+	}
 	if w.writeErr == nil {
 		return os.Rename(w.f.Name(), w.fn)
 	}

+ 9 - 12
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/multireader.go

@@ -97,27 +97,24 @@ func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) {
 }
 
 func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, int64, error) {
-	var rdr io.ReadSeeker
-	var rdrOffset int64
 
-	for i, rdr := range r.readers {
-		offsetTo, err := r.getOffsetToReader(rdr)
+	var offsetTo int64
+
+	for _, rdr := range r.readers {
+		size, err := getReadSeekerSize(rdr)
 		if err != nil {
 			return nil, -1, err
 		}
-		if offsetTo > offset {
-			rdr = r.readers[i-1]
-			rdrOffset = offsetTo - offset
-			break
+		if offsetTo+size > offset {
+			return rdr, offset - offsetTo, nil
 		}
-
 		if rdr == r.readers[len(r.readers)-1] {
-			rdrOffset = offsetTo + offset
-			break
+			return rdr, offsetTo + offset, nil
 		}
+		offsetTo += size
 	}
 
-	return rdr, rdrOffset, nil
+	return nil, 0, nil
 }
 
 func (r *multiReadSeeker) getCurOffset() (int64, error) {

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

@@ -55,7 +55,7 @@ func HashData(src io.Reader) (string, error) {
 	return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
 }
 
-// OnEOFReader wraps a io.ReadCloser and a function
+// OnEOFReader wraps an io.ReadCloser and a function
 // the function will run at the end of file or close the file.
 type OnEOFReader struct {
 	Rc io.ReadCloser

+ 106 - 49
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/mount/flags.go

@@ -5,6 +5,112 @@ import (
 	"strings"
 )
 
+var flags = map[string]struct {
+	clear bool
+	flag  int
+}{
+	"defaults":      {false, 0},
+	"ro":            {false, RDONLY},
+	"rw":            {true, RDONLY},
+	"suid":          {true, NOSUID},
+	"nosuid":        {false, NOSUID},
+	"dev":           {true, NODEV},
+	"nodev":         {false, NODEV},
+	"exec":          {true, NOEXEC},
+	"noexec":        {false, NOEXEC},
+	"sync":          {false, SYNCHRONOUS},
+	"async":         {true, SYNCHRONOUS},
+	"dirsync":       {false, DIRSYNC},
+	"remount":       {false, REMOUNT},
+	"mand":          {false, MANDLOCK},
+	"nomand":        {true, MANDLOCK},
+	"atime":         {true, NOATIME},
+	"noatime":       {false, NOATIME},
+	"diratime":      {true, NODIRATIME},
+	"nodiratime":    {false, NODIRATIME},
+	"bind":          {false, BIND},
+	"rbind":         {false, RBIND},
+	"unbindable":    {false, UNBINDABLE},
+	"runbindable":   {false, RUNBINDABLE},
+	"private":       {false, PRIVATE},
+	"rprivate":      {false, RPRIVATE},
+	"shared":        {false, SHARED},
+	"rshared":       {false, RSHARED},
+	"slave":         {false, SLAVE},
+	"rslave":        {false, RSLAVE},
+	"relatime":      {false, RELATIME},
+	"norelatime":    {true, RELATIME},
+	"strictatime":   {false, STRICTATIME},
+	"nostrictatime": {true, STRICTATIME},
+}
+
+var validFlags = map[string]bool{
+	"":          true,
+	"size":      true,
+	"mode":      true,
+	"uid":       true,
+	"gid":       true,
+	"nr_inodes": true,
+	"nr_blocks": true,
+	"mpol":      true,
+}
+
+var propagationFlags = map[string]bool{
+	"bind":        true,
+	"rbind":       true,
+	"unbindable":  true,
+	"runbindable": true,
+	"private":     true,
+	"rprivate":    true,
+	"shared":      true,
+	"rshared":     true,
+	"slave":       true,
+	"rslave":      true,
+}
+
+// MergeTmpfsOptions merge mount options to make sure there is no duplicate.
+func MergeTmpfsOptions(options []string) ([]string, error) {
+	// We use collisions maps to remove duplicates.
+	// For flag, the key is the flag value (the key for propagation flag is -1)
+	// For data=value, the key is the data
+	flagCollisions := map[int]bool{}
+	dataCollisions := map[string]bool{}
+
+	var newOptions []string
+	// We process in reverse order
+	for i := len(options) - 1; i >= 0; i-- {
+		option := options[i]
+		if option == "defaults" {
+			continue
+		}
+		if f, ok := flags[option]; ok && f.flag != 0 {
+			// There is only one propagation mode
+			key := f.flag
+			if propagationFlags[option] {
+				key = -1
+			}
+			// Check to see if there is collision for flag
+			if !flagCollisions[key] {
+				// We prepend the option and add to collision map
+				newOptions = append([]string{option}, newOptions...)
+				flagCollisions[key] = true
+			}
+			continue
+		}
+		opt := strings.SplitN(option, "=", 2)
+		if len(opt) != 2 || !validFlags[opt[0]] {
+			return nil, fmt.Errorf("Invalid tmpfs option %q", opt)
+		}
+		if !dataCollisions[opt[0]] {
+			// We prepend the option and add to collision map
+			newOptions = append([]string{option}, newOptions...)
+			dataCollisions[opt[0]] = true
+		}
+	}
+
+	return newOptions, nil
+}
+
 // Parse fstab type mount options into mount() flags
 // and device specific data
 func parseOptions(options string) (int, string) {
@@ -13,45 +119,6 @@ func parseOptions(options string) (int, string) {
 		data []string
 	)
 
-	flags := map[string]struct {
-		clear bool
-		flag  int
-	}{
-		"defaults":      {false, 0},
-		"ro":            {false, RDONLY},
-		"rw":            {true, RDONLY},
-		"suid":          {true, NOSUID},
-		"nosuid":        {false, NOSUID},
-		"dev":           {true, NODEV},
-		"nodev":         {false, NODEV},
-		"exec":          {true, NOEXEC},
-		"noexec":        {false, NOEXEC},
-		"sync":          {false, SYNCHRONOUS},
-		"async":         {true, SYNCHRONOUS},
-		"dirsync":       {false, DIRSYNC},
-		"remount":       {false, REMOUNT},
-		"mand":          {false, MANDLOCK},
-		"nomand":        {true, MANDLOCK},
-		"atime":         {true, NOATIME},
-		"noatime":       {false, NOATIME},
-		"diratime":      {true, NODIRATIME},
-		"nodiratime":    {false, NODIRATIME},
-		"bind":          {false, BIND},
-		"rbind":         {false, RBIND},
-		"unbindable":    {false, UNBINDABLE},
-		"runbindable":   {false, RUNBINDABLE},
-		"private":       {false, PRIVATE},
-		"rprivate":      {false, RPRIVATE},
-		"shared":        {false, SHARED},
-		"rshared":       {false, RSHARED},
-		"slave":         {false, SLAVE},
-		"rslave":        {false, RSLAVE},
-		"relatime":      {false, RELATIME},
-		"norelatime":    {true, RELATIME},
-		"strictatime":   {false, STRICTATIME},
-		"nostrictatime": {true, STRICTATIME},
-	}
-
 	for _, o := range strings.Split(options, ",") {
 		// If the option does not exist in the flags table or the flag
 		// is not supported on the platform,
@@ -72,16 +139,6 @@ func parseOptions(options string) (int, string) {
 // 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]] {

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

@@ -5,7 +5,6 @@
 package kernel
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 )
@@ -46,31 +45,6 @@ func CompareKernelVersion(a, b VersionInfo) int {
 	return 0
 }
 
-// GetKernelVersion gets the current kernel version.
-func GetKernelVersion() (*VersionInfo, error) {
-	var (
-		err error
-	)
-
-	uts, err := uname()
-	if err != nil {
-		return nil, err
-	}
-
-	release := make([]byte, len(uts.Release))
-
-	i := 0
-	for _, c := range uts.Release {
-		release[i] = byte(c)
-		i++
-	}
-
-	// Remove the \x00 from the release for Atoi to parse correctly
-	release = release[:bytes.IndexByte(release, 0)]
-
-	return ParseRelease(string(release))
-}
-
 // ParseRelease parses a string and creates a VersionInfo based on it.
 func ParseRelease(release string) (*VersionInfo, error) {
 	var (

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

@@ -0,0 +1,56 @@
+// +build darwin
+
+// Package kernel provides helper function to get, parse and compare kernel
+// versions for different platforms.
+package kernel
+
+import (
+	"fmt"
+	"os/exec"
+	"strings"
+
+	"github.com/mattn/go-shellwords"
+)
+
+// GetKernelVersion gets the current kernel version.
+func GetKernelVersion() (*VersionInfo, error) {
+	release, err := getRelease()
+	if err != nil {
+		return nil, err
+	}
+
+	return ParseRelease(release)
+}
+
+// getRelease uses `system_profiler SPSoftwareDataType` to get OSX kernel version
+func getRelease() (string, error) {
+	cmd := exec.Command("system_profiler", "SPSoftwareDataType")
+	osName, err := cmd.Output()
+	if err != nil {
+		return "", err
+	}
+
+	var release string
+	data := strings.Split(string(osName), "\n")
+	for _, line := range data {
+		if strings.Contains(line, "Kernel Version") {
+			// It has the format like '      Kernel Version: Darwin 14.5.0'
+			content := strings.SplitN(line, ":", 2)
+			if len(content) != 2 {
+				return "", fmt.Errorf("Kernel Version is invalid")
+			}
+
+			prettyNames, err := shellwords.Parse(content[1])
+			if err != nil {
+				return "", fmt.Errorf("Kernel Version is invalid: %s", err.Error())
+			}
+
+			if len(prettyNames) != 2 {
+				return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ")
+			}
+			release = prettyNames[1]
+		}
+	}
+
+	return release, nil
+}

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

@@ -0,0 +1,45 @@
+// +build linux freebsd solaris
+
+// Package kernel provides helper function to get, parse and compare kernel
+// versions for different platforms.
+package kernel
+
+import (
+	"bytes"
+
+	"github.com/Sirupsen/logrus"
+)
+
+// GetKernelVersion gets the current kernel version.
+func GetKernelVersion() (*VersionInfo, error) {
+	uts, err := uname()
+	if err != nil {
+		return nil, err
+	}
+
+	release := make([]byte, len(uts.Release))
+
+	i := 0
+	for _, c := range uts.Release {
+		release[i] = byte(c)
+		i++
+	}
+
+	// Remove the \x00 from the release for Atoi to parse correctly
+	release = release[:bytes.IndexByte(release, 0)]
+
+	return ParseRelease(string(release))
+}
+
+// CheckKernelVersion checks if current kernel is newer than (or equal to)
+// the given version.
+func CheckKernelVersion(k, major, minor int) bool {
+	if v, err := GetKernelVersion(); err != nil {
+		logrus.Warnf("error getting kernel version: %s", err)
+	} else {
+		if CompareKernelVersion(*v, VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 {
+			return false
+		}
+	}
+	return true
+}

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

@@ -1,3 +1,5 @@
+// +build windows
+
 package kernel
 
 import (

+ 8 - 6
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go

@@ -20,14 +20,16 @@ const (
 )
 
 // NewClient creates a new plugin client (http).
-func NewClient(addr string, tlsConfig tlsconfig.Options) (*Client, error) {
+func NewClient(addr string, tlsConfig *tlsconfig.Options) (*Client, error) {
 	tr := &http.Transport{}
 
-	c, err := tlsconfig.Client(tlsConfig)
-	if err != nil {
-		return nil, err
+	if tlsConfig != nil {
+		c, err := tlsconfig.Client(*tlsConfig)
+		if err != nil {
+			return nil, err
+		}
+		tr.TLSClientConfig = c
 	}
-	tr.TLSClientConfig = c
 
 	u, err := url.Parse(addr)
 	if err != nil {
@@ -130,7 +132,7 @@ func (c *Client) callWithRetry(serviceMethod string, data io.Reader, retry bool)
 				return nil, err
 			}
 			retries++
-			logrus.Warnf("Unable to connect to plugin: %s:%s, retrying in %v", req.URL.Host, req.URL.Path, timeOff)
+			logrus.Warnf("Unable to connect to plugin: %s%s: %v, retrying in %v", req.URL.Host, req.URL.Path, err, timeOff)
 			time.Sleep(timeOff)
 			continue
 		}

+ 4 - 5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery.go

@@ -16,7 +16,6 @@ var (
 	// ErrNotFound plugin not found
 	ErrNotFound = errors.New("plugin not found")
 	socketsPath = "/run/docker/plugins"
-	specsPaths  = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
 )
 
 // localRegistry defines a registry that is local (using unix socket).
@@ -64,7 +63,7 @@ func (l *localRegistry) Plugin(name string) (*Plugin, error) {
 
 	for _, p := range socketpaths {
 		if fi, err := os.Stat(p); err == nil && fi.Mode()&os.ModeSocket != 0 {
-			return newLocalPlugin(name, "unix://"+p), nil
+			return NewLocalPlugin(name, "unix://"+p), nil
 		}
 	}
 
@@ -101,7 +100,7 @@ func readPluginInfo(name, path string) (*Plugin, error) {
 		return nil, fmt.Errorf("Unknown protocol")
 	}
 
-	return newLocalPlugin(name, addr), nil
+	return NewLocalPlugin(name, addr), nil
 }
 
 func readPluginJSONInfo(name, path string) (*Plugin, error) {
@@ -115,8 +114,8 @@ func readPluginJSONInfo(name, path string) (*Plugin, error) {
 	if err := json.NewDecoder(f).Decode(&p); err != nil {
 		return nil, err
 	}
-	p.Name = name
-	if len(p.TLSConfig.CAFile) == 0 {
+	p.name = name
+	if p.TLSConfig != nil && len(p.TLSConfig.CAFile) == 0 {
 		p.TLSConfig.InsecureSkipVerify = true
 	}
 	p.activateWait = sync.NewCond(&sync.Mutex{})

+ 5 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_unix.go

@@ -0,0 +1,5 @@
+// +build !windows
+
+package plugins
+
+var specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}

+ 8 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_windows.go

@@ -0,0 +1,8 @@
+package plugins
+
+import (
+	"os"
+	"path/filepath"
+)
+
+var specsPaths = []string{filepath.Join(os.Getenv("programdata"), "docker", "plugins")}

+ 27 - 10
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/plugins.go

@@ -55,13 +55,13 @@ type Manifest struct {
 // Plugin is the definition of a docker plugin.
 type Plugin struct {
 	// Name of the plugin
-	Name string `json:"-"`
+	name string
 	// Address of the plugin
 	Addr string
 	// TLS configuration of the plugin
-	TLSConfig tlsconfig.Options
+	TLSConfig *tlsconfig.Options
 	// Client attached to the plugin
-	Client *Client `json:"-"`
+	client *Client
 	// Manifest of the plugin (see above)
 	Manifest *Manifest `json:"-"`
 
@@ -73,11 +73,28 @@ type Plugin struct {
 	activateWait *sync.Cond
 }
 
-func newLocalPlugin(name, addr string) *Plugin {
+// Name returns the name of the plugin.
+func (p *Plugin) Name() string {
+	return p.name
+}
+
+// Client returns a ready-to-use plugin client that can be used to communicate with the plugin.
+func (p *Plugin) Client() *Client {
+	return p.client
+}
+
+// IsLegacy returns true for legacy plugins and false otherwise.
+func (p *Plugin) IsLegacy() bool {
+	return true
+}
+
+// NewLocalPlugin creates a new local plugin.
+func NewLocalPlugin(name, addr string) *Plugin {
 	return &Plugin{
-		Name:         name,
-		Addr:         addr,
-		TLSConfig:    tlsconfig.Options{InsecureSkipVerify: true},
+		name: name,
+		Addr: addr,
+		// TODO: change to nil
+		TLSConfig:    &tlsconfig.Options{InsecureSkipVerify: true},
 		activateWait: sync.NewCond(&sync.Mutex{}),
 	}
 }
@@ -102,10 +119,10 @@ func (p *Plugin) activateWithLock() error {
 	if err != nil {
 		return err
 	}
-	p.Client = c
+	p.client = c
 
 	m := new(Manifest)
-	if err = p.Client.Call("Plugin.Activate", nil, m); err != nil {
+	if err = p.client.Call("Plugin.Activate", nil, m); err != nil {
 		return err
 	}
 
@@ -116,7 +133,7 @@ func (p *Plugin) activateWithLock() error {
 		if !handled {
 			continue
 		}
-		handler(p.Name, p.Client)
+		handler(p.name, p.client)
 	}
 	return nil
 }

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_linux.go

@@ -13,7 +13,7 @@ func Self() string {
 	return "/proc/self/exe"
 }
 
-// Command returns *exec.Cmd which have Path as current binary. Also it setting
+// Command returns *exec.Cmd which has Path as current binary. Also it setting
 // SysProcAttr.Pdeathsig to SIGTERM.
 // This will use the in-memory version (/proc/self/exe) of the current binary,
 // it is thus safe to delete or replace the on-disk binary (os.Args[0]).

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

@@ -1,4 +1,4 @@
-// +build freebsd solaris
+// +build freebsd solaris darwin
 
 package reexec
 
@@ -12,7 +12,7 @@ func Self() string {
 	return naiveSelf()
 }
 
-// Command returns *exec.Cmd which have Path as current binary.
+// Command returns *exec.Cmd which has Path as current binary.
 // For example if current binary is "docker" at "/usr/bin/", then cmd.Path will
 // be set to "/usr/bin/docker".
 func Command(args ...string) *exec.Cmd {

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

@@ -1,4 +1,4 @@
-// +build !linux,!windows,!freebsd,!solaris
+// +build !linux,!windows,!freebsd,!solaris,!darwin
 
 package reexec
 
@@ -6,7 +6,7 @@ import (
 	"os/exec"
 )
 
-// Command is unsupported on operating systems apart from Linux and Windows.
+// Command is unsupported on operating systems apart from Linux, Windows, Solaris and Darwin.
 func Command(args ...string) *exec.Cmd {
 	return nil
 }

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_windows.go

@@ -12,7 +12,7 @@ func Self() string {
 	return naiveSelf()
 }
 
-// Command returns *exec.Cmd which have Path as current binary.
+// Command returns *exec.Cmd which has Path as current binary.
 // For example if current binary is "docker.exe" at "C:\", then cmd.Path will
 // be set to "C:\docker.exe".
 func Command(args ...string) *exec.Cmd {

+ 41 - 7
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/signal/trap.go

@@ -3,9 +3,11 @@ package signal
 import (
 	"os"
 	gosignal "os/signal"
+	"path/filepath"
 	"runtime"
 	"sync/atomic"
 	"syscall"
+	"time"
 
 	"github.com/Sirupsen/logrus"
 )
@@ -18,15 +20,22 @@ import (
 // * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is
 //   skipped and the process is terminated immediately (allows force quit of stuck daemon)
 // * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit.
+// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while
+//   the docker daemon is not restarted and also running under systemd.
+//   Fixes https://github.com/docker/docker/issues/19728
 //
 func Trap(cleanup func()) {
 	c := make(chan os.Signal, 1)
-	// we will handle INT, TERM, QUIT here
-	signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}
+	// we will handle INT, TERM, QUIT, SIGPIPE here
+	signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
 	gosignal.Notify(c, signals...)
 	go func() {
 		interruptCount := uint32(0)
 		for sig := range c {
+			if sig == syscall.SIGPIPE {
+				continue
+			}
+
 			go func(sig os.Signal) {
 				logrus.Infof("Processing signal '%v'", sig)
 				switch sig {
@@ -42,11 +51,11 @@ func Trap(cleanup func()) {
 						}
 					} else {
 						// 3 SIGTERM/INT signals received; force exit without cleanup
-						logrus.Infof("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
+						logrus.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
 					}
 				case syscall.SIGQUIT:
-					DumpStacks()
-					logrus.Infof("Forcing docker daemon shutdown without cleanup on SIGQUIT")
+					DumpStacks("")
+					logrus.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
 				}
 				//for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
 				os.Exit(128 + int(sig.(syscall.Signal)))
@@ -56,7 +65,7 @@ func Trap(cleanup func()) {
 }
 
 // DumpStacks dumps the runtime stack.
-func DumpStacks() {
+func DumpStacks(root string) {
 	var (
 		buf       []byte
 		stackSize int
@@ -70,5 +79,30 @@ func DumpStacks() {
 	buf = buf[:stackSize]
 	// Note that if the daemon is started with a less-verbose log-level than "info" (the default), the goroutine
 	// traces won't show up in the log.
-	logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
+	if root == "" {
+		logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
+	} else {
+		// Dumps the stacks to a file in the root directory of the daemon
+		// On Windows, this overcomes two issues - one being that if the stack is too big, it doesn't
+		// get written to the event log when the Windows daemon is running as a service.
+		// Second, using logrus, the tabs and new-lines end up getting written as literal
+		// \t and \n's, meaning you need to use something like notepad++ to convert the
+		// output into something readable using 'type' from a command line or notepad/notepad++ etc.
+		path := filepath.Join(root, "goroutine-stacks.log")
+		f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
+		if err != nil {
+			logrus.Warnf("Could not open %s to write the goroutine stacks: %v", path, err)
+			return
+		}
+		defer f.Close()
+		f.WriteString("=== BEGIN goroutine stack dump ===\n")
+		f.WriteString(time.Now().String() + "\n")
+		if _, err := f.Write(buf); err != nil {
+			logrus.Warnf("Could not write goroutine stacks to %s: %v", path, err)
+			return
+		}
+		f.WriteString("=== END goroutine stack dump ===\n")
+		f.Sync()
+		logrus.Infof("goroutine stacks written to %s", path)
+	}
 }

+ 3 - 5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/stringid/stringid.go

@@ -29,11 +29,10 @@ func TruncateID(id string) string {
 	if i := strings.IndexRune(id, ':'); i >= 0 {
 		id = id[i+1:]
 	}
-	trimTo := shortLen
-	if len(id) < shortLen {
-		trimTo = len(id)
+	if len(id) > shortLen {
+		id = id[:shortLen]
 	}
-	return id[:trimTo]
+	return id
 }
 
 func generateID(crypto bool) string {
@@ -60,7 +59,6 @@ func generateID(crypto bool) string {
 // GenerateRandomID returns a unique id.
 func GenerateRandomID() string {
 	return generateID(true)
-
 }
 
 // GenerateNonCryptoID generates unique id without using cryptographically

+ 32 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_darwin.go

@@ -0,0 +1,32 @@
+package system
+
+import (
+	"syscall"
+)
+
+// fromStatT creates a system.StatT type from a syscall.Stat_t type
+func fromStatT(s *syscall.Stat_t) (*StatT, error) {
+	return &StatT{size: s.Size,
+		mode: uint32(s.Mode),
+		uid:  s.Uid,
+		gid:  s.Gid,
+		rdev: uint64(s.Rdev),
+		mtim: s.Mtimespec}, nil
+}
+
+// FromStatT loads a system.StatT from a syscall.Stat_t.
+func FromStatT(s *syscall.Stat_t) (*StatT, error) {
+	return fromStatT(s)
+}
+
+// Stat takes a path to a file and returns
+// a system.StatT type pertaining to that file.
+//
+// Throws an error if the file does not exist
+func Stat(path string) (*StatT, error) {
+	s := &syscall.Stat_t{}
+	if err := syscall.Stat(path, s); err != nil {
+		return nil, err
+	}
+	return fromStatT(s)
+}

+ 1 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_unsupported.go

@@ -1,4 +1,4 @@
-// +build !linux,!windows,!freebsd,!solaris,!openbsd
+// +build !linux,!windows,!freebsd,!solaris,!openbsd,!darwin
 
 package system
 

+ 0 - 8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go

@@ -1,8 +0,0 @@
-package system
-
-import "syscall"
-
-// LUtimesNano is not supported by darwin platform.
-func LUtimesNano(path string, ts []syscall.Timespec) error {
-	return ErrNotSupportedPlatform
-}

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

@@ -1,10 +1,10 @@
-// +build !linux,!freebsd,!darwin
+// +build !linux,!freebsd
 
 package system
 
 import "syscall"
 
-// LUtimesNano is not supported on platforms other than linux, freebsd and darwin.
+// LUtimesNano is only supported on linux and freebsd.
 func LUtimesNano(path string, ts []syscall.Timespec) error {
 	return ErrNotSupportedPlatform
 }

+ 19 - 5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go

@@ -1,11 +1,12 @@
 // +build !windows
 
-// Package term provides provides structures and helper functions to work with
+// Package term provides structures and helper functions to work with
 // terminal (state, sizes).
 package term
 
 import (
 	"errors"
+	"fmt"
 	"io"
 	"os"
 	"os/signal"
@@ -88,7 +89,8 @@ func DisableEcho(fd uintptr, state *State) error {
 }
 
 // SetRawTerminal puts the terminal connected to the given file descriptor into
-// raw mode and returns the previous state.
+// raw mode and returns the previous state. On UNIX, this puts both the input
+// and output into raw mode. On Windows, it only puts the input into raw mode.
 func SetRawTerminal(fd uintptr) (*State, error) {
 	oldState, err := MakeRaw(fd)
 	if err != nil {
@@ -98,12 +100,24 @@ func SetRawTerminal(fd uintptr) (*State, error) {
 	return oldState, err
 }
 
+// SetRawTerminalOutput puts the output of terminal connected to the given file
+// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
+// state. On Windows, it disables LF -> CRLF translation.
+func SetRawTerminalOutput(fd uintptr) (*State, error) {
+	return nil, nil
+}
+
 func handleInterrupt(fd uintptr, state *State) {
 	sigchan := make(chan os.Signal, 1)
 	signal.Notify(sigchan, os.Interrupt)
-
 	go func() {
-		_ = <-sigchan
-		RestoreTerminal(fd, state)
+		for range sigchan {
+			// quit cleanly and the new terminal item is on a new line
+			fmt.Println()
+			signal.Stop(sigchan)
+			close(sigchan)
+			RestoreTerminal(fd, state)
+			os.Exit(1)
+		}
 	}()
 }

+ 75 - 146
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go

@@ -9,14 +9,12 @@ import (
 	"syscall"
 
 	"github.com/Azure/go-ansiterm/winterm"
-	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/term/windows"
 )
 
 // State holds the console mode for the terminal.
 type State struct {
-	inMode, outMode     uint32
-	inHandle, outHandle syscall.Handle
+	mode uint32
 }
 
 // Winsize is used for window size.
@@ -32,143 +30,72 @@ const (
 	disableNewlineAutoReturn        = 0x0008
 )
 
-// usingNativeConsole is true if we are using the Windows native console
-var usingNativeConsole bool
+// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
+var vtInputSupported bool
 
 // StdStreams returns the standard streams (stdin, stdout, stedrr).
 func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
-	switch {
-	case os.Getenv("ConEmuANSI") == "ON":
-		// The ConEmu terminal emulates ANSI on output streams well.
-		return windows.ConEmuStreams()
-	case os.Getenv("MSYSTEM") != "":
-		// MSYS (mingw) does not emulate ANSI well.
-		return windows.ConsoleStreams()
-	default:
-		if useNativeConsole() {
-			usingNativeConsole = true
-			return os.Stdin, os.Stdout, os.Stderr
+	// Turn on VT handling on all std handles, if possible. This might
+	// fail, in which case we will fall back to terminal emulation.
+	var emulateStdin, emulateStdout, emulateStderr bool
+	fd := os.Stdin.Fd()
+	if mode, err := winterm.GetConsoleMode(fd); err == nil {
+		// Validate that enableVirtualTerminalInput is supported, but do not set it.
+		if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalInput); err != nil {
+			emulateStdin = true
+		} else {
+			vtInputSupported = true
 		}
-		return windows.ConsoleStreams()
-	}
-}
-
-// useNativeConsole determines if the docker client should use the built-in
-// console which supports ANSI emulation, or fall-back to the golang emulator
-// (github.com/azure/go-ansiterm).
-func useNativeConsole() bool {
-	osv := system.GetOSVersion()
-
-	// Native console is not available before major version 10
-	if osv.MajorVersion < 10 {
-		return false
-	}
-
-	// Get the console modes. If this fails, we can't use the native console
-	state, err := getNativeConsole()
-	if err != nil {
-		return false
-	}
-
-	// Probe the console to see if it can be enabled.
-	if nil != probeNativeConsole(state) {
-		return false
-	}
-
-	// Environment variable override
-	if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" {
-		if e == "1" {
-			return true
+		// Unconditionally set the console mode back even on failure because SetConsoleMode
+		// remembers invalid bits on input handles.
+		winterm.SetConsoleMode(fd, mode)
+	}
+
+	fd = os.Stdout.Fd()
+	if mode, err := winterm.GetConsoleMode(fd); err == nil {
+		// Validate disableNewlineAutoReturn is supported, but do not set it.
+		if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
+			emulateStdout = true
+		} else {
+			winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
 		}
-		return false
-	}
-
-	// Must have a post-TP5 RS1 build of Windows Server 2016/Windows 10 for
-	// the native console to be usable.
-	if osv.Build < 14350 {
-		return false
-	}
-
-	return true
-}
-
-// getNativeConsole returns the console modes ('state') for the native Windows console
-func getNativeConsole() (State, error) {
-	var (
-		err   error
-		state State
-	)
-
-	// Get the handle to stdout
-	if state.outHandle, err = syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE); err != nil {
-		return state, err
 	}
 
-	// Get the console mode from the consoles stdout handle
-	if err = syscall.GetConsoleMode(state.outHandle, &state.outMode); err != nil {
-		return state, err
+	fd = os.Stderr.Fd()
+	if mode, err := winterm.GetConsoleMode(fd); err == nil {
+		// Validate disableNewlineAutoReturn is supported, but do not set it.
+		if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
+			emulateStderr = true
+		} else {
+			winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
+		}
 	}
 
-	// Get the handle to stdin
-	if state.inHandle, err = syscall.GetStdHandle(syscall.STD_INPUT_HANDLE); err != nil {
-		return state, err
+	if os.Getenv("ConEmuANSI") == "ON" {
+		// The ConEmu terminal emulates ANSI on output streams well.
+		emulateStdout = false
+		emulateStderr = false
 	}
 
-	// Get the console mode from the consoles stdin handle
-	if err = syscall.GetConsoleMode(state.inHandle, &state.inMode); err != nil {
-		return state, err
+	if emulateStdin {
+		stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
+	} else {
+		stdIn = os.Stdin
 	}
 
-	return state, nil
-}
-
-// probeNativeConsole probes the console to determine if native can be supported,
-func probeNativeConsole(state State) error {
-	if err := winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode|enableVirtualTerminalProcessing); err != nil {
-		return err
+	if emulateStdout {
+		stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
+	} else {
+		stdOut = os.Stdout
 	}
-	defer winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode)
 
-	if err := winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode|enableVirtualTerminalInput); err != nil {
-		return err
+	if emulateStderr {
+		stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
+	} else {
+		stdErr = os.Stderr
 	}
-	defer winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode)
 
-	return nil
-}
-
-// enableNativeConsole turns on native console mode
-func enableNativeConsole(state State) error {
-	// First attempt both enableVirtualTerminalProcessing and disableNewlineAutoReturn
-	if err := winterm.SetConsoleMode(uintptr(state.outHandle),
-		state.outMode|(enableVirtualTerminalProcessing|disableNewlineAutoReturn)); err != nil {
-
-		// That may fail, so fallback to trying just enableVirtualTerminalProcessing
-		if err := winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode|enableVirtualTerminalProcessing); err != nil {
-			return err
-		}
-	}
-
-	if err := winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode|enableVirtualTerminalInput); err != nil {
-		winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode) // restore out if we can
-		return err
-	}
-
-	return nil
-}
-
-// disableNativeConsole turns off native console mode
-func disableNativeConsole(state *State) error {
-	// Try and restore both in an out before error checking.
-	errout := winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode)
-	errin := winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode)
-	if errout != nil {
-		return errout
-	}
-	if errin != nil {
-		return errin
-	}
-	return nil
+	return
 }
 
 // GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
@@ -199,34 +126,23 @@ func IsTerminal(fd uintptr) bool {
 // RestoreTerminal restores the terminal connected to the given file descriptor
 // to a previous state.
 func RestoreTerminal(fd uintptr, state *State) error {
-	if usingNativeConsole {
-		return disableNativeConsole(state)
-	}
-	return winterm.SetConsoleMode(fd, state.outMode)
+	return winterm.SetConsoleMode(fd, state.mode)
 }
 
 // SaveState saves the state of the terminal connected to the given file descriptor.
 func SaveState(fd uintptr) (*State, error) {
-	if usingNativeConsole {
-		state, err := getNativeConsole()
-		if err != nil {
-			return nil, err
-		}
-		return &state, nil
-	}
-
 	mode, e := winterm.GetConsoleMode(fd)
 	if e != nil {
 		return nil, e
 	}
 
-	return &State{outMode: mode}, nil
+	return &State{mode: mode}, nil
 }
 
 // DisableEcho disables echo for the terminal connected to the given file descriptor.
 // -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
 func DisableEcho(fd uintptr, state *State) error {
-	mode := state.inMode
+	mode := state.mode
 	mode &^= winterm.ENABLE_ECHO_INPUT
 	mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
 	err := winterm.SetConsoleMode(fd, mode)
@@ -239,8 +155,9 @@ func DisableEcho(fd uintptr, state *State) error {
 	return nil
 }
 
-// SetRawTerminal puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state.
+// SetRawTerminal puts the terminal connected to the given file descriptor into
+// raw mode and returns the previous state. On UNIX, this puts both the input
+// and output into raw mode. On Windows, it only puts the input into raw mode.
 func SetRawTerminal(fd uintptr) (*State, error) {
 	state, err := MakeRaw(fd)
 	if err != nil {
@@ -252,6 +169,21 @@ func SetRawTerminal(fd uintptr) (*State, error) {
 	return state, err
 }
 
+// SetRawTerminalOutput puts the output of terminal connected to the given file
+// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
+// state. On Windows, it disables LF -> CRLF translation.
+func SetRawTerminalOutput(fd uintptr) (*State, error) {
+	state, err := SaveState(fd)
+	if err != nil {
+		return nil, err
+	}
+
+	// Ignore failures, since disableNewlineAutoReturn might not be supported on this
+	// version of Windows.
+	winterm.SetConsoleMode(fd, state.mode|disableNewlineAutoReturn)
+	return state, err
+}
+
 // MakeRaw puts the terminal (Windows Console) connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be restored.
 func MakeRaw(fd uintptr) (*State, error) {
@@ -260,13 +192,7 @@ func MakeRaw(fd uintptr) (*State, error) {
 		return nil, err
 	}
 
-	mode := state.inMode
-	if usingNativeConsole {
-		if err := enableNativeConsole(*state); err != nil {
-			return nil, err
-		}
-		mode |= enableVirtualTerminalInput
-	}
+	mode := state.mode
 
 	// See
 	// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
@@ -283,6 +209,9 @@ func MakeRaw(fd uintptr) (*State, error) {
 	mode |= winterm.ENABLE_EXTENDED_FLAGS
 	mode |= winterm.ENABLE_INSERT_MODE
 	mode |= winterm.ENABLE_QUICK_EDIT_MODE
+	if vtInputSupported {
+		mode |= enableVirtualTerminalInput
+	}
 
 	err = winterm.SetConsoleMode(fd, mode)
 	if err != nil {

+ 5 - 1
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/ansi_reader.go

@@ -6,6 +6,7 @@ import (
 	"bytes"
 	"errors"
 	"fmt"
+	"io"
 	"os"
 	"strings"
 	"unsafe"
@@ -27,7 +28,10 @@ type ansiReader struct {
 	command  []byte
 }
 
-func newAnsiReader(nFile int) *ansiReader {
+// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a
+// Windows console input handle.
+func NewAnsiReader(nFile int) io.ReadCloser {
+	initLogger()
 	file, fd := winterm.GetStdFile(nFile)
 	return &ansiReader{
 		file:    file,

+ 5 - 17
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/ansi_writer.go

@@ -3,16 +3,13 @@
 package windows
 
 import (
-	"io/ioutil"
+	"io"
 	"os"
 
 	ansiterm "github.com/Azure/go-ansiterm"
 	"github.com/Azure/go-ansiterm/winterm"
-	"github.com/Sirupsen/logrus"
 )
 
-var logger *logrus.Logger
-
 // ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation.
 type ansiWriter struct {
 	file           *os.File
@@ -24,19 +21,10 @@ type ansiWriter struct {
 	parser         *ansiterm.AnsiParser
 }
 
-func newAnsiWriter(nFile int) *ansiWriter {
-	logFile := ioutil.Discard
-
-	if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
-		logFile, _ = os.Create("ansiReaderWriter.log")
-	}
-
-	logger = &logrus.Logger{
-		Out:       logFile,
-		Formatter: new(logrus.TextFormatter),
-		Level:     logrus.DebugLevel,
-	}
-
+// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
+// Windows console output handle.
+func NewAnsiWriter(nFile int) io.Writer {
+	initLogger()
 	file, fd := winterm.GetStdFile(nFile)
 	info, err := winterm.GetConsoleScreenBufferInfo(fd)
 	if err != nil {

+ 0 - 62
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/console.go

@@ -3,73 +3,11 @@
 package windows
 
 import (
-	"io"
 	"os"
-	"syscall"
 
 	"github.com/Azure/go-ansiterm/winterm"
-
-	ansiterm "github.com/Azure/go-ansiterm"
-	"github.com/Sirupsen/logrus"
-	"io/ioutil"
 )
 
-// ConEmuStreams returns prepared versions of console streams,
-// for proper use in ConEmu terminal.
-// The ConEmu terminal emulates ANSI on output streams well by default.
-func ConEmuStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
-	if IsConsole(os.Stdin.Fd()) {
-		stdIn = newAnsiReader(syscall.STD_INPUT_HANDLE)
-	} else {
-		stdIn = os.Stdin
-	}
-
-	stdOut = os.Stdout
-	stdErr = os.Stderr
-
-	// WARNING (BEGIN): sourced from newAnsiWriter
-
-	logFile := ioutil.Discard
-
-	if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
-		logFile, _ = os.Create("ansiReaderWriter.log")
-	}
-
-	logger = &logrus.Logger{
-		Out:       logFile,
-		Formatter: new(logrus.TextFormatter),
-		Level:     logrus.DebugLevel,
-	}
-
-	// WARNING (END): sourced from newAnsiWriter
-
-	return stdIn, stdOut, stdErr
-}
-
-// ConsoleStreams returns a wrapped version for each standard stream referencing a console,
-// that handles ANSI character sequences.
-func ConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
-	if IsConsole(os.Stdin.Fd()) {
-		stdIn = newAnsiReader(syscall.STD_INPUT_HANDLE)
-	} else {
-		stdIn = os.Stdin
-	}
-
-	if IsConsole(os.Stdout.Fd()) {
-		stdOut = newAnsiWriter(syscall.STD_OUTPUT_HANDLE)
-	} else {
-		stdOut = os.Stdout
-	}
-
-	if IsConsole(os.Stderr.Fd()) {
-		stdErr = newAnsiWriter(syscall.STD_ERROR_HANDLE)
-	} else {
-		stdErr = os.Stderr
-	}
-
-	return stdIn, stdOut, stdErr
-}
-
 // GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
 func GetHandleInfo(in interface{}) (uintptr, bool) {
 	switch t := in.(type) {

+ 28 - 0
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/windows.go

@@ -3,3 +3,31 @@
 // and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
 
 package windows
+
+import (
+	"io/ioutil"
+	"os"
+	"sync"
+
+	ansiterm "github.com/Azure/go-ansiterm"
+	"github.com/Sirupsen/logrus"
+)
+
+var logger *logrus.Logger
+var initOnce sync.Once
+
+func initLogger() {
+	initOnce.Do(func() {
+		logFile := ioutil.Discard
+
+		if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
+			logFile, _ = os.Create("ansiReaderWriter.log")
+		}
+
+		logger = &logrus.Logger{
+			Out:       logFile,
+			Formatter: new(logrus.TextFormatter),
+			Level:     logrus.DebugLevel,
+		}
+	})
+}

+ 8 - 0
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/.travis.yml

@@ -0,0 +1,8 @@
+language: go
+go:
+  - tip
+before_install:
+  - go get github.com/mattn/goveralls
+  - go get golang.org/x/tools/cmd/cover
+script:
+    - $HOME/gopath/bin/goveralls -repotoken 2FMhp57u8LcstKL9B190fLTcEnBtAAiEL

+ 47 - 0
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/README.md

@@ -0,0 +1,47 @@
+# go-shellwords
+
+[![Coverage Status](https://coveralls.io/repos/mattn/go-shellwords/badge.png?branch=master)](https://coveralls.io/r/mattn/go-shellwords?branch=master)
+[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
+
+Parse line as shell words.
+
+## Usage
+
+```go
+args, err := shellwords.Parse("./foo --bar=baz")
+// args should be ["./foo", "--bar=baz"]
+```
+
+```go
+os.Setenv("FOO", "bar")
+p := shellwords.NewParser()
+p.ParseEnv = true
+args, err := p.Parse("./foo $FOO")
+// args should be ["./foo", "bar"]
+```
+
+```go
+p := shellwords.NewParser()
+p.ParseBacktick = true
+args, err := p.Parse("./foo `echo $SHELL`")
+// args should be ["./foo", "/bin/bash"]
+```
+
+```go
+shellwords.ParseBacktick = true
+p := shellwords.NewParser()
+args, err := p.Parse("./foo `echo $SHELL`")
+// args should be ["./foo", "/bin/bash"]
+```
+
+# Thanks
+
+This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).
+
+# License
+
+under the MIT License: http://mattn.mit-license.org/2014
+
+# Author
+
+Yasuhiro Matsumoto (a.k.a mattn)

+ 134 - 0
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/shellwords.go

@@ -0,0 +1,134 @@
+package shellwords
+
+import (
+	"errors"
+	"os"
+	"regexp"
+	"strings"
+)
+
+var (
+	ParseEnv      bool = false
+	ParseBacktick bool = false
+)
+
+var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`)
+
+func isSpace(r rune) bool {
+	switch r {
+	case ' ', '\t', '\r', '\n':
+		return true
+	}
+	return false
+}
+
+func replaceEnv(s string) string {
+	return envRe.ReplaceAllStringFunc(s, func(s string) string {
+		s = s[1:]
+		if s[0] == '{' {
+			s = s[1 : len(s)-1]
+		}
+		return os.Getenv(s)
+	})
+}
+
+type Parser struct {
+	ParseEnv      bool
+	ParseBacktick bool
+}
+
+func NewParser() *Parser {
+	return &Parser{ParseEnv, ParseBacktick}
+}
+
+func (p *Parser) Parse(line string) ([]string, error) {
+	line = strings.TrimSpace(line)
+
+	args := []string{}
+	buf := ""
+	var escaped, doubleQuoted, singleQuoted, backQuote bool
+	backtick := ""
+
+	for _, r := range line {
+		if escaped {
+			buf += string(r)
+			escaped = false
+			continue
+		}
+
+		if r == '\\' {
+			if singleQuoted {
+				buf += string(r)
+			} else {
+				escaped = true
+			}
+			continue
+		}
+
+		if isSpace(r) {
+			if singleQuoted || doubleQuoted || backQuote {
+				buf += string(r)
+				backtick += string(r)
+			} else if buf != "" {
+				if p.ParseEnv {
+					buf = replaceEnv(buf)
+				}
+				args = append(args, buf)
+				buf = ""
+			}
+			continue
+		}
+
+		switch r {
+		case '`':
+			if !singleQuoted && !doubleQuoted {
+				if p.ParseBacktick {
+					if backQuote {
+						out, err := shellRun(backtick)
+						if err != nil {
+							return nil, err
+						}
+						buf = out
+					}
+					backtick = ""
+					backQuote = !backQuote
+					continue
+				}
+				backtick = ""
+				backQuote = !backQuote
+			}
+		case '"':
+			if !singleQuoted {
+				doubleQuoted = !doubleQuoted
+				continue
+			}
+		case '\'':
+			if !doubleQuoted {
+				singleQuoted = !singleQuoted
+				continue
+			}
+		}
+
+		buf += string(r)
+		if backQuote {
+			backtick += string(r)
+		}
+	}
+
+	if buf != "" {
+		if p.ParseEnv {
+			buf = replaceEnv(buf)
+		}
+		args = append(args, buf)
+	}
+
+	if escaped || singleQuoted || doubleQuoted || backQuote {
+		return nil, errors.New("invalid command line string")
+	}
+
+	return args, nil
+}
+
+func Parse(line string) ([]string, error) {
+	return NewParser().Parse(line)
+}

+ 19 - 0
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_posix.go

@@ -0,0 +1,19 @@
+// +build !windows
+
+package shellwords
+
+import (
+	"errors"
+	"os"
+	"os/exec"
+	"strings"
+)
+
+func shellRun(line string) (string, error) {
+	shell := os.Getenv("SHELL")
+	b, err := exec.Command(shell, "-c", line).Output()
+	if err != nil {
+		return "", errors.New(err.Error() + ":" + string(b))
+	}
+	return strings.TrimSpace(string(b)), nil
+}

+ 17 - 0
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_windows.go

@@ -0,0 +1,17 @@
+package shellwords
+
+import (
+	"errors"
+	"os"
+	"os/exec"
+	"strings"
+)
+
+func shellRun(line string) (string, error) {
+	shell := os.Getenv("COMSPEC")
+	b, err := exec.Command(shell, "/c", line).Output()
+	if err != nil {
+		return "", errors.New(err.Error() + ":" + string(b))
+	}
+	return strings.TrimSpace(string(b)), nil
+}

+ 1 - 1
libnetwork/client/client.go

@@ -8,7 +8,7 @@ import (
 	"reflect"
 	"strings"
 
-	flag "github.com/docker/docker/pkg/mflag"
+	flag "github.com/docker/libnetwork/client/mflag"
 )
 
 // CallFunc provides environment specific call utility to invoke backend functions from UI

+ 27 - 0
libnetwork/client/mflag/LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) 2014-2016 The Docker & Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 40 - 0
libnetwork/client/mflag/README.md

@@ -0,0 +1,40 @@
+Package mflag (aka multiple-flag) implements command-line flag parsing.  
+It's an **hacky** fork of the [official golang package](http://golang.org/pkg/flag/)
+
+It adds:
+
+* both short and long flag version  
+`./example -s red` `./example --string blue`
+
+* multiple names for the same option  
+```
+$>./example -h
+Usage of example:
+  -s, --string="": a simple string
+```
+
+___
+It is very flexible on purpose, so you can do things like:  
+```
+$>./example -h
+Usage of example:
+  -s, -string, --string="": a simple string
+```
+
+Or:  
+```
+$>./example -h
+Usage of example:
+  -oldflag, --newflag="": a simple string
+```
+
+You can also hide some flags from the usage, so if we want only `--newflag`:  
+```
+$>./example -h
+Usage of example:
+  --newflag="": a simple string
+$>./example -oldflag str
+str
+```
+
+See [example.go](example/example.go) for more details.

+ 36 - 0
libnetwork/client/mflag/example/example.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"fmt"
+
+	flag "github.com/docker/libnetwork/client/mflag"
+)
+
+var (
+	i        int
+	str      string
+	b, b2, h bool
+)
+
+func init() {
+	flag.Bool([]string{"#hp", "#-halp"}, false, "display the halp")
+	flag.BoolVar(&b, []string{"b", "#bal", "#bol", "-bal"}, false, "a simple bool")
+	flag.BoolVar(&b, []string{"g", "#gil"}, false, "a simple bool")
+	flag.BoolVar(&b2, []string{"#-bool"}, false, "a simple bool")
+	flag.IntVar(&i, []string{"-integer", "-number"}, -1, "a simple integer")
+	flag.StringVar(&str, []string{"s", "#hidden", "-string"}, "", "a simple string") //-s -hidden and --string will work, but -hidden won't be in the usage
+	flag.BoolVar(&h, []string{"h", "#help", "-help"}, false, "display the help")
+	flag.StringVar(&str, []string{"mode"}, "mode1", "set the mode\nmode1: use the mode1\nmode2: use the mode2\nmode3: use the mode3")
+	flag.Parse()
+}
+func main() {
+	if h {
+		flag.PrintDefaults()
+	} else {
+		fmt.Printf("s/#hidden/-string: %s\n", str)
+		fmt.Printf("b: %t\n", b)
+		fmt.Printf("-bool: %t\n", b2)
+		fmt.Printf("s/#hidden/-string(via lookup): %s\n", flag.Lookup("s").Value.String())
+		fmt.Printf("ARGS: %v\n", flag.Args())
+	}
+}

+ 1280 - 0
libnetwork/client/mflag/flag.go

@@ -0,0 +1,1280 @@
+// Copyright 2014-2016 The Docker & Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//	Package mflag implements command-line flag parsing.
+//
+//	Usage:
+//
+//	Define flags using flag.String(), Bool(), Int(), etc.
+//
+//	This declares an integer flag, -f or --flagname, stored in the pointer ip, with type *int.
+//		import "flag /github.com/docker/libnetwork/client/mflag"
+//		var ip = flag.Int([]string{"f", "-flagname"}, 1234, "help message for flagname")
+//	If you like, you can bind the flag to a variable using the Var() functions.
+//		var flagvar int
+//		func init() {
+//			// -flaghidden will work, but will be hidden from the usage
+//			flag.IntVar(&flagvar, []string{"f", "#flaghidden", "-flagname"}, 1234, "help message for flagname")
+//		}
+//	Or you can create custom flags that satisfy the Value interface (with
+//	pointer receivers) and couple them to flag parsing by
+//		flag.Var(&flagVal, []string{"name"}, "help message for flagname")
+//	For such flags, the default value is just the initial value of the variable.
+//
+//	You can also add "deprecated" flags, they are still usable, but are not shown
+//	in the usage and will display a warning when you try to use them. `#` before
+//	an option means this option is deprecated, if there is an following option
+//	without `#` ahead, then that's the replacement, if not, it will just be removed:
+//		var ip = flag.Int([]string{"#f", "#flagname", "-flagname"}, 1234, "help message for flagname")
+//	this will display: `Warning: '-f' is deprecated, it will be replaced by '--flagname' soon. See usage.` or
+//	this will display: `Warning: '-flagname' is deprecated, it will be replaced by '--flagname' soon. See usage.`
+//		var ip = flag.Int([]string{"f", "#flagname"}, 1234, "help message for flagname")
+//	will display: `Warning: '-flagname' is deprecated, it will be removed soon. See usage.`
+//	so you can only use `-f`.
+//
+//	You can also group one letter flags, bif you declare
+//		var v = flag.Bool([]string{"v", "-verbose"}, false, "help message for verbose")
+//		var s = flag.Bool([]string{"s", "-slow"}, false, "help message for slow")
+//	you will be able to use the -vs or -sv
+//
+//	After all flags are defined, call
+//		flag.Parse()
+//	to parse the command line into the defined flags.
+//
+//	Flags may then be used directly. If you're using the flags themselves,
+//	they are all pointers; if you bind to variables, they're values.
+//		fmt.Println("ip has value ", *ip)
+//		fmt.Println("flagvar has value ", flagvar)
+//
+//	After parsing, the arguments after the flag are available as the
+//	slice flag.Args() or individually as flag.Arg(i).
+//	The arguments are indexed from 0 through flag.NArg()-1.
+//
+//	Command line flag syntax:
+//		-flag
+//		-flag=x
+//		-flag="x"
+//		-flag='x'
+//		-flag x  // non-boolean flags only
+//	One or two minus signs may be used; they are equivalent.
+//	The last form is not permitted for boolean flags because the
+//	meaning of the command
+//		cmd -x *
+//	will change if there is a file called 0, false, etc.  You must
+//	use the -flag=false form to turn off a boolean flag.
+//
+//	Flag parsing stops just before the first non-flag argument
+//	("-" is a non-flag argument) or after the terminator "--".
+//
+//	Integer flags accept 1234, 0664, 0x1234 and may be negative.
+//	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
+//	Duration flags accept any input valid for time.ParseDuration.
+//
+//	The default set of command-line flags is controlled by
+//	top-level functions.  The FlagSet type allows one to define
+//	independent sets of flags, such as to implement subcommands
+//	in a command-line interface. The methods of FlagSet are
+//	analogous to the top-level functions for the command-line
+//	flag set.
+
+package mflag
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"text/tabwriter"
+	"time"
+
+	"github.com/docker/docker/pkg/homedir"
+)
+
+// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
+var ErrHelp = errors.New("flag: help requested")
+
+// ErrRetry is the error returned if you need to try letter by letter
+var ErrRetry = errors.New("flag: retry")
+
+// -- bool Value
+type boolValue bool
+
+func newBoolValue(val bool, p *bool) *boolValue {
+	*p = val
+	return (*boolValue)(p)
+}
+
+func (b *boolValue) Set(s string) error {
+	v, err := strconv.ParseBool(s)
+	*b = boolValue(v)
+	return err
+}
+
+func (b *boolValue) Get() interface{} { return bool(*b) }
+
+func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
+
+func (b *boolValue) IsBoolFlag() bool { return true }
+
+// optional interface to indicate boolean flags that can be
+// supplied without "=value" text
+type boolFlag interface {
+	Value
+	IsBoolFlag() bool
+}
+
+// -- int Value
+type intValue int
+
+func newIntValue(val int, p *int) *intValue {
+	*p = val
+	return (*intValue)(p)
+}
+
+func (i *intValue) Set(s string) error {
+	v, err := strconv.ParseInt(s, 0, 64)
+	*i = intValue(v)
+	return err
+}
+
+func (i *intValue) Get() interface{} { return int(*i) }
+
+func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- int64 Value
+type int64Value int64
+
+func newInt64Value(val int64, p *int64) *int64Value {
+	*p = val
+	return (*int64Value)(p)
+}
+
+func (i *int64Value) Set(s string) error {
+	v, err := strconv.ParseInt(s, 0, 64)
+	*i = int64Value(v)
+	return err
+}
+
+func (i *int64Value) Get() interface{} { return int64(*i) }
+
+func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- uint Value
+type uintValue uint
+
+func newUintValue(val uint, p *uint) *uintValue {
+	*p = val
+	return (*uintValue)(p)
+}
+
+func (i *uintValue) Set(s string) error {
+	v, err := strconv.ParseUint(s, 0, 64)
+	*i = uintValue(v)
+	return err
+}
+
+func (i *uintValue) Get() interface{} { return uint(*i) }
+
+func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- uint64 Value
+type uint64Value uint64
+
+func newUint64Value(val uint64, p *uint64) *uint64Value {
+	*p = val
+	return (*uint64Value)(p)
+}
+
+func (i *uint64Value) Set(s string) error {
+	v, err := strconv.ParseUint(s, 0, 64)
+	*i = uint64Value(v)
+	return err
+}
+
+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
+
+func newStringValue(val string, p *string) *stringValue {
+	*p = val
+	return (*stringValue)(p)
+}
+
+func (s *stringValue) Set(val string) error {
+	*s = stringValue(val)
+	return nil
+}
+
+func (s *stringValue) Get() interface{} { return string(*s) }
+
+func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
+
+// -- float64 Value
+type float64Value float64
+
+func newFloat64Value(val float64, p *float64) *float64Value {
+	*p = val
+	return (*float64Value)(p)
+}
+
+func (f *float64Value) Set(s string) error {
+	v, err := strconv.ParseFloat(s, 64)
+	*f = float64Value(v)
+	return err
+}
+
+func (f *float64Value) Get() interface{} { return float64(*f) }
+
+func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
+
+// -- time.Duration Value
+type durationValue time.Duration
+
+func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
+	*p = val
+	return (*durationValue)(p)
+}
+
+func (d *durationValue) Set(s string) error {
+	v, err := time.ParseDuration(s)
+	*d = durationValue(v)
+	return err
+}
+
+func (d *durationValue) Get() interface{} { return time.Duration(*d) }
+
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
+
+// Value is the interface to the dynamic value stored in a flag.
+// (The default value is represented as a string.)
+//
+// If a Value has an IsBoolFlag() bool method returning true,
+// the command-line parser makes -name equivalent to -name=true
+// rather than using the next command-line argument.
+type Value interface {
+	String() string
+	Set(string) error
+}
+
+// Getter is an interface that allows the contents of a Value to be retrieved.
+// It wraps the Value interface, rather than being part of it, because it
+// appeared after Go 1 and its compatibility rules. All Value types provided
+// by this package satisfy the Getter interface.
+type Getter interface {
+	Value
+	Get() interface{}
+}
+
+// ErrorHandling defines how to handle flag parsing errors.
+type ErrorHandling int
+
+// ErrorHandling strategies available when a flag parsing error occurs
+const (
+	ContinueOnError ErrorHandling = iota
+	ExitOnError
+	PanicOnError
+)
+
+// A FlagSet represents a set of defined flags.  The zero value of a FlagSet
+// has no name and has ContinueOnError error handling.
+type FlagSet struct {
+	// Usage is the function called when an error occurs while parsing flags.
+	// The field is a function (not a method) that may be changed to point to
+	// a custom error handler.
+	Usage      func()
+	ShortUsage func()
+
+	name             string
+	parsed           bool
+	actual           map[string]*Flag
+	formal           map[string]*Flag
+	args             []string // arguments after flags
+	errorHandling    ErrorHandling
+	output           io.Writer // nil means stderr; use Out() accessor
+	nArgRequirements []nArgRequirement
+}
+
+// A Flag represents the state of a flag.
+type Flag struct {
+	Names    []string // name as it appears on command line
+	Usage    string   // help message
+	Value    Value    // value as set
+	DefValue string   // default value (as text); for usage message
+}
+
+type flagSlice []string
+
+func (p flagSlice) Len() int { return len(p) }
+func (p flagSlice) Less(i, j int) bool {
+	pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-")
+	lpi, lpj := strings.ToLower(pi), strings.ToLower(pj)
+	if lpi != lpj {
+		return lpi < lpj
+	}
+	return pi < pj
+}
+func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+// sortFlags returns the flags as a slice in lexicographical sorted order.
+func sortFlags(flags map[string]*Flag) []*Flag {
+	var list flagSlice
+
+	// The sorted list is based on the first name, when flag map might use the other names.
+	nameMap := make(map[string]string)
+
+	for n, f := range flags {
+		fName := strings.TrimPrefix(f.Names[0], "#")
+		nameMap[fName] = n
+		if len(f.Names) == 1 {
+			list = append(list, fName)
+			continue
+		}
+
+		found := false
+		for _, name := range list {
+			if name == fName {
+				found = true
+				break
+			}
+		}
+		if !found {
+			list = append(list, fName)
+		}
+	}
+	sort.Sort(list)
+	result := make([]*Flag, len(list))
+	for i, name := range list {
+		result[i] = flags[nameMap[name]]
+	}
+	return result
+}
+
+// Name returns the name of the FlagSet.
+func (fs *FlagSet) Name() string {
+	return fs.name
+}
+
+// Out returns the destination for usage and error messages.
+func (fs *FlagSet) Out() io.Writer {
+	if fs.output == nil {
+		return os.Stderr
+	}
+	return fs.output
+}
+
+// SetOutput sets the destination for usage and error messages.
+// If output is nil, os.Stderr is used.
+func (fs *FlagSet) SetOutput(output io.Writer) {
+	fs.output = output
+}
+
+// VisitAll visits the flags in lexicographical order, calling fn for each.
+// It visits all flags, even those not set.
+func (fs *FlagSet) VisitAll(fn func(*Flag)) {
+	for _, flag := range sortFlags(fs.formal) {
+		fn(flag)
+	}
+}
+
+// VisitAll visits the command-line flags in lexicographical order, calling
+// fn for each.  It visits all flags, even those not set.
+func VisitAll(fn func(*Flag)) {
+	CommandLine.VisitAll(fn)
+}
+
+// Visit visits the flags in lexicographical order, calling fn for each.
+// It visits only those flags that have been set.
+func (fs *FlagSet) Visit(fn func(*Flag)) {
+	for _, flag := range sortFlags(fs.actual) {
+		fn(flag)
+	}
+}
+
+// Visit visits the command-line flags in lexicographical order, calling fn
+// for each.  It visits only those flags that have been set.
+func Visit(fn func(*Flag)) {
+	CommandLine.Visit(fn)
+}
+
+// Lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (fs *FlagSet) Lookup(name string) *Flag {
+	return fs.formal[name]
+}
+
+// IsSet indicates whether the specified flag is set in the given FlagSet
+func (fs *FlagSet) IsSet(name string) bool {
+	return fs.actual[name] != nil
+}
+
+// Lookup returns the Flag structure of the named command-line flag,
+// returning nil if none exists.
+func Lookup(name string) *Flag {
+	return CommandLine.formal[name]
+}
+
+// IsSet indicates whether the specified flag was specified at all on the cmd line.
+func IsSet(name string) bool {
+	return CommandLine.IsSet(name)
+}
+
+type nArgRequirementType int
+
+// Indicator used to pass to BadArgs function
+const (
+	Exact nArgRequirementType = iota
+	Max
+	Min
+)
+
+type nArgRequirement struct {
+	Type nArgRequirementType
+	N    int
+}
+
+// Require adds a requirement about the number of arguments for the FlagSet.
+// The first parameter can be Exact, Max, or Min to respectively specify the exact,
+// the maximum, or the minimal number of arguments required.
+// The actual check is done in FlagSet.CheckArgs().
+func (fs *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) {
+	fs.nArgRequirements = append(fs.nArgRequirements, nArgRequirement{nArgRequirementType, nArg})
+}
+
+// CheckArgs uses the requirements set by FlagSet.Require() to validate
+// the number of arguments. If the requirements are not met,
+// an error message string is returned.
+func (fs *FlagSet) CheckArgs() (message string) {
+	for _, req := range fs.nArgRequirements {
+		var arguments string
+		if req.N == 1 {
+			arguments = "1 argument"
+		} else {
+			arguments = fmt.Sprintf("%d arguments", req.N)
+		}
+
+		str := func(kind string) string {
+			return fmt.Sprintf("%q requires %s%s", fs.name, kind, arguments)
+		}
+
+		switch req.Type {
+		case Exact:
+			if fs.NArg() != req.N {
+				return str("")
+			}
+		case Max:
+			if fs.NArg() > req.N {
+				return str("a maximum of ")
+			}
+		case Min:
+			if fs.NArg() < req.N {
+				return str("a minimum of ")
+			}
+		}
+	}
+	return ""
+}
+
+// Set sets the value of the named flag.
+func (fs *FlagSet) Set(name, value string) error {
+	flag, ok := fs.formal[name]
+	if !ok {
+		return fmt.Errorf("no such flag -%v", name)
+	}
+	if err := flag.Value.Set(value); err != nil {
+		return err
+	}
+	if fs.actual == nil {
+		fs.actual = make(map[string]*Flag)
+	}
+	fs.actual[name] = flag
+	return nil
+}
+
+// Set sets the value of the named command-line flag.
+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() {
+	writer := tabwriter.NewWriter(fs.Out(), 20, 1, 3, ' ', 0)
+	home := homedir.Get()
+
+	// Don't substitute when HOME is /
+	if runtime.GOOS != "windows" && home == "/" {
+		home = ""
+	}
+
+	// Add a blank line between cmd description and list of options
+	if fs.FlagCount() > 0 {
+		fmt.Fprintln(writer, "")
+	}
+
+	fs.VisitAll(func(flag *Flag) {
+		names := []string{}
+		for _, name := range flag.Names {
+			if name[0] != '#' {
+				names = append(names, name)
+			}
+		}
+		if len(names) > 0 && len(flag.Usage) > 0 {
+			val := flag.DefValue
+
+			if home != "" && strings.HasPrefix(val, home) {
+				val = homedir.GetShortcutString() + val[len(home):]
+			}
+
+			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 _, line := range strings.Split(flag.Usage, "\n") {
+				fmt.Fprintln(writer, "\t", line)
+			}
+		}
+	})
+	writer.Flush()
+}
+
+// PrintDefaults prints to standard error the default values of all defined command-line flags.
+func PrintDefaults() {
+	CommandLine.PrintDefaults()
+}
+
+// defaultUsage is the default function to print a usage message.
+func defaultUsage(fs *FlagSet) {
+	if fs.name == "" {
+		fmt.Fprintf(fs.Out(), "Usage:\n")
+	} else {
+		fmt.Fprintf(fs.Out(), "Usage of %s:\n", fs.name)
+	}
+	fs.PrintDefaults()
+}
+
+// NOTE: Usage is not just defaultUsage(CommandLine)
+// because it serves (via godoc flag Usage) as the example
+// for how to write your own usage function.
+
+// Usage prints to standard error a usage message documenting all defined command-line flags.
+// The function is a variable that may be changed to point to a custom function.
+var Usage = func() {
+	fmt.Fprintf(CommandLine.Out(), "Usage of %s:\n", os.Args[0])
+	PrintDefaults()
+}
+
+// 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])
+}
+
+// FlagCount returns the number of flags that have been defined.
+func (fs *FlagSet) FlagCount() int { return len(sortFlags(fs.formal)) }
+
+// FlagCountUndeprecated returns the number of undeprecated flags that have been defined.
+func (fs *FlagSet) FlagCountUndeprecated() int {
+	count := 0
+	for _, flag := range sortFlags(fs.formal) {
+		for _, name := range flag.Names {
+			if name[0] != '#' {
+				count++
+				break
+			}
+		}
+	}
+	return count
+}
+
+// NFlag returns the number of flags that have been set.
+func (fs *FlagSet) NFlag() int { return len(fs.actual) }
+
+// NFlag returns the number of command-line flags that have been set.
+func NFlag() int { return len(CommandLine.actual) }
+
+// Arg returns the i'th argument.  Arg(0) is the first remaining argument
+// after flags have been processed.
+func (fs *FlagSet) Arg(i int) string {
+	if i < 0 || i >= len(fs.args) {
+		return ""
+	}
+	return fs.args[i]
+}
+
+// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
+// after flags have been processed.
+func Arg(i int) string {
+	return CommandLine.Arg(i)
+}
+
+// NArg is the number of arguments remaining after flags have been processed.
+func (fs *FlagSet) NArg() int { return len(fs.args) }
+
+// NArg is the number of arguments remaining after flags have been processed.
+func NArg() int { return len(CommandLine.args) }
+
+// Args returns the non-flag arguments.
+func (fs *FlagSet) Args() []string { return fs.args }
+
+// Args returns the non-flag command-line arguments.
+func Args() []string { return CommandLine.args }
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func (fs *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) {
+	fs.Var(newBoolValue(value, p), names, usage)
+}
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func BoolVar(p *bool, names []string, value bool, usage string) {
+	CommandLine.Var(newBoolValue(value, p), names, usage)
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func (fs *FlagSet) Bool(names []string, value bool, usage string) *bool {
+	p := new(bool)
+	fs.BoolVar(p, names, value, usage)
+	return p
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func Bool(names []string, value bool, usage string) *bool {
+	return CommandLine.Bool(names, value, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func (fs *FlagSet) IntVar(p *int, names []string, value int, usage string) {
+	fs.Var(newIntValue(value, p), names, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func IntVar(p *int, names []string, value int, usage string) {
+	CommandLine.Var(newIntValue(value, p), names, usage)
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func (fs *FlagSet) Int(names []string, value int, usage string) *int {
+	p := new(int)
+	fs.IntVar(p, names, value, usage)
+	return p
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func Int(names []string, value int, usage string) *int {
+	return CommandLine.Int(names, value, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func (fs *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) {
+	fs.Var(newInt64Value(value, p), names, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func Int64Var(p *int64, names []string, value int64, usage string) {
+	CommandLine.Var(newInt64Value(value, p), names, usage)
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func (fs *FlagSet) Int64(names []string, value int64, usage string) *int64 {
+	p := new(int64)
+	fs.Int64Var(p, names, value, usage)
+	return p
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func Int64(names []string, value int64, usage string) *int64 {
+	return CommandLine.Int64(names, value, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (fs *FlagSet) UintVar(p *uint, names []string, value uint, usage string) {
+	fs.Var(newUintValue(value, p), names, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint  variable in which to store the value of the flag.
+func UintVar(p *uint, names []string, value uint, usage string) {
+	CommandLine.Var(newUintValue(value, p), names, usage)
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint  variable that stores the value of the flag.
+func (fs *FlagSet) Uint(names []string, value uint, usage string) *uint {
+	p := new(uint)
+	fs.UintVar(p, names, value, usage)
+	return p
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint  variable that stores the value of the flag.
+func Uint(names []string, value uint, usage string) *uint {
+	return CommandLine.Uint(names, value, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (fs *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) {
+	fs.Var(newUint64Value(value, p), names, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func Uint64Var(p *uint64, names []string, value uint64, usage string) {
+	CommandLine.Var(newUint64Value(value, p), names, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (fs *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 {
+	p := new(uint64)
+	fs.Uint64Var(p, names, value, usage)
+	return p
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+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) {
+	fs.Var(newStringValue(value, p), names, 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 StringVar(p *string, names []string, value string, usage string) {
+	CommandLine.Var(newStringValue(value, p), names, usage)
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func (fs *FlagSet) String(names []string, value string, usage string) *string {
+	p := new(string)
+	fs.StringVar(p, names, value, usage)
+	return p
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func String(names []string, value string, usage string) *string {
+	return CommandLine.String(names, value, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func (fs *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) {
+	fs.Var(newFloat64Value(value, p), names, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func Float64Var(p *float64, names []string, value float64, usage string) {
+	CommandLine.Var(newFloat64Value(value, p), names, usage)
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func (fs *FlagSet) Float64(names []string, value float64, usage string) *float64 {
+	p := new(float64)
+	fs.Float64Var(p, names, value, usage)
+	return p
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func Float64(names []string, value float64, usage string) *float64 {
+	return CommandLine.Float64(names, value, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+func (fs *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
+	fs.Var(newDurationValue(value, p), names, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
+	CommandLine.Var(newDurationValue(value, p), names, usage)
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+func (fs *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration {
+	p := new(time.Duration)
+	fs.DurationVar(p, names, value, usage)
+	return p
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+func Duration(names []string, value time.Duration, usage string) *time.Duration {
+	return CommandLine.Duration(names, value, usage)
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func (fs *FlagSet) Var(value Value, names []string, usage string) {
+	// Remember the default value as a string; it won't change.
+	flag := &Flag{names, usage, value, value.String()}
+	for _, name := range names {
+		name = strings.TrimPrefix(name, "#")
+		_, alreadythere := fs.formal[name]
+		if alreadythere {
+			var msg string
+			if fs.name == "" {
+				msg = fmt.Sprintf("flag redefined: %s", name)
+			} else {
+				msg = fmt.Sprintf("%s flag redefined: %s", fs.name, name)
+			}
+			fmt.Fprintln(fs.Out(), msg)
+			panic(msg) // Happens only if flags are declared with identical names
+		}
+		if fs.formal == nil {
+			fs.formal = make(map[string]*Flag)
+		}
+		fs.formal[name] = flag
+	}
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func Var(value Value, names []string, usage string) {
+	CommandLine.Var(value, names, usage)
+}
+
+// failf prints to standard error a formatted error and usage message and
+// returns the error.
+func (fs *FlagSet) failf(format string, a ...interface{}) error {
+	err := fmt.Errorf(format, a...)
+	fmt.Fprintln(fs.Out(), err)
+	if os.Args[0] == fs.name {
+		fmt.Fprintf(fs.Out(), "See '%s --help'.\n", os.Args[0])
+	} else {
+		fmt.Fprintf(fs.Out(), "See '%s %s --help'.\n", os.Args[0], fs.name)
+	}
+	return err
+}
+
+// usage calls the Usage method for the flag set, or the usage function if
+// the flag set is CommandLine.
+func (fs *FlagSet) usage() {
+	if fs == CommandLine {
+		Usage()
+	} else if fs.Usage == nil {
+		defaultUsage(fs)
+	} else {
+		fs.Usage()
+	}
+}
+
+func trimQuotes(str string) string {
+	if len(str) == 0 {
+		return str
+	}
+	type quote struct {
+		start, end byte
+	}
+
+	// All valid quote types.
+	quotes := []quote{
+		// Double quotes
+		{
+			start: '"',
+			end:   '"',
+		},
+
+		// Single quotes
+		{
+			start: '\'',
+			end:   '\'',
+		},
+	}
+
+	for _, quote := range quotes {
+		// Only strip if outermost match.
+		if str[0] == quote.start && str[len(str)-1] == quote.end {
+			str = str[1 : len(str)-1]
+			break
+		}
+	}
+
+	return str
+}
+
+// parseOne parses one flag. It reports whether a flag was seen.
+func (fs *FlagSet) parseOne() (bool, string, error) {
+	if len(fs.args) == 0 {
+		return false, "", nil
+	}
+	s := fs.args[0]
+	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
+		return false, "", nil
+	}
+	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
+		fs.args = fs.args[1:]
+		return false, "", nil
+	}
+	name := s[1:]
+	if len(name) == 0 || name[0] == '=' {
+		return false, "", fs.failf("bad flag syntax: %s", s)
+	}
+
+	// it's a flag. does it have an argument?
+	fs.args = fs.args[1:]
+	hasValue := false
+	value := ""
+	if i := strings.Index(name, "="); i != -1 {
+		value = trimQuotes(name[i+1:])
+		hasValue = true
+		name = name[:i]
+	}
+
+	m := fs.formal
+	flag, alreadythere := m[name] // BUG
+	if !alreadythere {
+		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
+			fs.usage()
+			return false, "", ErrHelp
+		}
+		if len(name) > 0 && name[0] == '-' {
+			return false, "", fs.failf("flag provided but not defined: -%s", name)
+		}
+		return false, name, ErrRetry
+	}
+	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
+		if hasValue {
+			if err := fv.Set(value); err != nil {
+				return false, "", fs.failf("invalid boolean value %q for  -%s: %v", value, name, err)
+			}
+		} else {
+			fv.Set("true")
+		}
+	} else {
+		// It must have a value, which might be the next argument.
+		if !hasValue && len(fs.args) > 0 {
+			// value is the next arg
+			hasValue = true
+			value, fs.args = fs.args[0], fs.args[1:]
+		}
+		if !hasValue {
+			return false, "", fs.failf("flag needs an argument: -%s", name)
+		}
+		if err := flag.Value.Set(value); err != nil {
+			return false, "", fs.failf("invalid value %q for flag -%s: %v", value, name, err)
+		}
+	}
+	if fs.actual == nil {
+		fs.actual = make(map[string]*Flag)
+	}
+	fs.actual[name] = flag
+	for i, n := range flag.Names {
+		if n == fmt.Sprintf("#%s", name) {
+			replacement := ""
+			for j := i; j < len(flag.Names); j++ {
+				if flag.Names[j][0] != '#' {
+					replacement = flag.Names[j]
+					break
+				}
+			}
+			if replacement != "" {
+				fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
+			} else {
+				fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
+			}
+		}
+	}
+	return true, "", nil
+}
+
+// Parse parses flag definitions from the argument list, which should not
+// include the command name.  Must be called after all flags in the FlagSet
+// are defined and before flags are accessed by the program.
+// The return value will be ErrHelp if -help was set but not defined.
+func (fs *FlagSet) Parse(arguments []string) error {
+	fs.parsed = true
+	fs.args = arguments
+	for {
+		seen, name, err := fs.parseOne()
+		if seen {
+			continue
+		}
+		if err == nil {
+			break
+		}
+		if err == ErrRetry {
+			if len(name) > 1 {
+				err = nil
+				for _, letter := range strings.Split(name, "") {
+					fs.args = append([]string{"-" + letter}, fs.args...)
+					seen2, _, err2 := fs.parseOne()
+					if seen2 {
+						continue
+					}
+					if err2 != nil {
+						err = fs.failf("flag provided but not defined: -%s", name)
+						break
+					}
+				}
+				if err == nil {
+					continue
+				}
+			} else {
+				err = fs.failf("flag provided but not defined: -%s", name)
+			}
+		}
+		switch fs.errorHandling {
+		case ContinueOnError:
+			return err
+		case ExitOnError:
+			os.Exit(125)
+		case PanicOnError:
+			panic(err)
+		}
+	}
+	return nil
+}
+
+// ParseFlags is a utility function that adds a help flag if withHelp is true,
+// calls fs.Parse(args) and prints a relevant error message if there are
+// incorrect number of arguments. It returns error only if error handling is
+// set to ContinueOnError and parsing fails. If error handling is set to
+// ExitOnError, it's safe to ignore the return value.
+func (fs *FlagSet) ParseFlags(args []string, withHelp bool) error {
+	var help *bool
+	if withHelp {
+		help = fs.Bool([]string{"#help", "-help"}, false, "Print usage")
+	}
+	if err := fs.Parse(args); err != nil {
+		return err
+	}
+	if help != nil && *help {
+		fs.SetOutput(os.Stdout)
+		fs.Usage()
+		os.Exit(0)
+	}
+	if str := fs.CheckArgs(); str != "" {
+		fs.SetOutput(os.Stderr)
+		fs.ReportError(str, withHelp)
+		fs.ShortUsage()
+		os.Exit(1)
+	}
+	return nil
+}
+
+// ReportError is a utility method that prints a user-friendly message
+// containing the error that occurred during parsing and a suggestion to get help
+func (fs *FlagSet) ReportError(str string, withHelp bool) {
+	if withHelp {
+		if os.Args[0] == fs.Name() {
+			str += ".\nSee '" + os.Args[0] + " --help'"
+		} else {
+			str += ".\nSee '" + os.Args[0] + " " + fs.Name() + " --help'"
+		}
+	}
+	fmt.Fprintf(fs.Out(), "%s: %s.\n", os.Args[0], str)
+}
+
+// Parsed reports whether fs.Parse has been called.
+func (fs *FlagSet) Parsed() bool {
+	return fs.parsed
+}
+
+// Parse parses the command-line flags from os.Args[1:].  Must be called
+// after all flags are defined and before flags are accessed by the program.
+func Parse() {
+	// Ignore errors; CommandLine is set for ExitOnError.
+	CommandLine.Parse(os.Args[1:])
+}
+
+// Parsed returns true if the command-line flags have been parsed.
+func Parsed() bool {
+	return CommandLine.Parsed()
+}
+
+// CommandLine is the default set of command-line flags, parsed from os.Args.
+// The top-level functions such as BoolVar, Arg, and on are wrappers for the
+// methods of CommandLine.
+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
+
+// NewFlagSet returns a new, empty flag set with the specified name and
+// error handling property.
+func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
+	f := &FlagSet{
+		name:          name,
+		errorHandling: errorHandling,
+	}
+	return f
+}
+
+// Init sets the name and error handling property for a flag set.
+// By default, the zero FlagSet uses an empty name and the
+// ContinueOnError error handling policy.
+func (fs *FlagSet) Init(name string, errorHandling ErrorHandling) {
+	fs.name = name
+	fs.errorHandling = errorHandling
+}
+
+type mergeVal struct {
+	Value
+	key  string
+	fset *FlagSet
+}
+
+func (v mergeVal) Set(s string) error {
+	return v.fset.Set(v.key, s)
+}
+
+func (v mergeVal) IsBoolFlag() bool {
+	if b, ok := v.Value.(boolFlag); ok {
+		return b.IsBoolFlag()
+	}
+	return false
+}
+
+// Name returns the name of a mergeVal.
+// If the original value had a name, return the original name,
+// otherwise, return the key asinged to this mergeVal.
+func (v mergeVal) Name() string {
+	type namedValue interface {
+		Name() string
+	}
+	if nVal, ok := v.Value.(namedValue); ok {
+		return nVal.Name()
+	}
+	return v.key
+}
+
+// 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 behavior.
+func Merge(dest *FlagSet, flagsets ...*FlagSet) error {
+	for _, fset := range flagsets {
+		if fset.formal == nil {
+			continue
+		}
+		for k, f := range fset.formal {
+			if _, ok := dest.formal[k]; ok {
+				var err error
+				if fset.name == "" {
+					err = fmt.Errorf("flag redefined: %s", k)
+				} else {
+					err = fmt.Errorf("%s flag redefined: %s", fset.name, k)
+				}
+				fmt.Fprintln(fset.Out(), err.Error())
+				// Happens only if flags are declared with identical names
+				switch dest.errorHandling {
+				case ContinueOnError:
+					return err
+				case ExitOnError:
+					os.Exit(2)
+				case PanicOnError:
+					panic(err)
+				}
+			}
+			newF := *f
+			newF.Value = mergeVal{f.Value, k, fset}
+			if dest.formal == nil {
+				dest.formal = make(map[string]*Flag)
+			}
+			dest.formal[k] = &newF
+		}
+	}
+	return nil
+}
+
+// IsEmpty reports if the FlagSet is actually empty.
+func (fs *FlagSet) IsEmpty() bool {
+	return len(fs.actual) == 0
+}

+ 529 - 0
libnetwork/client/mflag/flag_test.go

@@ -0,0 +1,529 @@
+// Copyright 2014-2016 The Docker & Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mflag
+
+import (
+	"bytes"
+	"fmt"
+	"os"
+	"sort"
+	"strings"
+	"testing"
+	"time"
+
+	_ "github.com/docker/libnetwork/testutils"
+)
+
+// ResetForTesting clears all flag state and sets the usage function as directed.
+// After calling ResetForTesting, parse errors in flag handling will not
+// exit the program.
+func ResetForTesting(usage func()) {
+	CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
+	Usage = usage
+}
+func boolString(s string) string {
+	if s == "0" {
+		return "false"
+	}
+	return "true"
+}
+
+func TestEverything(t *testing.T) {
+	ResetForTesting(nil)
+	Bool([]string{"test_bool"}, false, "bool value")
+	Int([]string{"test_int"}, 0, "int value")
+	Int64([]string{"test_int64"}, 0, "int64 value")
+	Uint([]string{"test_uint"}, 0, "uint value")
+	Uint64([]string{"test_uint64"}, 0, "uint64 value")
+	String([]string{"test_string"}, "0", "string value")
+	Float64([]string{"test_float64"}, 0, "float64 value")
+	Duration([]string{"test_duration"}, 0, "time.Duration value")
+
+	m := make(map[string]*Flag)
+	desired := "0"
+	visitor := func(f *Flag) {
+		for _, name := range f.Names {
+			if len(name) > 5 && name[0:5] == "test_" {
+				m[name] = f
+				ok := false
+				switch {
+				case f.Value.String() == desired:
+					ok = true
+				case name == "test_bool" && f.Value.String() == boolString(desired):
+					ok = true
+				case name == "test_duration" && f.Value.String() == desired+"s":
+					ok = true
+				}
+				if !ok {
+					t.Error("Visit: bad value", f.Value.String(), "for", name)
+				}
+			}
+		}
+	}
+	VisitAll(visitor)
+	if len(m) != 8 {
+		t.Error("VisitAll misses some flags")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	m = make(map[string]*Flag)
+	Visit(visitor)
+	if len(m) != 0 {
+		t.Errorf("Visit sees unset flags")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	// Now set all flags
+	Set("test_bool", "true")
+	Set("test_int", "1")
+	Set("test_int64", "1")
+	Set("test_uint", "1")
+	Set("test_uint64", "1")
+	Set("test_string", "1")
+	Set("test_float64", "1")
+	Set("test_duration", "1s")
+	desired = "1"
+	Visit(visitor)
+	if len(m) != 8 {
+		t.Error("Visit fails after set")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	// Now test they're visited in sort order.
+	var flagNames []string
+	Visit(func(f *Flag) {
+		for _, name := range f.Names {
+			flagNames = append(flagNames, name)
+		}
+	})
+	if !sort.StringsAreSorted(flagNames) {
+		t.Errorf("flag names not sorted: %v", flagNames)
+	}
+}
+
+func TestGet(t *testing.T) {
+	ResetForTesting(nil)
+	Bool([]string{"test_bool"}, true, "bool value")
+	Int([]string{"test_int"}, 1, "int value")
+	Int64([]string{"test_int64"}, 2, "int64 value")
+	Uint([]string{"test_uint"}, 3, "uint value")
+	Uint64([]string{"test_uint64"}, 4, "uint64 value")
+	String([]string{"test_string"}, "5", "string value")
+	Float64([]string{"test_float64"}, 6, "float64 value")
+	Duration([]string{"test_duration"}, 7, "time.Duration value")
+
+	visitor := func(f *Flag) {
+		for _, name := range f.Names {
+			if len(name) > 5 && name[0:5] == "test_" {
+				g, ok := f.Value.(Getter)
+				if !ok {
+					t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
+					return
+				}
+				switch name {
+				case "test_bool":
+					ok = g.Get() == true
+				case "test_int":
+					ok = g.Get() == int(1)
+				case "test_int64":
+					ok = g.Get() == int64(2)
+				case "test_uint":
+					ok = g.Get() == uint(3)
+				case "test_uint64":
+					ok = g.Get() == uint64(4)
+				case "test_string":
+					ok = g.Get() == "5"
+				case "test_float64":
+					ok = g.Get() == float64(6)
+				case "test_duration":
+					ok = g.Get() == time.Duration(7)
+				}
+				if !ok {
+					t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), name)
+				}
+			}
+		}
+	}
+	VisitAll(visitor)
+}
+
+func testParse(f *FlagSet, t *testing.T) {
+	if f.Parsed() {
+		t.Error("f.Parse() = true before Parse")
+	}
+	boolFlag := f.Bool([]string{"bool"}, false, "bool value")
+	bool2Flag := f.Bool([]string{"bool2"}, false, "bool2 value")
+	f.Bool([]string{"bool3"}, false, "bool3 value")
+	bool4Flag := f.Bool([]string{"bool4"}, false, "bool4 value")
+	intFlag := f.Int([]string{"-int"}, 0, "int value")
+	int64Flag := f.Int64([]string{"-int64"}, 0, "int64 value")
+	uintFlag := f.Uint([]string{"uint"}, 0, "uint value")
+	uint64Flag := f.Uint64([]string{"-uint64"}, 0, "uint64 value")
+	stringFlag := f.String([]string{"string"}, "0", "string value")
+	f.String([]string{"string2"}, "0", "string2 value")
+	singleQuoteFlag := f.String([]string{"squote"}, "", "single quoted value")
+	doubleQuoteFlag := f.String([]string{"dquote"}, "", "double quoted value")
+	mixedQuoteFlag := f.String([]string{"mquote"}, "", "mixed quoted value")
+	mixed2QuoteFlag := f.String([]string{"mquote2"}, "", "mixed2 quoted value")
+	nestedQuoteFlag := f.String([]string{"nquote"}, "", "nested quoted value")
+	nested2QuoteFlag := f.String([]string{"nquote2"}, "", "nested2 quoted value")
+	float64Flag := f.Float64([]string{"float64"}, 0, "float64 value")
+	durationFlag := f.Duration([]string{"duration"}, 5*time.Second, "time.Duration value")
+	extra := "one-extra-argument"
+	args := []string{
+		"-bool",
+		"-bool2=true",
+		"-bool4=false",
+		"--int", "22",
+		"--int64", "0x23",
+		"-uint", "24",
+		"--uint64", "25",
+		"-string", "hello",
+		"-squote='single'",
+		`-dquote="double"`,
+		`-mquote='mixed"`,
+		`-mquote2="mixed2'`,
+		`-nquote="'single nested'"`,
+		`-nquote2='"double nested"'`,
+		"-float64", "2718e28",
+		"-duration", "2m",
+		extra,
+	}
+	if err := f.Parse(args); err != nil {
+		t.Fatal(err)
+	}
+	if !f.Parsed() {
+		t.Error("f.Parse() = false after Parse")
+	}
+	if *boolFlag != true {
+		t.Error("bool flag should be true, is ", *boolFlag)
+	}
+	if *bool2Flag != true {
+		t.Error("bool2 flag should be true, is ", *bool2Flag)
+	}
+	if !f.IsSet("bool2") {
+		t.Error("bool2 should be marked as set")
+	}
+	if f.IsSet("bool3") {
+		t.Error("bool3 should not be marked as set")
+	}
+	if !f.IsSet("bool4") {
+		t.Error("bool4 should be marked as set")
+	}
+	if *bool4Flag != false {
+		t.Error("bool4 flag should be false, is ", *bool4Flag)
+	}
+	if *intFlag != 22 {
+		t.Error("int flag should be 22, is ", *intFlag)
+	}
+	if *int64Flag != 0x23 {
+		t.Error("int64 flag should be 0x23, is ", *int64Flag)
+	}
+	if *uintFlag != 24 {
+		t.Error("uint flag should be 24, is ", *uintFlag)
+	}
+	if *uint64Flag != 25 {
+		t.Error("uint64 flag should be 25, is ", *uint64Flag)
+	}
+	if *stringFlag != "hello" {
+		t.Error("string flag should be `hello`, is ", *stringFlag)
+	}
+	if !f.IsSet("string") {
+		t.Error("string flag should be marked as set")
+	}
+	if f.IsSet("string2") {
+		t.Error("string2 flag should not be marked as set")
+	}
+	if *singleQuoteFlag != "single" {
+		t.Error("single quote string flag should be `single`, is ", *singleQuoteFlag)
+	}
+	if *doubleQuoteFlag != "double" {
+		t.Error("double quote string flag should be `double`, is ", *doubleQuoteFlag)
+	}
+	if *mixedQuoteFlag != `'mixed"` {
+		t.Error("mixed quote string flag should be `'mixed\"`, is ", *mixedQuoteFlag)
+	}
+	if *mixed2QuoteFlag != `"mixed2'` {
+		t.Error("mixed2 quote string flag should be `\"mixed2'`, is ", *mixed2QuoteFlag)
+	}
+	if *nestedQuoteFlag != "'single nested'" {
+		t.Error("nested quote string flag should be `'single nested'`, is ", *nestedQuoteFlag)
+	}
+	if *nested2QuoteFlag != `"double nested"` {
+		t.Error("double quote string flag should be `\"double nested\"`, is ", *nested2QuoteFlag)
+	}
+	if *float64Flag != 2718e28 {
+		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
+	}
+	if *durationFlag != 2*time.Minute {
+		t.Error("duration flag should be 2m, is ", *durationFlag)
+	}
+	if len(f.Args()) != 1 {
+		t.Error("expected one argument, got", len(f.Args()))
+	} else if f.Args()[0] != extra {
+		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
+	}
+}
+
+func testPanic(f *FlagSet, t *testing.T) {
+	f.Int([]string{"-int"}, 0, "int value")
+	if f.Parsed() {
+		t.Error("f.Parse() = true before Parse")
+	}
+	args := []string{
+		"-int", "21",
+	}
+	f.Parse(args)
+}
+
+func TestParsePanic(t *testing.T) {
+	ResetForTesting(func() {})
+	testPanic(CommandLine, t)
+}
+
+func TestParse(t *testing.T) {
+	ResetForTesting(func() { t.Error("bad parse") })
+	testParse(CommandLine, t)
+}
+
+func TestFlagSetParse(t *testing.T) {
+	testParse(NewFlagSet("test", ContinueOnError), t)
+}
+
+// Declare a user-defined flag type.
+type flagVar []string
+
+func (f *flagVar) String() string {
+	return fmt.Sprint([]string(*f))
+}
+
+func (f *flagVar) Set(value string) error {
+	*f = append(*f, value)
+	return nil
+}
+
+func TestUserDefined(t *testing.T) {
+	var flags FlagSet
+	flags.Init("test", ContinueOnError)
+	var v flagVar
+	flags.Var(&v, []string{"v"}, "usage")
+	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
+		t.Error(err)
+	}
+	if len(v) != 3 {
+		t.Fatal("expected 3 args; got ", len(v))
+	}
+	expect := "[1 2 3]"
+	if v.String() != expect {
+		t.Errorf("expected value %q got %q", expect, v.String())
+	}
+}
+
+// Declare a user-defined boolean flag type.
+type boolFlagVar struct {
+	count int
+}
+
+func (b *boolFlagVar) String() string {
+	return fmt.Sprintf("%d", b.count)
+}
+
+func (b *boolFlagVar) Set(value string) error {
+	if value == "true" {
+		b.count++
+	}
+	return nil
+}
+
+func (b *boolFlagVar) IsBoolFlag() bool {
+	return b.count < 4
+}
+
+func TestUserDefinedBool(t *testing.T) {
+	var flags FlagSet
+	flags.Init("test", ContinueOnError)
+	var b boolFlagVar
+	var err error
+	flags.Var(&b, []string{"b"}, "usage")
+	if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
+		if b.count < 4 {
+			t.Error(err)
+		}
+	}
+
+	if b.count != 4 {
+		t.Errorf("want: %d; got: %d", 4, b.count)
+	}
+
+	if err == nil {
+		t.Error("expected error; got none")
+	}
+}
+
+func TestSetOutput(t *testing.T) {
+	var flags FlagSet
+	var buf bytes.Buffer
+	flags.SetOutput(&buf)
+	flags.Init("test", ContinueOnError)
+	flags.Parse([]string{"-unknown"})
+	if out := buf.String(); !strings.Contains(out, "-unknown") {
+		t.Logf("expected output mentioning unknown; got %q", out)
+	}
+}
+
+// This tests that one can reset the flags. This still works but not well, and is
+// superseded by FlagSet.
+func TestChangingArgs(t *testing.T) {
+	ResetForTesting(func() { t.Fatal("bad parse") })
+	oldArgs := os.Args
+	defer func() { os.Args = oldArgs }()
+	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
+	before := Bool([]string{"before"}, false, "")
+	if err := CommandLine.Parse(os.Args[1:]); err != nil {
+		t.Fatal(err)
+	}
+	cmd := Arg(0)
+	os.Args = Args()
+	after := Bool([]string{"after"}, false, "")
+	Parse()
+	args := Args()
+
+	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
+		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
+	}
+}
+
+// Test that -help invokes the usage message and returns ErrHelp.
+func TestHelp(t *testing.T) {
+	var helpCalled = false
+	fs := NewFlagSet("help test", ContinueOnError)
+	fs.Usage = func() { helpCalled = true }
+	var flag bool
+	fs.BoolVar(&flag, []string{"flag"}, false, "regular flag")
+	// Regular flag invocation should work
+	err := fs.Parse([]string{"-flag=true"})
+	if err != nil {
+		t.Fatal("expected no error; got ", err)
+	}
+	if !flag {
+		t.Error("flag was not set by -flag")
+	}
+	if helpCalled {
+		t.Error("help called for regular flag")
+		helpCalled = false // reset for next test
+	}
+	// Help flag should work as expected.
+	err = fs.Parse([]string{"-help"})
+	if err == nil {
+		t.Fatal("error expected")
+	}
+	if err != ErrHelp {
+		t.Fatal("expected ErrHelp; got ", err)
+	}
+	if !helpCalled {
+		t.Fatal("help was not called")
+	}
+	// If we define a help flag, that should override.
+	var help bool
+	fs.BoolVar(&help, []string{"help"}, false, "help flag")
+	helpCalled = false
+	err = fs.Parse([]string{"-help"})
+	if err != nil {
+		t.Fatal("expected no error for defined -help; got ", err)
+	}
+	if helpCalled {
+		t.Fatal("help was called; should not have been for defined help flag")
+	}
+}
+
+// Test the flag count functions.
+func TestFlagCounts(t *testing.T) {
+	fs := NewFlagSet("help test", ContinueOnError)
+	var flag bool
+	fs.BoolVar(&flag, []string{"flag1"}, false, "regular flag")
+	fs.BoolVar(&flag, []string{"#deprecated1"}, false, "regular flag")
+	fs.BoolVar(&flag, []string{"f", "flag2"}, false, "regular flag")
+	fs.BoolVar(&flag, []string{"#d", "#deprecated2"}, false, "regular flag")
+	fs.BoolVar(&flag, []string{"flag3"}, false, "regular flag")
+	fs.BoolVar(&flag, []string{"g", "#flag4", "-flag4"}, false, "regular flag")
+
+	if fs.FlagCount() != 6 {
+		t.Fatal("FlagCount wrong. ", fs.FlagCount())
+	}
+	if fs.FlagCountUndeprecated() != 4 {
+		t.Fatal("FlagCountUndeprecated wrong. ", fs.FlagCountUndeprecated())
+	}
+	if fs.NFlag() != 0 {
+		t.Fatal("NFlag wrong. ", fs.NFlag())
+	}
+	err := fs.Parse([]string{"-fd", "-g", "-flag4"})
+	if err != nil {
+		t.Fatal("expected no error for defined -help; got ", err)
+	}
+	if fs.NFlag() != 4 {
+		t.Fatal("NFlag wrong. ", fs.NFlag())
+	}
+}
+
+// Show up bug in sortFlags
+func TestSortFlags(t *testing.T) {
+	fs := NewFlagSet("help TestSortFlags", ContinueOnError)
+
+	var err error
+
+	var b bool
+	fs.BoolVar(&b, []string{"b", "-banana"}, false, "usage")
+
+	err = fs.Parse([]string{"--banana=true"})
+	if err != nil {
+		t.Fatal("expected no error; got ", err)
+	}
+
+	count := 0
+
+	fs.VisitAll(func(flag *Flag) {
+		count++
+		if flag == nil {
+			t.Fatal("VisitAll should not return a nil flag")
+		}
+	})
+	flagcount := fs.FlagCount()
+	if flagcount != count {
+		t.Fatalf("FlagCount (%d) != number (%d) of elements visited", flagcount, count)
+	}
+	// Make sure its idempotent
+	if flagcount != fs.FlagCount() {
+		t.Fatalf("FlagCount (%d) != fs.FlagCount() (%d) of elements visited", flagcount, fs.FlagCount())
+	}
+
+	count = 0
+	fs.Visit(func(flag *Flag) {
+		count++
+		if flag == nil {
+			t.Fatal("Visit should not return a nil flag")
+		}
+	})
+	nflag := fs.NFlag()
+	if nflag != count {
+		t.Fatalf("NFlag (%d) != number (%d) of elements visited", nflag, count)
+	}
+	if nflag != fs.NFlag() {
+		t.Fatalf("NFlag (%d) != fs.NFlag() (%d) of elements visited", nflag, fs.NFlag())
+	}
+}
+
+func TestMergeFlags(t *testing.T) {
+	base := NewFlagSet("base", ContinueOnError)
+	base.String([]string{"f"}, "", "")
+
+	fs := NewFlagSet("test", ContinueOnError)
+	Merge(fs, base)
+	if len(fs.formal) != 1 {
+		t.Fatalf("FlagCount (%d) != number (1) of elements merged", len(fs.formal))
+	}
+}

+ 1 - 1
libnetwork/client/network.go

@@ -8,8 +8,8 @@ import (
 	"strings"
 	"text/tabwriter"
 
-	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/stringid"
+	flag "github.com/docker/libnetwork/client/mflag"
 	"github.com/docker/libnetwork/netlabel"
 )
 

+ 1 - 1
libnetwork/client/service.go

@@ -9,8 +9,8 @@ import (
 	"text/tabwriter"
 
 	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
 	"github.com/docker/docker/pkg/stringid"
+	flag "github.com/docker/libnetwork/client/mflag"
 	"github.com/docker/libnetwork/netutils"
 )
 

+ 1 - 1
libnetwork/cluster/provider.go

@@ -1,7 +1,7 @@
 package cluster
 
 import (
-	"github.com/docker/engine-api/types/network"
+	"github.com/docker/docker/api/types/network"
 	"golang.org/x/net/context"
 )
 

+ 1 - 1
libnetwork/cmd/dnet/dnet.go

@@ -23,8 +23,8 @@ import (
 	"github.com/docker/docker/pkg/reexec"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/pkg/term"
-	"github.com/docker/engine-api/types/network"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork/api"
 	"github.com/docker/libnetwork/config"

+ 1 - 1
libnetwork/cmd/dnet/dnet_linux.go

@@ -13,7 +13,7 @@ func setupDumpStackTrap() {
 	signal.Notify(c, syscall.SIGUSR1)
 	go func() {
 		for range c {
-			psignal.DumpStacks()
+			psignal.DumpStacks("")
 		}
 	}()
 }

+ 1 - 1
libnetwork/cmd/dnet/dnet_windows.go

@@ -21,7 +21,7 @@ func setupDumpStackTrap() {
 			logrus.Debugf("Stackdump - waiting signal at %s", ev)
 			for {
 				syscall.WaitForSingleObject(h, syscall.INFINITE)
-				signal.DumpStacks()
+				signal.DumpStacks("")
 			}
 		}
 	}()

+ 7 - 7
libnetwork/drivers/remote/driver_test.go

@@ -218,7 +218,7 @@ func TestGetEmptyCapabilities(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newDriver(plugin, p.Client)
+	d := newDriver(plugin, p.Client())
 	if d.Type() != plugin {
 		t.Fatal("Driver type does not match that given")
 	}
@@ -247,7 +247,7 @@ func TestGetExtraCapabilities(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newDriver(plugin, p.Client)
+	d := newDriver(plugin, p.Client())
 	if d.Type() != plugin {
 		t.Fatal("Driver type does not match that given")
 	}
@@ -277,7 +277,7 @@ func TestGetInvalidCapabilities(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newDriver(plugin, p.Client)
+	d := newDriver(plugin, p.Client())
 	if d.Type() != plugin {
 		t.Fatal("Driver type does not match that given")
 	}
@@ -391,7 +391,7 @@ func TestRemoteDriver(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newDriver(plugin, p.Client)
+	d := newDriver(plugin, p.Client())
 	if d.Type() != plugin {
 		t.Fatal("Driver type does not match that given")
 	}
@@ -469,7 +469,7 @@ func TestDriverError(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	driver := newDriver(plugin, p.Client)
+	driver := newDriver(plugin, p.Client())
 
 	if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil {
 		t.Fatalf("Expected error from driver")
@@ -501,7 +501,7 @@ func TestMissingValues(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	driver := newDriver(plugin, p.Client)
+	driver := newDriver(plugin, p.Client())
 
 	if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil {
 		t.Fatal(err)
@@ -562,7 +562,7 @@ func TestRollback(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	driver := newDriver(plugin, p.Client)
+	driver := newDriver(plugin, p.Client())
 
 	ep := &rollbackEndpoint{}
 

+ 4 - 4
libnetwork/ipams/remote/remote_test.go

@@ -79,7 +79,7 @@ func TestGetCapabilities(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newAllocator(plugin, p.Client)
+	d := newAllocator(plugin, p.Client())
 
 	caps, err := d.(*allocator).getCapabilities()
 	if err != nil {
@@ -102,7 +102,7 @@ func TestGetCapabilitiesFromLegacyDriver(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newAllocator(plugin, p.Client)
+	d := newAllocator(plugin, p.Client())
 
 	if _, err := d.(*allocator).getCapabilities(); err == nil {
 		t.Fatalf("Expected error, but got Success %v", err)
@@ -127,7 +127,7 @@ func TestGetDefaultAddressSpaces(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newAllocator(plugin, p.Client)
+	d := newAllocator(plugin, p.Client())
 
 	l, g, err := d.(*allocator).GetDefaultAddressSpaces()
 	if err != nil {
@@ -217,7 +217,7 @@ func TestRemoteDriver(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	d := newAllocator(plugin, p.Client)
+	d := newAllocator(plugin, p.Client())
 
 	l, g, err := d.(*allocator).GetDefaultAddressSpaces()
 	if err != nil {