Merge pull request #1437 from mrjana/agent
Move engine-api to docker/docker/api
This commit is contained in:
commit
146551e922
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/libnetwork",
|
"ImportPath": "github.com/docker/libnetwork",
|
||||||
"GoVersion": "go1.5",
|
"GoVersion": "go1.5",
|
||||||
"GodepVersion": "v74",
|
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
|
@ -81,105 +80,110 @@
|
||||||
"Comment": "v1-26-gef32fa3",
|
"Comment": "v1-26-gef32fa3",
|
||||||
"Rev": "ef32fa3046d9f249d399f98ebaf9be944430fd1d"
|
"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",
|
"ImportPath": "github.com/docker/docker/opts",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/discovery",
|
"ImportPath": "github.com/docker/docker/pkg/discovery",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/discovery/kv",
|
"ImportPath": "github.com/docker/docker/pkg/discovery/kv",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/homedir",
|
"ImportPath": "github.com/docker/docker/pkg/homedir",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/ioutils",
|
"ImportPath": "github.com/docker/docker/pkg/ioutils",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/longpath",
|
"ImportPath": "github.com/docker/docker/pkg/longpath",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/docker/docker/pkg/mflag",
|
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/mount",
|
"ImportPath": "github.com/docker/docker/pkg/mount",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/parsers/kernel",
|
"ImportPath": "github.com/docker/docker/pkg/parsers/kernel",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/plugins",
|
"ImportPath": "github.com/docker/docker/pkg/plugins",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/plugins/transport",
|
"ImportPath": "github.com/docker/docker/pkg/plugins/transport",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/random",
|
"ImportPath": "github.com/docker/docker/pkg/random",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/reexec",
|
"ImportPath": "github.com/docker/docker/pkg/reexec",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/signal",
|
"ImportPath": "github.com/docker/docker/pkg/signal",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/stringid",
|
"ImportPath": "github.com/docker/docker/pkg/stringid",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/symlink",
|
"ImportPath": "github.com/docker/docker/pkg/symlink",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/system",
|
"ImportPath": "github.com/docker/docker/pkg/system",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/term",
|
"ImportPath": "github.com/docker/docker/pkg/term",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/term/windows",
|
"ImportPath": "github.com/docker/docker/pkg/term/windows",
|
||||||
"Comment": "v1.4.1-12227-g86a7632",
|
"Comment": "docs-v1.12.0-rc4-2016-07-15-1316-g426a0af",
|
||||||
"Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
|
"Rev": "426a0af0759798d8e3332b38236ee40df6d14798"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/docker/engine-api/types/network",
|
|
||||||
"Comment": "v0.3.1-210-g25941ec",
|
|
||||||
"Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/go-connections/sockets",
|
"ImportPath": "github.com/docker/go-connections/sockets",
|
||||||
|
@ -289,6 +293,11 @@
|
||||||
"Comment": "v0.7.0-47-g598c548",
|
"Comment": "v0.7.0-47-g598c548",
|
||||||
"Rev": "598c54895cc5a7b1a24a398d635e8c0ea0959870"
|
"Rev": "598c54895cc5a7b1a24a398d635e8c0ea0959870"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mattn/go-shellwords",
|
||||||
|
"Comment": "v1.0.0-1-g525bede",
|
||||||
|
"Rev": "525bedee691b5a8df547cb5cf9f86b7fb1883e24"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/miekg/dns",
|
"ImportPath": "github.com/miekg/dns",
|
||||||
"Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02"
|
"Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02"
|
||||||
|
|
307
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/filters/parse.go
generated
vendored
Normal file
307
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/filters/parse.go
generated
vendored
Normal file
|
@ -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
|
||||||
|
}
|
14
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/README.md
generated
vendored
Normal file
14
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/README.md
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/compare.go
generated
vendored
Normal file
62
libnetwork/Godeps/_workspace/src/github.com/docker/docker/api/types/versions/compare.go
generated
vendored
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -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.
|
// 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.
|
// Depending of the address specified, this may return one of the global Default* strings defined in hosts.go.
|
||||||
func parseDockerDaemonHost(addr string) (string, error) {
|
func parseDockerDaemonHost(addr string) (string, error) {
|
||||||
addrParts := strings.Split(addr, "://")
|
addrParts := strings.SplitN(addr, "://", 2)
|
||||||
if len(addrParts) == 1 && addrParts[0] != "" {
|
if len(addrParts) == 1 && addrParts[0] != "" {
|
||||||
addrParts = []string{"tcp", addrParts[0]}
|
addrParts = []string{"tcp", addrParts[0]}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch addrParts[0] {
|
switch addrParts[0] {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
return parseTCPAddr(addrParts[1], DefaultTCPHost)
|
return ParseTCPAddr(addrParts[1], DefaultTCPHost)
|
||||||
case "unix":
|
case "unix":
|
||||||
return parseSimpleProtoAddr("unix", addrParts[1], DefaultUnixSocket)
|
return parseSimpleProtoAddr("unix", addrParts[1], DefaultUnixSocket)
|
||||||
case "npipe":
|
case "npipe":
|
||||||
|
@ -97,12 +97,12 @@ func parseSimpleProtoAddr(proto, addr, defaultAddr string) (string, error) {
|
||||||
return fmt.Sprintf("%s://%s", proto, addr), nil
|
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
|
// 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.
|
// from tryAddr, or the contents of defaultAddr if tryAddr is a blank string.
|
||||||
// tryAddr is expected to have already been Trim()'d
|
// tryAddr is expected to have already been Trim()'d
|
||||||
// defaultAddr must be in the full `tcp://host:port` form
|
// 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://" {
|
if tryAddr == "" || tryAddr == "tcp://" {
|
||||||
return defaultAddr, nil
|
return defaultAddr, nil
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,11 @@ func parseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(u.Host)
|
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 {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
|
return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,3 +40,8 @@ func (o *IPOpt) String() string {
|
||||||
}
|
}
|
||||||
return o.IP.String()
|
return o.IP.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type returns the type of the option
|
||||||
|
func (o *IPOpt) Type() string {
|
||||||
|
return "ip"
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -100,6 +102,11 @@ func (opts *ListOpts) Len() int {
|
||||||
return len((*opts.values))
|
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
|
// NamedOption is an interface that list and map options
|
||||||
// with names implement.
|
// with names implement.
|
||||||
type NamedOption interface {
|
type NamedOption interface {
|
||||||
|
@ -163,6 +170,11 @@ func (opts *MapOpts) String() string {
|
||||||
return fmt.Sprintf("%v", map[string]string((opts.values)))
|
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.
|
// NewMapOpts creates a new MapOpts with the specified map of values and a validator.
|
||||||
func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
|
func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
|
||||||
if values == nil {
|
if values == nil {
|
||||||
|
@ -241,7 +253,7 @@ func ValidateLabel(val string) (string, error) {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateSysctl validates an sysctl and returns it.
|
// ValidateSysctl validates a sysctl and returns it.
|
||||||
func ValidateSysctl(val string) (string, error) {
|
func ValidateSysctl(val string) (string, error) {
|
||||||
validSysctlMap := map[string]bool{
|
validSysctlMap := map[string]bool{
|
||||||
"kernel.msgmax": true,
|
"kernel.msgmax": true,
|
||||||
|
@ -272,3 +284,38 @@ func ValidateSysctl(val string) (string, error) {
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
|
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
|
||||||
|
}
|
||||||
|
|
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/backends.go
generated
vendored
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/backends.go
generated
vendored
|
@ -6,7 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -21,7 +21,7 @@ func Register(scheme string, d Backend) error {
|
||||||
if _, exists := backends[scheme]; exists {
|
if _, exists := backends[scheme]; exists {
|
||||||
return fmt.Errorf("scheme already registered %s", scheme)
|
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
|
backends[scheme] = d
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func ParseAdvertise(advertise string) (string, error) {
|
||||||
return advertise, nil
|
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
|
ifaceName := addr
|
||||||
iface, err = net.InterfaceByName(ifaceName)
|
iface, err = net.InterfaceByName(ifaceName)
|
||||||
if err != nil {
|
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) {
|
func New(rawurl string, heartbeat time.Duration, ttl time.Duration, clusterOpts map[string]string) (Backend, error) {
|
||||||
scheme, uri := parse(rawurl)
|
scheme, uri := parse(rawurl)
|
||||||
if backend, exists := backends[scheme]; exists {
|
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)
|
err := backend.Initialize(uri, heartbeat, ttl, clusterOpts)
|
||||||
return backend, err
|
return backend, err
|
||||||
}
|
}
|
||||||
|
|
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv.go
generated
vendored
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/discovery/kv/kv.go
generated
vendored
|
@ -6,7 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/pkg/discovery"
|
"github.com/docker/docker/pkg/discovery"
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
"github.com/docker/libkv"
|
"github.com/docker/libkv"
|
||||||
|
@ -73,7 +73,7 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
|
||||||
|
|
||||||
var config *store.Config
|
var config *store.Config
|
||||||
if clusterOpts["kv.cacertfile"] != "" && clusterOpts["kv.certfile"] != "" && clusterOpts["kv.keyfile"] != "" {
|
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{
|
tlsConfig, err := tlsconfig.Client(tlsconfig.Options{
|
||||||
CAFile: clusterOpts["kv.cacertfile"],
|
CAFile: clusterOpts["kv.cacertfile"],
|
||||||
CertFile: clusterOpts["kv.certfile"],
|
CertFile: clusterOpts["kv.certfile"],
|
||||||
|
@ -93,7 +93,7 @@ func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Du
|
||||||
TLS: tlsConfig,
|
TLS: tlsConfig,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Info("Initializing discovery without TLS")
|
logrus.Infof("Initializing discovery without TLS")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new store, will ignore options given
|
// 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
|
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`.
|
// Convert `KVPair` into `discovery.Entry`.
|
||||||
addrs := make([]string, len(pairs))
|
addrs := make([]string, len(pairs))
|
||||||
|
|
3
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe.go
generated
vendored
3
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/bytespipe.go
generated
vendored
|
@ -133,8 +133,9 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
bp.wait.Wait()
|
bp.wait.Wait()
|
||||||
if bp.bufLen == 0 && bp.closeErr != nil {
|
if bp.bufLen == 0 && bp.closeErr != nil {
|
||||||
|
err := bp.closeErr
|
||||||
bp.mu.Unlock()
|
bp.mu.Unlock()
|
||||||
return 0, bp.closeErr
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
9
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/fswriters.go
generated
vendored
9
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/fswriters.go
generated
vendored
|
@ -15,6 +15,7 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
abspath, err := filepath.Abs(filename)
|
abspath, err := filepath.Abs(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -22,6 +23,7 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
||||||
return &atomicFileWriter{
|
return &atomicFileWriter{
|
||||||
f: f,
|
f: f,
|
||||||
fn: abspath,
|
fn: abspath,
|
||||||
|
perm: perm,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +36,7 @@ func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
n, err := f.Write(data)
|
n, err := f.Write(data)
|
||||||
if err == nil && n < len(data) {
|
if err == nil && n < len(data) {
|
||||||
err = io.ErrShortWrite
|
err = io.ErrShortWrite
|
||||||
|
f.(*atomicFileWriter).writeErr = err
|
||||||
}
|
}
|
||||||
if err1 := f.Close(); err == nil {
|
if err1 := f.Close(); err == nil {
|
||||||
err = err1
|
err = err1
|
||||||
|
@ -45,6 +48,7 @@ type atomicFileWriter struct {
|
||||||
f *os.File
|
f *os.File
|
||||||
fn string
|
fn string
|
||||||
writeErr error
|
writeErr error
|
||||||
|
perm os.FileMode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *atomicFileWriter) Write(dt []byte) (int, error) {
|
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) {
|
func (w *atomicFileWriter) Close() (retErr error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if retErr != nil {
|
if retErr != nil || w.writeErr != nil {
|
||||||
os.Remove(w.f.Name())
|
os.Remove(w.f.Name())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -68,6 +72,9 @@ func (w *atomicFileWriter) Close() (retErr error) {
|
||||||
if err := w.f.Close(); err != nil {
|
if err := w.f.Close(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := os.Chmod(w.f.Name(), w.perm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if w.writeErr == nil {
|
if w.writeErr == nil {
|
||||||
return os.Rename(w.f.Name(), w.fn)
|
return os.Rename(w.f.Name(), w.fn)
|
||||||
}
|
}
|
||||||
|
|
21
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/multireader.go
generated
vendored
21
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/multireader.go
generated
vendored
|
@ -97,27 +97,24 @@ func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, 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 {
|
var offsetTo int64
|
||||||
offsetTo, err := r.getOffsetToReader(rdr)
|
|
||||||
|
for _, rdr := range r.readers {
|
||||||
|
size, err := getReadSeekerSize(rdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
if offsetTo > offset {
|
if offsetTo+size > offset {
|
||||||
rdr = r.readers[i-1]
|
return rdr, offset - offsetTo, nil
|
||||||
rdrOffset = offsetTo - offset
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rdr == r.readers[len(r.readers)-1] {
|
if rdr == r.readers[len(r.readers)-1] {
|
||||||
rdrOffset = offsetTo + offset
|
return rdr, offsetTo + offset, nil
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
offsetTo += size
|
||||||
}
|
}
|
||||||
|
|
||||||
return rdr, rdrOffset, nil
|
return nil, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *multiReadSeeker) getCurOffset() (int64, error) {
|
func (r *multiReadSeeker) getCurOffset() (int64, error) {
|
||||||
|
|
2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
generated
vendored
2
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
generated
vendored
|
@ -55,7 +55,7 @@ func HashData(src io.Reader) (string, error) {
|
||||||
return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
|
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.
|
// the function will run at the end of file or close the file.
|
||||||
type OnEOFReader struct {
|
type OnEOFReader struct {
|
||||||
Rc io.ReadCloser
|
Rc io.ReadCloser
|
||||||
|
|
|
@ -5,15 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse fstab type mount options into mount() flags
|
var flags = map[string]struct {
|
||||||
// and device specific data
|
|
||||||
func parseOptions(options string) (int, string) {
|
|
||||||
var (
|
|
||||||
flag int
|
|
||||||
data []string
|
|
||||||
)
|
|
||||||
|
|
||||||
flags := map[string]struct {
|
|
||||||
clear bool
|
clear bool
|
||||||
flag int
|
flag int
|
||||||
}{
|
}{
|
||||||
|
@ -52,6 +44,81 @@ func parseOptions(options string) (int, string) {
|
||||||
"nostrictatime": {true, 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) {
|
||||||
|
var (
|
||||||
|
flag int
|
||||||
|
data []string
|
||||||
|
)
|
||||||
|
|
||||||
for _, o := range strings.Split(options, ",") {
|
for _, o := range strings.Split(options, ",") {
|
||||||
// If the option does not exist in the flags table or the flag
|
// If the option does not exist in the flags table or the flag
|
||||||
// is not supported on the platform,
|
// 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
|
// ParseTmpfsOptions parse fstab type mount options into flags and data
|
||||||
func ParseTmpfsOptions(options string) (int, string, error) {
|
func ParseTmpfsOptions(options string) (int, string, error) {
|
||||||
flags, data := parseOptions(options)
|
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, ",") {
|
for _, o := range strings.Split(data, ",") {
|
||||||
opt := strings.SplitN(o, "=", 2)
|
opt := strings.SplitN(o, "=", 2)
|
||||||
if !validFlags[opt[0]] {
|
if !validFlags[opt[0]] {
|
||||||
|
|
26
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go
generated
vendored
26
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel.go
generated
vendored
|
@ -5,7 +5,6 @@
|
||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
@ -46,31 +45,6 @@ func CompareKernelVersion(a, b VersionInfo) int {
|
||||||
return 0
|
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.
|
// ParseRelease parses a string and creates a VersionInfo based on it.
|
||||||
func ParseRelease(release string) (*VersionInfo, error) {
|
func ParseRelease(release string) (*VersionInfo, error) {
|
||||||
var (
|
var (
|
||||||
|
|
56
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go
generated
vendored
Normal file
56
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_darwin.go
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go
generated
vendored
Normal file
45
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/parsers/kernel/kernel_unix.go
generated
vendored
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go
generated
vendored
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/client.go
generated
vendored
|
@ -20,14 +20,16 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewClient creates a new plugin client (http).
|
// 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{}
|
tr := &http.Transport{}
|
||||||
|
|
||||||
c, err := tlsconfig.Client(tlsConfig)
|
if tlsConfig != nil {
|
||||||
|
c, err := tlsconfig.Client(*tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tr.TLSClientConfig = c
|
tr.TLSClientConfig = c
|
||||||
|
}
|
||||||
|
|
||||||
u, err := url.Parse(addr)
|
u, err := url.Parse(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -130,7 +132,7 @@ func (c *Client) callWithRetry(serviceMethod string, data io.Reader, retry bool)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
retries++
|
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)
|
time.Sleep(timeOff)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
9
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery.go
generated
vendored
9
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery.go
generated
vendored
|
@ -16,7 +16,6 @@ var (
|
||||||
// ErrNotFound plugin not found
|
// ErrNotFound plugin not found
|
||||||
ErrNotFound = errors.New("plugin not found")
|
ErrNotFound = errors.New("plugin not found")
|
||||||
socketsPath = "/run/docker/plugins"
|
socketsPath = "/run/docker/plugins"
|
||||||
specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// localRegistry defines a registry that is local (using unix socket).
|
// 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 {
|
for _, p := range socketpaths {
|
||||||
if fi, err := os.Stat(p); err == nil && fi.Mode()&os.ModeSocket != 0 {
|
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 nil, fmt.Errorf("Unknown protocol")
|
||||||
}
|
}
|
||||||
|
|
||||||
return newLocalPlugin(name, addr), nil
|
return NewLocalPlugin(name, addr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readPluginJSONInfo(name, path string) (*Plugin, error) {
|
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 {
|
if err := json.NewDecoder(f).Decode(&p); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p.Name = name
|
p.name = name
|
||||||
if len(p.TLSConfig.CAFile) == 0 {
|
if p.TLSConfig != nil && len(p.TLSConfig.CAFile) == 0 {
|
||||||
p.TLSConfig.InsecureSkipVerify = true
|
p.TLSConfig.InsecureSkipVerify = true
|
||||||
}
|
}
|
||||||
p.activateWait = sync.NewCond(&sync.Mutex{})
|
p.activateWait = sync.NewCond(&sync.Mutex{})
|
||||||
|
|
5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_unix.go
generated
vendored
Normal file
5
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
var specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"}
|
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_windows.go
generated
vendored
Normal file
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/discovery_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var specsPaths = []string{filepath.Join(os.Getenv("programdata"), "docker", "plugins")}
|
35
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/plugins.go
generated
vendored
35
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/plugins/plugins.go
generated
vendored
|
@ -55,13 +55,13 @@ type Manifest struct {
|
||||||
// Plugin is the definition of a docker plugin.
|
// Plugin is the definition of a docker plugin.
|
||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
// Name of the plugin
|
// Name of the plugin
|
||||||
Name string `json:"-"`
|
name string
|
||||||
// Address of the plugin
|
// Address of the plugin
|
||||||
Addr string
|
Addr string
|
||||||
// TLS configuration of the plugin
|
// TLS configuration of the plugin
|
||||||
TLSConfig tlsconfig.Options
|
TLSConfig *tlsconfig.Options
|
||||||
// Client attached to the plugin
|
// Client attached to the plugin
|
||||||
Client *Client `json:"-"`
|
client *Client
|
||||||
// Manifest of the plugin (see above)
|
// Manifest of the plugin (see above)
|
||||||
Manifest *Manifest `json:"-"`
|
Manifest *Manifest `json:"-"`
|
||||||
|
|
||||||
|
@ -73,11 +73,28 @@ type Plugin struct {
|
||||||
activateWait *sync.Cond
|
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{
|
return &Plugin{
|
||||||
Name: name,
|
name: name,
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
TLSConfig: tlsconfig.Options{InsecureSkipVerify: true},
|
// TODO: change to nil
|
||||||
|
TLSConfig: &tlsconfig.Options{InsecureSkipVerify: true},
|
||||||
activateWait: sync.NewCond(&sync.Mutex{}),
|
activateWait: sync.NewCond(&sync.Mutex{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,10 +119,10 @@ func (p *Plugin) activateWithLock() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.Client = c
|
p.client = c
|
||||||
|
|
||||||
m := new(Manifest)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +133,7 @@ func (p *Plugin) activateWithLock() error {
|
||||||
if !handled {
|
if !handled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
handler(p.Name, p.Client)
|
handler(p.name, p.client)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ func Self() string {
|
||||||
return "/proc/self/exe"
|
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.
|
// SysProcAttr.Pdeathsig to SIGTERM.
|
||||||
// This will use the in-memory version (/proc/self/exe) of the current binary,
|
// 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]).
|
// it is thus safe to delete or replace the on-disk binary (os.Args[0]).
|
||||||
|
|
4
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_unix.go
generated
vendored
4
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/reexec/command_unix.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// +build freebsd solaris
|
// +build freebsd solaris darwin
|
||||||
|
|
||||||
package reexec
|
package reexec
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ func Self() string {
|
||||||
return naiveSelf()
|
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
|
// For example if current binary is "docker" at "/usr/bin/", then cmd.Path will
|
||||||
// be set to "/usr/bin/docker".
|
// be set to "/usr/bin/docker".
|
||||||
func Command(args ...string) *exec.Cmd {
|
func Command(args ...string) *exec.Cmd {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!windows,!freebsd,!solaris
|
// +build !linux,!windows,!freebsd,!solaris,!darwin
|
||||||
|
|
||||||
package reexec
|
package reexec
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import (
|
||||||
"os/exec"
|
"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 {
|
func Command(args ...string) *exec.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func Self() string {
|
||||||
return naiveSelf()
|
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
|
// For example if current binary is "docker.exe" at "C:\", then cmd.Path will
|
||||||
// be set to "C:\docker.exe".
|
// be set to "C:\docker.exe".
|
||||||
func Command(args ...string) *exec.Cmd {
|
func Command(args ...string) *exec.Cmd {
|
||||||
|
|
|
@ -3,9 +3,11 @@ package signal
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
gosignal "os/signal"
|
gosignal "os/signal"
|
||||||
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -18,15 +20,22 @@ import (
|
||||||
// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is
|
// * 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)
|
// 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.
|
// * 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()) {
|
func Trap(cleanup func()) {
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
// we will handle INT, TERM, QUIT here
|
// we will handle INT, TERM, QUIT, SIGPIPE here
|
||||||
signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT}
|
signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
|
||||||
gosignal.Notify(c, signals...)
|
gosignal.Notify(c, signals...)
|
||||||
go func() {
|
go func() {
|
||||||
interruptCount := uint32(0)
|
interruptCount := uint32(0)
|
||||||
for sig := range c {
|
for sig := range c {
|
||||||
|
if sig == syscall.SIGPIPE {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
go func(sig os.Signal) {
|
go func(sig os.Signal) {
|
||||||
logrus.Infof("Processing signal '%v'", sig)
|
logrus.Infof("Processing signal '%v'", sig)
|
||||||
switch sig {
|
switch sig {
|
||||||
|
@ -42,11 +51,11 @@ func Trap(cleanup func()) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 3 SIGTERM/INT signals received; force exit without cleanup
|
// 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:
|
case syscall.SIGQUIT:
|
||||||
DumpStacks()
|
DumpStacks("")
|
||||||
logrus.Infof("Forcing docker daemon shutdown without cleanup on SIGQUIT")
|
logrus.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
|
||||||
}
|
}
|
||||||
//for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
|
//for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
|
||||||
os.Exit(128 + int(sig.(syscall.Signal)))
|
os.Exit(128 + int(sig.(syscall.Signal)))
|
||||||
|
@ -56,7 +65,7 @@ func Trap(cleanup func()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DumpStacks dumps the runtime stack.
|
// DumpStacks dumps the runtime stack.
|
||||||
func DumpStacks() {
|
func DumpStacks(root string) {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
stackSize int
|
stackSize int
|
||||||
|
@ -70,5 +79,30 @@ func DumpStacks() {
|
||||||
buf = buf[:stackSize]
|
buf = buf[:stackSize]
|
||||||
// Note that if the daemon is started with a less-verbose log-level than "info" (the default), the goroutine
|
// 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.
|
// traces won't show up in the log.
|
||||||
|
if root == "" {
|
||||||
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/stringid/stringid.go
generated
vendored
8
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/stringid/stringid.go
generated
vendored
|
@ -29,11 +29,10 @@ func TruncateID(id string) string {
|
||||||
if i := strings.IndexRune(id, ':'); i >= 0 {
|
if i := strings.IndexRune(id, ':'); i >= 0 {
|
||||||
id = id[i+1:]
|
id = id[i+1:]
|
||||||
}
|
}
|
||||||
trimTo := shortLen
|
if len(id) > shortLen {
|
||||||
if len(id) < shortLen {
|
id = id[:shortLen]
|
||||||
trimTo = len(id)
|
|
||||||
}
|
}
|
||||||
return id[:trimTo]
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateID(crypto bool) string {
|
func generateID(crypto bool) string {
|
||||||
|
@ -60,7 +59,6 @@ func generateID(crypto bool) string {
|
||||||
// GenerateRandomID returns a unique id.
|
// GenerateRandomID returns a unique id.
|
||||||
func GenerateRandomID() string {
|
func GenerateRandomID() string {
|
||||||
return generateID(true)
|
return generateID(true)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateNonCryptoID generates unique id without using cryptographically
|
// GenerateNonCryptoID generates unique id without using cryptographically
|
||||||
|
|
32
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_darwin.go
generated
vendored
Normal file
32
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/system/stat_darwin.go
generated
vendored
Normal file
|
@ -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,4 +1,4 @@
|
||||||
// +build !linux,!windows,!freebsd,!solaris,!openbsd
|
// +build !linux,!windows,!freebsd,!solaris,!openbsd,!darwin
|
||||||
|
|
||||||
package system
|
package system
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -1,10 +1,10 @@
|
||||||
// +build !linux,!freebsd,!darwin
|
// +build !linux,!freebsd
|
||||||
|
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import "syscall"
|
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 {
|
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||||
return ErrNotSupportedPlatform
|
return ErrNotSupportedPlatform
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// +build !windows
|
// +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).
|
// terminal (state, sizes).
|
||||||
package term
|
package term
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -88,7 +89,8 @@ func DisableEcho(fd uintptr, state *State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRawTerminal puts the terminal connected to the given file descriptor into
|
// 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) {
|
func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
oldState, err := MakeRaw(fd)
|
oldState, err := MakeRaw(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -98,12 +100,24 @@ func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
return oldState, err
|
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) {
|
func handleInterrupt(fd uintptr, state *State) {
|
||||||
sigchan := make(chan os.Signal, 1)
|
sigchan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigchan, os.Interrupt)
|
signal.Notify(sigchan, os.Interrupt)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
_ = <-sigchan
|
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)
|
RestoreTerminal(fd, state)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
231
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go
generated
vendored
231
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/term_windows.go
generated
vendored
|
@ -9,14 +9,12 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Azure/go-ansiterm/winterm"
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
"github.com/docker/docker/pkg/system"
|
|
||||||
"github.com/docker/docker/pkg/term/windows"
|
"github.com/docker/docker/pkg/term/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
// State holds the console mode for the terminal.
|
// State holds the console mode for the terminal.
|
||||||
type State struct {
|
type State struct {
|
||||||
inMode, outMode uint32
|
mode uint32
|
||||||
inHandle, outHandle syscall.Handle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Winsize is used for window size.
|
// Winsize is used for window size.
|
||||||
|
@ -32,143 +30,72 @@ const (
|
||||||
disableNewlineAutoReturn = 0x0008
|
disableNewlineAutoReturn = 0x0008
|
||||||
)
|
)
|
||||||
|
|
||||||
// usingNativeConsole is true if we are using the Windows native console
|
// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
|
||||||
var usingNativeConsole bool
|
var vtInputSupported bool
|
||||||
|
|
||||||
// StdStreams returns the standard streams (stdin, stdout, stedrr).
|
// StdStreams returns the standard streams (stdin, stdout, stedrr).
|
||||||
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||||
switch {
|
// Turn on VT handling on all std handles, if possible. This might
|
||||||
case os.Getenv("ConEmuANSI") == "ON":
|
// 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
|
||||||
|
}
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("ConEmuANSI") == "ON" {
|
||||||
// The ConEmu terminal emulates ANSI on output streams well.
|
// The ConEmu terminal emulates ANSI on output streams well.
|
||||||
return windows.ConEmuStreams()
|
emulateStdout = false
|
||||||
case os.Getenv("MSYSTEM") != "":
|
emulateStderr = false
|
||||||
// MSYS (mingw) does not emulate ANSI well.
|
|
||||||
return windows.ConsoleStreams()
|
|
||||||
default:
|
|
||||||
if useNativeConsole() {
|
|
||||||
usingNativeConsole = true
|
|
||||||
return os.Stdin, os.Stdout, os.Stderr
|
|
||||||
}
|
|
||||||
return windows.ConsoleStreams()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// useNativeConsole determines if the docker client should use the built-in
|
if emulateStdin {
|
||||||
// console which supports ANSI emulation, or fall-back to the golang emulator
|
stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
|
||||||
// (github.com/azure/go-ansiterm).
|
} else {
|
||||||
func useNativeConsole() bool {
|
stdIn = os.Stdin
|
||||||
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
|
if emulateStdout {
|
||||||
state, err := getNativeConsole()
|
stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
|
||||||
if err != nil {
|
} else {
|
||||||
return false
|
stdOut = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probe the console to see if it can be enabled.
|
if emulateStderr {
|
||||||
if nil != probeNativeConsole(state) {
|
stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
|
||||||
return false
|
} else {
|
||||||
|
stdErr = os.Stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Environment variable override
|
return
|
||||||
if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" {
|
|
||||||
if e == "1" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the handle to stdin
|
|
||||||
if state.inHandle, err = syscall.GetStdHandle(syscall.STD_INPUT_HANDLE); err != nil {
|
|
||||||
return state, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the console mode from the consoles stdin handle
|
|
||||||
if err = syscall.GetConsoleMode(state.inHandle, &state.inMode); err != nil {
|
|
||||||
return state, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
defer winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode)
|
|
||||||
|
|
||||||
if err := winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode|enableVirtualTerminalInput); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
|
// 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
|
// RestoreTerminal restores the terminal connected to the given file descriptor
|
||||||
// to a previous state.
|
// to a previous state.
|
||||||
func RestoreTerminal(fd uintptr, state *State) error {
|
func RestoreTerminal(fd uintptr, state *State) error {
|
||||||
if usingNativeConsole {
|
return winterm.SetConsoleMode(fd, state.mode)
|
||||||
return disableNativeConsole(state)
|
|
||||||
}
|
|
||||||
return winterm.SetConsoleMode(fd, state.outMode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveState saves the state of the terminal connected to the given file descriptor.
|
// SaveState saves the state of the terminal connected to the given file descriptor.
|
||||||
func SaveState(fd uintptr) (*State, error) {
|
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)
|
mode, e := winterm.GetConsoleMode(fd)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return nil, e
|
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.
|
// 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
|
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
|
||||||
func DisableEcho(fd uintptr, state *State) error {
|
func DisableEcho(fd uintptr, state *State) error {
|
||||||
mode := state.inMode
|
mode := state.mode
|
||||||
mode &^= winterm.ENABLE_ECHO_INPUT
|
mode &^= winterm.ENABLE_ECHO_INPUT
|
||||||
mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
|
mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
|
||||||
err := winterm.SetConsoleMode(fd, mode)
|
err := winterm.SetConsoleMode(fd, mode)
|
||||||
|
@ -239,8 +155,9 @@ func DisableEcho(fd uintptr, state *State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRawTerminal puts the terminal connected to the given file descriptor into raw
|
// SetRawTerminal puts the terminal connected to the given file descriptor into
|
||||||
// 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) {
|
func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
state, err := MakeRaw(fd)
|
state, err := MakeRaw(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -252,6 +169,21 @@ func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
return state, err
|
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
|
// 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.
|
// mode and returns the previous state of the terminal so that it can be restored.
|
||||||
func MakeRaw(fd uintptr) (*State, error) {
|
func MakeRaw(fd uintptr) (*State, error) {
|
||||||
|
@ -260,13 +192,7 @@ func MakeRaw(fd uintptr) (*State, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mode := state.inMode
|
mode := state.mode
|
||||||
if usingNativeConsole {
|
|
||||||
if err := enableNativeConsole(*state); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mode |= enableVirtualTerminalInput
|
|
||||||
}
|
|
||||||
|
|
||||||
// See
|
// See
|
||||||
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
// -- 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_EXTENDED_FLAGS
|
||||||
mode |= winterm.ENABLE_INSERT_MODE
|
mode |= winterm.ENABLE_INSERT_MODE
|
||||||
mode |= winterm.ENABLE_QUICK_EDIT_MODE
|
mode |= winterm.ENABLE_QUICK_EDIT_MODE
|
||||||
|
if vtInputSupported {
|
||||||
|
mode |= enableVirtualTerminalInput
|
||||||
|
}
|
||||||
|
|
||||||
err = winterm.SetConsoleMode(fd, mode)
|
err = winterm.SetConsoleMode(fd, mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -27,7 +28,10 @@ type ansiReader struct {
|
||||||
command []byte
|
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)
|
file, fd := winterm.GetStdFile(nFile)
|
||||||
return &ansiReader{
|
return &ansiReader{
|
||||||
file: file,
|
file: file,
|
||||||
|
|
|
@ -3,16 +3,13 @@
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
ansiterm "github.com/Azure/go-ansiterm"
|
ansiterm "github.com/Azure/go-ansiterm"
|
||||||
"github.com/Azure/go-ansiterm/winterm"
|
"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.
|
// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation.
|
||||||
type ansiWriter struct {
|
type ansiWriter struct {
|
||||||
file *os.File
|
file *os.File
|
||||||
|
@ -24,19 +21,10 @@ type ansiWriter struct {
|
||||||
parser *ansiterm.AnsiParser
|
parser *ansiterm.AnsiParser
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAnsiWriter(nFile int) *ansiWriter {
|
// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
|
||||||
logFile := ioutil.Discard
|
// Windows console output handle.
|
||||||
|
func NewAnsiWriter(nFile int) io.Writer {
|
||||||
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
|
initLogger()
|
||||||
logFile, _ = os.Create("ansiReaderWriter.log")
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = &logrus.Logger{
|
|
||||||
Out: logFile,
|
|
||||||
Formatter: new(logrus.TextFormatter),
|
|
||||||
Level: logrus.DebugLevel,
|
|
||||||
}
|
|
||||||
|
|
||||||
file, fd := winterm.GetStdFile(nFile)
|
file, fd := winterm.GetStdFile(nFile)
|
||||||
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
62
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/console.go
generated
vendored
62
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/console.go
generated
vendored
|
@ -3,73 +3,11 @@
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/Azure/go-ansiterm/winterm"
|
"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.
|
// GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
|
||||||
func GetHandleInfo(in interface{}) (uintptr, bool) {
|
func GetHandleInfo(in interface{}) (uintptr, bool) {
|
||||||
switch t := in.(type) {
|
switch t := in.(type) {
|
||||||
|
|
28
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/windows.go
generated
vendored
28
libnetwork/Godeps/_workspace/src/github.com/docker/docker/pkg/term/windows/windows.go
generated
vendored
|
@ -3,3 +3,31 @@
|
||||||
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
||||||
|
|
||||||
package windows
|
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
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/.travis.yml
generated
vendored
Normal file
8
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/.travis.yml
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/README.md
generated
vendored
Normal file
47
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/README.md
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/shellwords.go
generated
vendored
Normal file
134
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/shellwords.go
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_posix.go
generated
vendored
Normal file
19
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_posix.go
generated
vendored
Normal file
|
@ -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
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_windows.go
generated
vendored
Normal file
17
libnetwork/Godeps/_workspace/src/github.com/mattn/go-shellwords/util_windows.go
generated
vendored
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"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
|
// CallFunc provides environment specific call utility to invoke backend functions from UI
|
||||||
|
|
|
@ -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.
|
|
@ -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.
|
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
flag "github.com/docker/libnetwork/client/mflag"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
|
flag "github.com/docker/libnetwork/client/mflag"
|
||||||
"github.com/docker/libnetwork/netutils"
|
"github.com/docker/libnetwork/netutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cluster
|
package cluster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/engine-api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"github.com/docker/docker/pkg/reexec"
|
"github.com/docker/docker/pkg/reexec"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/docker/pkg/term"
|
"github.com/docker/docker/pkg/term"
|
||||||
"github.com/docker/engine-api/types/network"
|
|
||||||
"github.com/docker/libnetwork"
|
"github.com/docker/libnetwork"
|
||||||
"github.com/docker/libnetwork/api"
|
"github.com/docker/libnetwork/api"
|
||||||
"github.com/docker/libnetwork/config"
|
"github.com/docker/libnetwork/config"
|
||||||
|
|
|
@ -13,7 +13,7 @@ func setupDumpStackTrap() {
|
||||||
signal.Notify(c, syscall.SIGUSR1)
|
signal.Notify(c, syscall.SIGUSR1)
|
||||||
go func() {
|
go func() {
|
||||||
for range c {
|
for range c {
|
||||||
psignal.DumpStacks()
|
psignal.DumpStacks("")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func setupDumpStackTrap() {
|
||||||
logrus.Debugf("Stackdump - waiting signal at %s", ev)
|
logrus.Debugf("Stackdump - waiting signal at %s", ev)
|
||||||
for {
|
for {
|
||||||
syscall.WaitForSingleObject(h, syscall.INFINITE)
|
syscall.WaitForSingleObject(h, syscall.INFINITE)
|
||||||
signal.DumpStacks()
|
signal.DumpStacks("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -218,7 +218,7 @@ func TestGetEmptyCapabilities(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newDriver(plugin, p.Client)
|
d := newDriver(plugin, p.Client())
|
||||||
if d.Type() != plugin {
|
if d.Type() != plugin {
|
||||||
t.Fatal("Driver type does not match that given")
|
t.Fatal("Driver type does not match that given")
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ func TestGetExtraCapabilities(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newDriver(plugin, p.Client)
|
d := newDriver(plugin, p.Client())
|
||||||
if d.Type() != plugin {
|
if d.Type() != plugin {
|
||||||
t.Fatal("Driver type does not match that given")
|
t.Fatal("Driver type does not match that given")
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ func TestGetInvalidCapabilities(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newDriver(plugin, p.Client)
|
d := newDriver(plugin, p.Client())
|
||||||
if d.Type() != plugin {
|
if d.Type() != plugin {
|
||||||
t.Fatal("Driver type does not match that given")
|
t.Fatal("Driver type does not match that given")
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ func TestRemoteDriver(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newDriver(plugin, p.Client)
|
d := newDriver(plugin, p.Client())
|
||||||
if d.Type() != plugin {
|
if d.Type() != plugin {
|
||||||
t.Fatal("Driver type does not match that given")
|
t.Fatal("Driver type does not match that given")
|
||||||
}
|
}
|
||||||
|
@ -469,7 +469,7 @@ func TestDriverError(t *testing.T) {
|
||||||
t.Fatal(err)
|
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 {
|
if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil {
|
||||||
t.Fatalf("Expected error from driver")
|
t.Fatalf("Expected error from driver")
|
||||||
|
@ -501,7 +501,7 @@ func TestMissingValues(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -562,7 +562,7 @@ func TestRollback(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
driver := newDriver(plugin, p.Client)
|
driver := newDriver(plugin, p.Client())
|
||||||
|
|
||||||
ep := &rollbackEndpoint{}
|
ep := &rollbackEndpoint{}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestGetCapabilities(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newAllocator(plugin, p.Client)
|
d := newAllocator(plugin, p.Client())
|
||||||
|
|
||||||
caps, err := d.(*allocator).getCapabilities()
|
caps, err := d.(*allocator).getCapabilities()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -102,7 +102,7 @@ func TestGetCapabilitiesFromLegacyDriver(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newAllocator(plugin, p.Client)
|
d := newAllocator(plugin, p.Client())
|
||||||
|
|
||||||
if _, err := d.(*allocator).getCapabilities(); err == nil {
|
if _, err := d.(*allocator).getCapabilities(); err == nil {
|
||||||
t.Fatalf("Expected error, but got Success %v", err)
|
t.Fatalf("Expected error, but got Success %v", err)
|
||||||
|
@ -127,7 +127,7 @@ func TestGetDefaultAddressSpaces(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newAllocator(plugin, p.Client)
|
d := newAllocator(plugin, p.Client())
|
||||||
|
|
||||||
l, g, err := d.(*allocator).GetDefaultAddressSpaces()
|
l, g, err := d.(*allocator).GetDefaultAddressSpaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -217,7 +217,7 @@ func TestRemoteDriver(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := newAllocator(plugin, p.Client)
|
d := newAllocator(plugin, p.Client())
|
||||||
|
|
||||||
l, g, err := d.(*allocator).GetDefaultAddressSpaces()
|
l, g, err := d.(*allocator).GetDefaultAddressSpaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue