From d9c62e1aca67de0cf3131d8aea17e2af7137159c Mon Sep 17 00:00:00 2001 From: Olli Janatuinen Date: Tue, 2 Apr 2019 20:14:30 +0300 Subject: [PATCH 1/2] Bump docker/docker to 827cb09f87964ed38b46502f22a585f2ed4a78e1 and docker/distribution to 0d3efadf0154c2b8a4e7b6621fff9809655cc580 Signed-off-by: Olli Janatuinen --- agent/exec/dockerapi/container.go | 2 +- agent/exec/dockerapi/container_test.go | 2 +- vendor.conf | 4 +- .../distribution/reference/normalize.go | 29 ++ .../distribution/reference/reference.go | 2 +- .../registry/api/errcode/errors.go | 267 ++++++++++++++++++ .../registry/api/errcode/handler.go | 40 +++ .../registry/api/errcode/register.go | 138 +++++++++ .../docker/distribution/vendor.conf | 18 +- .../docker/docker/api/types/client.go | 9 + .../docker/api/types/container/host_config.go | 20 +- .../docker/api/types/network/network.go | 13 +- .../docker/docker/api/types/seccomp.go | 5 +- .../docker/docker/api/types/swarm/config.go | 7 +- .../docker/api/types/swarm/container.go | 1 + .../docker/docker/api/types/types.go | 1 + .../github.com/docker/docker/client/README.md | 2 +- .../github.com/docker/docker/client/client.go | 158 +---------- .../docker/docker/client/client_deprecated.go | 23 ++ .../docker/docker/client/container_copy.go | 2 + .../docker/docker/client/container_create.go | 4 - .../github.com/docker/docker/client/errors.go | 28 +- .../docker/docker/client/image_build.go | 8 + .../docker/docker/client/image_pull.go | 4 +- .../docker/docker/client/image_push.go | 4 +- .../docker/docker/client/image_search.go | 4 +- .../github.com/docker/docker/client/login.go | 4 - .../docker/docker/client/options.go | 144 ++++++++++ .../github.com/docker/docker/client/ping.go | 55 +++- .../docker/docker/client/plugin_install.go | 4 +- .../docker/docker/client/request.go | 32 ++- .../docker/docker/errdefs/helpers.go | 56 ++-- .../docker/docker/errdefs/http_helpers.go | 172 +++++++++++ vendor/github.com/docker/docker/vendor.conf | 34 +-- 34 files changed, 1015 insertions(+), 281 deletions(-) create mode 100644 vendor/github.com/docker/distribution/registry/api/errcode/errors.go create mode 100644 vendor/github.com/docker/distribution/registry/api/errcode/handler.go create mode 100644 vendor/github.com/docker/distribution/registry/api/errcode/register.go create mode 100644 vendor/github.com/docker/docker/client/client_deprecated.go create mode 100644 vendor/github.com/docker/docker/client/options.go create mode 100644 vendor/github.com/docker/docker/errdefs/http_helpers.go diff --git a/agent/exec/dockerapi/container.go b/agent/exec/dockerapi/container.go index d0757b4875..51fbf9d2ba 100644 --- a/agent/exec/dockerapi/container.go +++ b/agent/exec/dockerapi/container.go @@ -442,7 +442,7 @@ func (c *containerConfig) resources() enginecontainer.Resources { // set pids limit pidsLimit := c.spec().PidsLimit if pidsLimit > 0 { - resources.PidsLimit = pidsLimit + resources.PidsLimit = &pidsLimit } // If no limits are specified let the engine use its defaults. diff --git a/agent/exec/dockerapi/container_test.go b/agent/exec/dockerapi/container_test.go index ad2950938e..9dfe79a908 100644 --- a/agent/exec/dockerapi/container_test.go +++ b/agent/exec/dockerapi/container_test.go @@ -190,7 +190,7 @@ func TestPidLimit(t *testing.T) { expected := int64(10) actual := hostConfig.PidsLimit - if expected != actual { + if expected != *actual { t.Fatalf("expected %d, got %d", expected, actual) } } diff --git a/vendor.conf b/vendor.conf index 3a2c8f729a..fe5089d91d 100644 --- a/vendor.conf +++ b/vendor.conf @@ -27,8 +27,8 @@ github.com/prometheus/client_model 6f3806018612930941127f2a7c6c453ba2c527d2 github.com/prometheus/common 7600349dcfe1abd18d72d3a1770870d9800a7801 github.com/prometheus/procfs 7d6f385de8bea29190f15ba9931442a0eaef9af7 -github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5 -github.com/docker/docker 5a718ef0f94f605fe4e4885937133c2f76ad2a41 +github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 +github.com/docker/docker 827cb09f87964ed38b46502f22a585f2ed4a78e1 github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 diff --git a/vendor/github.com/docker/distribution/reference/normalize.go b/vendor/github.com/docker/distribution/reference/normalize.go index 2d71fc5e9f..b3dfb7a6d7 100644 --- a/vendor/github.com/docker/distribution/reference/normalize.go +++ b/vendor/github.com/docker/distribution/reference/normalize.go @@ -56,6 +56,35 @@ func ParseNormalizedNamed(s string) (Named, error) { return named, nil } +// ParseDockerRef normalizes the image reference following the docker convention. This is added +// mainly for backward compatibility. +// The reference returned can only be either tagged or digested. For reference contains both tag +// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@ +// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as +// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa. +func ParseDockerRef(ref string) (Named, error) { + named, err := ParseNormalizedNamed(ref) + if err != nil { + return nil, err + } + if _, ok := named.(NamedTagged); ok { + if canonical, ok := named.(Canonical); ok { + // The reference is both tagged and digested, only + // return digested. + newNamed, err := WithName(canonical.Name()) + if err != nil { + return nil, err + } + newCanonical, err := WithDigest(newNamed, canonical.Digest()) + if err != nil { + return nil, err + } + return newCanonical, nil + } + } + return TagNameOnly(named), nil +} + // splitDockerDomain splits a repository name to domain and remotename string. // If no valid domain is found, the default domain is used. Repository name // needs to be already validated before. diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go index 2f66cca87a..8c0c23b2fe 100644 --- a/vendor/github.com/docker/distribution/reference/reference.go +++ b/vendor/github.com/docker/distribution/reference/reference.go @@ -205,7 +205,7 @@ func Parse(s string) (Reference, error) { var repo repository nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1]) - if nameMatch != nil && len(nameMatch) == 3 { + if len(nameMatch) == 3 { repo.domain = nameMatch[1] repo.path = nameMatch[2] } else { diff --git a/vendor/github.com/docker/distribution/registry/api/errcode/errors.go b/vendor/github.com/docker/distribution/registry/api/errcode/errors.go new file mode 100644 index 0000000000..4c35b879af --- /dev/null +++ b/vendor/github.com/docker/distribution/registry/api/errcode/errors.go @@ -0,0 +1,267 @@ +package errcode + +import ( + "encoding/json" + "fmt" + "strings" +) + +// ErrorCoder is the base interface for ErrorCode and Error allowing +// users of each to just call ErrorCode to get the real ID of each +type ErrorCoder interface { + ErrorCode() ErrorCode +} + +// ErrorCode represents the error type. The errors are serialized via strings +// and the integer format may change and should *never* be exported. +type ErrorCode int + +var _ error = ErrorCode(0) + +// ErrorCode just returns itself +func (ec ErrorCode) ErrorCode() ErrorCode { + return ec +} + +// Error returns the ID/Value +func (ec ErrorCode) Error() string { + // NOTE(stevvooe): Cannot use message here since it may have unpopulated args. + return strings.ToLower(strings.Replace(ec.String(), "_", " ", -1)) +} + +// Descriptor returns the descriptor for the error code. +func (ec ErrorCode) Descriptor() ErrorDescriptor { + d, ok := errorCodeToDescriptors[ec] + + if !ok { + return ErrorCodeUnknown.Descriptor() + } + + return d +} + +// String returns the canonical identifier for this error code. +func (ec ErrorCode) String() string { + return ec.Descriptor().Value +} + +// Message returned the human-readable error message for this error code. +func (ec ErrorCode) Message() string { + return ec.Descriptor().Message +} + +// MarshalText encodes the receiver into UTF-8-encoded text and returns the +// result. +func (ec ErrorCode) MarshalText() (text []byte, err error) { + return []byte(ec.String()), nil +} + +// UnmarshalText decodes the form generated by MarshalText. +func (ec *ErrorCode) UnmarshalText(text []byte) error { + desc, ok := idToDescriptors[string(text)] + + if !ok { + desc = ErrorCodeUnknown.Descriptor() + } + + *ec = desc.Code + + return nil +} + +// WithMessage creates a new Error struct based on the passed-in info and +// overrides the Message property. +func (ec ErrorCode) WithMessage(message string) Error { + return Error{ + Code: ec, + Message: message, + } +} + +// WithDetail creates a new Error struct based on the passed-in info and +// set the Detail property appropriately +func (ec ErrorCode) WithDetail(detail interface{}) Error { + return Error{ + Code: ec, + Message: ec.Message(), + }.WithDetail(detail) +} + +// WithArgs creates a new Error struct and sets the Args slice +func (ec ErrorCode) WithArgs(args ...interface{}) Error { + return Error{ + Code: ec, + Message: ec.Message(), + }.WithArgs(args...) +} + +// Error provides a wrapper around ErrorCode with extra Details provided. +type Error struct { + Code ErrorCode `json:"code"` + Message string `json:"message"` + Detail interface{} `json:"detail,omitempty"` + + // TODO(duglin): See if we need an "args" property so we can do the + // variable substitution right before showing the message to the user +} + +var _ error = Error{} + +// ErrorCode returns the ID/Value of this Error +func (e Error) ErrorCode() ErrorCode { + return e.Code +} + +// Error returns a human readable representation of the error. +func (e Error) Error() string { + return fmt.Sprintf("%s: %s", e.Code.Error(), e.Message) +} + +// WithDetail will return a new Error, based on the current one, but with +// some Detail info added +func (e Error) WithDetail(detail interface{}) Error { + return Error{ + Code: e.Code, + Message: e.Message, + Detail: detail, + } +} + +// WithArgs uses the passed-in list of interface{} as the substitution +// variables in the Error's Message string, but returns a new Error +func (e Error) WithArgs(args ...interface{}) Error { + return Error{ + Code: e.Code, + Message: fmt.Sprintf(e.Code.Message(), args...), + Detail: e.Detail, + } +} + +// ErrorDescriptor provides relevant information about a given error code. +type ErrorDescriptor struct { + // Code is the error code that this descriptor describes. + Code ErrorCode + + // Value provides a unique, string key, often captilized with + // underscores, to identify the error code. This value is used as the + // keyed value when serializing api errors. + Value string + + // Message is a short, human readable decription of the error condition + // included in API responses. + Message string + + // Description provides a complete account of the errors purpose, suitable + // for use in documentation. + Description string + + // HTTPStatusCode provides the http status code that is associated with + // this error condition. + HTTPStatusCode int +} + +// ParseErrorCode returns the value by the string error code. +// `ErrorCodeUnknown` will be returned if the error is not known. +func ParseErrorCode(value string) ErrorCode { + ed, ok := idToDescriptors[value] + if ok { + return ed.Code + } + + return ErrorCodeUnknown +} + +// Errors provides the envelope for multiple errors and a few sugar methods +// for use within the application. +type Errors []error + +var _ error = Errors{} + +func (errs Errors) Error() string { + switch len(errs) { + case 0: + return "" + case 1: + return errs[0].Error() + default: + msg := "errors:\n" + for _, err := range errs { + msg += err.Error() + "\n" + } + return msg + } +} + +// Len returns the current number of errors. +func (errs Errors) Len() int { + return len(errs) +} + +// MarshalJSON converts slice of error, ErrorCode or Error into a +// slice of Error - then serializes +func (errs Errors) MarshalJSON() ([]byte, error) { + var tmpErrs struct { + Errors []Error `json:"errors,omitempty"` + } + + for _, daErr := range errs { + var err Error + + switch daErr := daErr.(type) { + case ErrorCode: + err = daErr.WithDetail(nil) + case Error: + err = daErr + default: + err = ErrorCodeUnknown.WithDetail(daErr) + + } + + // If the Error struct was setup and they forgot to set the + // Message field (meaning its "") then grab it from the ErrCode + msg := err.Message + if msg == "" { + msg = err.Code.Message() + } + + tmpErrs.Errors = append(tmpErrs.Errors, Error{ + Code: err.Code, + Message: msg, + Detail: err.Detail, + }) + } + + return json.Marshal(tmpErrs) +} + +// UnmarshalJSON deserializes []Error and then converts it into slice of +// Error or ErrorCode +func (errs *Errors) UnmarshalJSON(data []byte) error { + var tmpErrs struct { + Errors []Error + } + + if err := json.Unmarshal(data, &tmpErrs); err != nil { + return err + } + + var newErrs Errors + for _, daErr := range tmpErrs.Errors { + // If Message is empty or exactly matches the Code's message string + // then just use the Code, no need for a full Error struct + if daErr.Detail == nil && (daErr.Message == "" || daErr.Message == daErr.Code.Message()) { + // Error's w/o details get converted to ErrorCode + newErrs = append(newErrs, daErr.Code) + } else { + // Error's w/ details are untouched + newErrs = append(newErrs, Error{ + Code: daErr.Code, + Message: daErr.Message, + Detail: daErr.Detail, + }) + } + } + + *errs = newErrs + return nil +} diff --git a/vendor/github.com/docker/distribution/registry/api/errcode/handler.go b/vendor/github.com/docker/distribution/registry/api/errcode/handler.go new file mode 100644 index 0000000000..d77e70473e --- /dev/null +++ b/vendor/github.com/docker/distribution/registry/api/errcode/handler.go @@ -0,0 +1,40 @@ +package errcode + +import ( + "encoding/json" + "net/http" +) + +// ServeJSON attempts to serve the errcode in a JSON envelope. It marshals err +// and sets the content-type header to 'application/json'. It will handle +// ErrorCoder and Errors, and if necessary will create an envelope. +func ServeJSON(w http.ResponseWriter, err error) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + var sc int + + switch errs := err.(type) { + case Errors: + if len(errs) < 1 { + break + } + + if err, ok := errs[0].(ErrorCoder); ok { + sc = err.ErrorCode().Descriptor().HTTPStatusCode + } + case ErrorCoder: + sc = errs.ErrorCode().Descriptor().HTTPStatusCode + err = Errors{err} // create an envelope. + default: + // We just have an unhandled error type, so just place in an envelope + // and move along. + err = Errors{err} + } + + if sc == 0 { + sc = http.StatusInternalServerError + } + + w.WriteHeader(sc) + + return json.NewEncoder(w).Encode(err) +} diff --git a/vendor/github.com/docker/distribution/registry/api/errcode/register.go b/vendor/github.com/docker/distribution/registry/api/errcode/register.go new file mode 100644 index 0000000000..d1e8826c6d --- /dev/null +++ b/vendor/github.com/docker/distribution/registry/api/errcode/register.go @@ -0,0 +1,138 @@ +package errcode + +import ( + "fmt" + "net/http" + "sort" + "sync" +) + +var ( + errorCodeToDescriptors = map[ErrorCode]ErrorDescriptor{} + idToDescriptors = map[string]ErrorDescriptor{} + groupToDescriptors = map[string][]ErrorDescriptor{} +) + +var ( + // ErrorCodeUnknown is a generic error that can be used as a last + // resort if there is no situation-specific error message that can be used + ErrorCodeUnknown = Register("errcode", ErrorDescriptor{ + Value: "UNKNOWN", + Message: "unknown error", + Description: `Generic error returned when the error does not have an + API classification.`, + HTTPStatusCode: http.StatusInternalServerError, + }) + + // ErrorCodeUnsupported is returned when an operation is not supported. + ErrorCodeUnsupported = Register("errcode", ErrorDescriptor{ + Value: "UNSUPPORTED", + Message: "The operation is unsupported.", + Description: `The operation was unsupported due to a missing + implementation or invalid set of parameters.`, + HTTPStatusCode: http.StatusMethodNotAllowed, + }) + + // ErrorCodeUnauthorized is returned if a request requires + // authentication. + ErrorCodeUnauthorized = Register("errcode", ErrorDescriptor{ + Value: "UNAUTHORIZED", + Message: "authentication required", + Description: `The access controller was unable to authenticate + the client. Often this will be accompanied by a + Www-Authenticate HTTP response header indicating how to + authenticate.`, + HTTPStatusCode: http.StatusUnauthorized, + }) + + // ErrorCodeDenied is returned if a client does not have sufficient + // permission to perform an action. + ErrorCodeDenied = Register("errcode", ErrorDescriptor{ + Value: "DENIED", + Message: "requested access to the resource is denied", + Description: `The access controller denied access for the + operation on a resource.`, + HTTPStatusCode: http.StatusForbidden, + }) + + // ErrorCodeUnavailable provides a common error to report unavailability + // of a service or endpoint. + ErrorCodeUnavailable = Register("errcode", ErrorDescriptor{ + Value: "UNAVAILABLE", + Message: "service unavailable", + Description: "Returned when a service is not available", + HTTPStatusCode: http.StatusServiceUnavailable, + }) + + // ErrorCodeTooManyRequests is returned if a client attempts too many + // times to contact a service endpoint. + ErrorCodeTooManyRequests = Register("errcode", ErrorDescriptor{ + Value: "TOOMANYREQUESTS", + Message: "too many requests", + Description: `Returned when a client attempts to contact a + service too many times`, + HTTPStatusCode: http.StatusTooManyRequests, + }) +) + +var nextCode = 1000 +var registerLock sync.Mutex + +// Register will make the passed-in error known to the environment and +// return a new ErrorCode +func Register(group string, descriptor ErrorDescriptor) ErrorCode { + registerLock.Lock() + defer registerLock.Unlock() + + descriptor.Code = ErrorCode(nextCode) + + if _, ok := idToDescriptors[descriptor.Value]; ok { + panic(fmt.Sprintf("ErrorValue %q is already registered", descriptor.Value)) + } + if _, ok := errorCodeToDescriptors[descriptor.Code]; ok { + panic(fmt.Sprintf("ErrorCode %v is already registered", descriptor.Code)) + } + + groupToDescriptors[group] = append(groupToDescriptors[group], descriptor) + errorCodeToDescriptors[descriptor.Code] = descriptor + idToDescriptors[descriptor.Value] = descriptor + + nextCode++ + return descriptor.Code +} + +type byValue []ErrorDescriptor + +func (a byValue) Len() int { return len(a) } +func (a byValue) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byValue) Less(i, j int) bool { return a[i].Value < a[j].Value } + +// GetGroupNames returns the list of Error group names that are registered +func GetGroupNames() []string { + keys := []string{} + + for k := range groupToDescriptors { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +// GetErrorCodeGroup returns the named group of error descriptors +func GetErrorCodeGroup(name string) []ErrorDescriptor { + desc := groupToDescriptors[name] + sort.Sort(byValue(desc)) + return desc +} + +// GetErrorAllDescriptors returns a slice of all ErrorDescriptors that are +// registered, irrespective of what group they're in +func GetErrorAllDescriptors() []ErrorDescriptor { + result := []ErrorDescriptor{} + + for _, group := range GetGroupNames() { + result = append(result, GetErrorCodeGroup(group)...) + } + sort.Sort(byValue(result)) + return result +} diff --git a/vendor/github.com/docker/distribution/vendor.conf b/vendor/github.com/docker/distribution/vendor.conf index d0ebadf8b9..12f71672f3 100644 --- a/vendor/github.com/docker/distribution/vendor.conf +++ b/vendor/github.com/docker/distribution/vendor.conf @@ -1,16 +1,15 @@ -github.com/Azure/azure-sdk-for-go 088007b3b08cc02b27f2eadfdcd870958460ce7e -github.com/Azure/go-autorest ec5f4903f77ed9927ac95b19ab8e44ada64c1356 +github.com/Azure/azure-sdk-for-go 4650843026a7fdec254a8d9cf893693a254edd0b +github.com/Azure/go-autorest eaa7994b2278094c904d31993d26f56324db3052 github.com/sirupsen/logrus 3d4380f53a34dcdc95f0c1db702615992b38d9a4 -github.com/aws/aws-sdk-go 5bcc0a238d880469f949fc7cd24e35f32ab80cbd +github.com/aws/aws-sdk-go f831d5a0822a1ad72420ab18c6269bca1ddaf490 github.com/bshuster-repo/logrus-logstash-hook d2c0ecc1836d91814e15e23bb5dc309c3ef51f4a github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 github.com/bugsnag/bugsnag-go b1d153021fcd90ca3f080db36bec96dc690fb274 github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702 github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782 -github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2 +github.com/denverdino/aliyungo 6df11717a253d9c7d4141f9af4deaa7c580cd531 github.com/dgrijalva/jwt-go a601269ab70c205d26370c16f7c81e9017c14e04 github.com/docker/go-metrics 399ea8c73916000c64c2c76e8da00ca82f8387ab -github.com/docker/goamz f0a21f5b2e12f83a505ecf79b633bb2035cf6f85 github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21 github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257 github.com/go-ini/ini 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c @@ -19,17 +18,19 @@ github.com/gorilla/handlers 60c7bfde3e33c201519a200a4507a158cc03a17b github.com/gorilla/mux 599cba5e7b6137d46ddf58fb1765f5d928e69604 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d +github.com/marstr/guid 8bd9a64bf37eb297b492a4101fb28e80ac0b290f +github.com/satori/go.uuid f58768cc1a7a7e77a3bd49e98cdd21419399b6a3 github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c github.com/miekg/dns 271c58e0c14f552178ea321a545ff9af38930f39 github.com/mitchellh/mapstructure 482a9fd5fa83e8c4e7817413b80f3eb8feec03ef -github.com/ncw/swift b964f2ca856aac39885e258ad25aec08d5f64ee6 +github.com/ncw/swift a0320860b16212c2b59b4912bb6508cda1d7cee6 github.com/prometheus/client_golang c332b6f63c0658a65eca15c0e5247ded801cf564 github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563 github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd +github.com/Shopify/logrus-bugsnag 577dee27f20dd8f1a529f82210094af593be12bd github.com/spf13/cobra 312092086bed4968099259622145a0c9ae280064 github.com/spf13/pflag 5644820622454e71517561946e3d94b9f9db6842 -github.com/stevvooe/resumable 2aaf90b2ceea5072cb503ef2a620b08ff3119870 github.com/xenolf/lego a9d8cec0e6563575e5868a005359ac97911b5985 github.com/yvasiyarov/go-metrics 57bccd1ccd43f94bb17fdd8bf3007059b802f85e github.com/yvasiyarov/gorelic a9bba5b9ab508a086f9a12b8c51fab68478e2128 @@ -44,6 +45,7 @@ google.golang.org/cloud 975617b05ea8a58727e6c1a06b6161ff4185a9f2 google.golang.org/grpc d3ddb4469d5a1b949fc7a7da7c1d6a0d1b6de994 gopkg.in/check.v1 64131543e7896d5bcc6bd5a76287eb75ea96c673 gopkg.in/square/go-jose.v1 40d457b439244b546f023d056628e5184136899b -gopkg.in/yaml.v2 bef53efd0c76e49e6de55ead051f886bea7e9420 +gopkg.in/yaml.v2 v2.2.1 rsc.io/letsencrypt e770c10b0f1a64775ae91d240407ce00d1a5bdeb https://github.com/dmcgowan/letsencrypt.git github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb +github.com/opencontainers/image-spec ab7389ef9f50030c9b245bc16b981c7ddf192882 diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index 3b698c2c24..4b9f50282b 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -187,6 +187,15 @@ type ImageBuildOptions struct { // build request. The same identifier can be used to gracefully cancel the // build with the cancel request. BuildID string + // Outputs defines configurations for exporting build results. Only supported + // in BuildKit mode + Outputs []ImageBuildOutput +} + +// ImageBuildOutput defines configuration for exporting a build result +type ImageBuildOutput struct { + Type string + Attrs map[string]string } // BuilderVersion sets the version of underlying builder to use diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go index 44bdfec962..c710107702 100644 --- a/vendor/github.com/docker/docker/api/types/container/host_config.go +++ b/vendor/github.com/docker/docker/api/types/container/host_config.go @@ -244,6 +244,16 @@ func (n PidMode) Container() string { return "" } +// DeviceRequest represents a request for devices from a device driver. +// Used by GPU device drivers. +type DeviceRequest struct { + Driver string // Name of device driver + Count int // Number of devices to request (-1 = All) + DeviceIDs []string // List of device IDs as recognizable by the device driver + Capabilities [][]string // An OR list of AND lists of device capabilities (e.g. "gpu") + Options map[string]string // Options to pass onto the device driver +} + // DeviceMapping represents the device mapping between the host and the container. type DeviceMapping struct { PathOnHost string @@ -327,6 +337,7 @@ type Resources struct { CpusetMems string // CpusetMems 0-2, 0,1 Devices []DeviceMapping // List of devices to map inside the container DeviceCgroupRules []string // List of rule to be added to the device cgroup + DeviceRequests []DeviceRequest // List of device requests for device drivers DiskQuota int64 // Disk limit (in bytes) KernelMemory int64 // Kernel memory limit (in bytes) KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes) @@ -334,7 +345,7 @@ type Resources struct { MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap MemorySwappiness *int64 // Tuning container memory swappiness behaviour OomKillDisable *bool // Whether to disable OOM Killer or not - PidsLimit int64 // Setting pids limit for a container + PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change. Ulimits []*units.Ulimit // List of ulimits to be set in the container // Applicable to Windows @@ -370,9 +381,10 @@ type HostConfig struct { // Applicable to UNIX platforms CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for + Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set) + DNS []string `json:"Dns"` // List of DNS server to lookup + DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for + DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for ExtraHosts []string // List of extra hosts GroupAdd []string // List of additional groups that the container process will run as IpcMode IpcMode // IPC namespace to use for the container diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/docker/docker/api/types/network/network.go index ccb448f23a..71e97338fd 100644 --- a/vendor/github.com/docker/docker/api/types/network/network.go +++ b/vendor/github.com/docker/docker/api/types/network/network.go @@ -112,12 +112,13 @@ type ConfigReference struct { } var acceptedFilters = map[string]bool{ - "driver": true, - "type": true, - "name": true, - "id": true, - "label": true, - "scope": true, + "dangling": true, + "driver": true, + "id": true, + "label": true, + "name": true, + "scope": true, + "type": true, } // ValidateFilters validates the list of filter args with the available filters. diff --git a/vendor/github.com/docker/docker/api/types/seccomp.go b/vendor/github.com/docker/docker/api/types/seccomp.go index 67a41e1a89..2259c6be1e 100644 --- a/vendor/github.com/docker/docker/api/types/seccomp.go +++ b/vendor/github.com/docker/docker/api/types/seccomp.go @@ -77,8 +77,9 @@ type Arg struct { // Filter is used to conditionally apply Seccomp rules type Filter struct { - Caps []string `json:"caps,omitempty"` - Arches []string `json:"arches,omitempty"` + Caps []string `json:"caps,omitempty"` + Arches []string `json:"arches,omitempty"` + MinKernel string `json:"minKernel,omitempty"` } // Syscall is used to match a group of syscalls in Seccomp diff --git a/vendor/github.com/docker/docker/api/types/swarm/config.go b/vendor/github.com/docker/docker/api/types/swarm/config.go index a1555cf43e..16202ccce6 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/config.go +++ b/vendor/github.com/docker/docker/api/types/swarm/config.go @@ -27,9 +27,14 @@ type ConfigReferenceFileTarget struct { Mode os.FileMode } +// ConfigReferenceRuntimeTarget is a target for a config specifying that it +// isn't mounted into the container but instead has some other purpose. +type ConfigReferenceRuntimeTarget struct{} + // ConfigReference is a reference to a config in swarm type ConfigReference struct { - File *ConfigReferenceFileTarget + File *ConfigReferenceFileTarget `json:",omitempty"` + Runtime *ConfigReferenceRuntimeTarget `json:",omitempty"` ConfigID string ConfigName string } diff --git a/vendor/github.com/docker/docker/api/types/swarm/container.go b/vendor/github.com/docker/docker/api/types/swarm/container.go index e12f09837f..48190c1762 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/container.go +++ b/vendor/github.com/docker/docker/api/types/swarm/container.go @@ -33,6 +33,7 @@ type SELinuxContext struct { // CredentialSpec for managed service account (Windows only) type CredentialSpec struct { + Config string File string Registry string } diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index 2accda9d07..a39ffcb7be 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -163,6 +163,7 @@ type Info struct { CPUCfsQuota bool `json:"CpuCfsQuota"` CPUShares bool CPUSet bool + PidsLimit bool IPv4Forwarding bool BridgeNfIptables bool BridgeNfIP6tables bool `json:"BridgeNfIp6tables"` diff --git a/vendor/github.com/docker/docker/client/README.md b/vendor/github.com/docker/docker/client/README.md index 059dfb3ce7..992f18117d 100644 --- a/vendor/github.com/docker/docker/client/README.md +++ b/vendor/github.com/docker/docker/client/README.md @@ -16,7 +16,7 @@ import ( ) func main() { - cli, err := client.NewEnvClient() + cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { panic(err) } diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index fa66850c39..0b7b4d953c 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -23,7 +23,7 @@ For example, to list running containers (the equivalent of "docker ps"): ) func main() { - cli, err := client.NewEnvClient() + cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { panic(err) } @@ -47,16 +47,13 @@ import ( "net" "net/http" "net/url" - "os" "path" - "path/filepath" "strings" "github.com/docker/docker/api" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions" "github.com/docker/go-connections/sockets" - "github.com/docker/go-connections/tlsconfig" "github.com/pkg/errors" ) @@ -90,7 +87,7 @@ type Client struct { // If the request is non-GET return `ErrRedirect`. Otherwise use the last response. // // Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client . -// The Docker client (and by extension docker API client) can be made to to send a request +// The Docker client (and by extension docker API client) can be made to send a request // like POST /containers//start where what would normally be in the name section of the URL is empty. // This triggers an HTTP 301 from the daemon. // In go 1.8 this 301 will be converted to a GET request, and ends up getting a 404 from the daemon. @@ -103,145 +100,6 @@ func CheckRedirect(req *http.Request, via []*http.Request) error { return ErrRedirect } -// NewEnvClient initializes a new API client based on environment variables. -// See FromEnv for a list of support environment variables. -// -// Deprecated: use NewClientWithOpts(FromEnv) -func NewEnvClient() (*Client, error) { - return NewClientWithOpts(FromEnv) -} - -// FromEnv configures the client with values from environment variables. -// -// Supported environment variables: -// DOCKER_HOST to set the url to the docker server. -// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest. -// DOCKER_CERT_PATH to load the TLS certificates from. -// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default. -func FromEnv(c *Client) error { - if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" { - options := tlsconfig.Options{ - CAFile: filepath.Join(dockerCertPath, "ca.pem"), - CertFile: filepath.Join(dockerCertPath, "cert.pem"), - KeyFile: filepath.Join(dockerCertPath, "key.pem"), - InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "", - } - tlsc, err := tlsconfig.Client(options) - if err != nil { - return err - } - - c.client = &http.Client{ - Transport: &http.Transport{TLSClientConfig: tlsc}, - CheckRedirect: CheckRedirect, - } - } - - if host := os.Getenv("DOCKER_HOST"); host != "" { - if err := WithHost(host)(c); err != nil { - return err - } - } - - if version := os.Getenv("DOCKER_API_VERSION"); version != "" { - c.version = version - c.manualOverride = true - } - return nil -} - -// WithTLSClientConfig applies a tls config to the client transport. -func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error { - return func(c *Client) error { - opts := tlsconfig.Options{ - CAFile: cacertPath, - CertFile: certPath, - KeyFile: keyPath, - ExclusiveRootPools: true, - } - config, err := tlsconfig.Client(opts) - if err != nil { - return errors.Wrap(err, "failed to create tls config") - } - if transport, ok := c.client.Transport.(*http.Transport); ok { - transport.TLSClientConfig = config - return nil - } - return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport) - } -} - -// WithDialer applies the dialer.DialContext to the client transport. This can be -// used to set the Timeout and KeepAlive settings of the client. -// Deprecated: use WithDialContext -func WithDialer(dialer *net.Dialer) func(*Client) error { - return WithDialContext(dialer.DialContext) -} - -// WithDialContext applies the dialer to the client transport. This can be -// used to set the Timeout and KeepAlive settings of the client. -func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) func(*Client) error { - return func(c *Client) error { - if transport, ok := c.client.Transport.(*http.Transport); ok { - transport.DialContext = dialContext - return nil - } - return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport) - } -} - -// WithVersion overrides the client version with the specified one -func WithVersion(version string) func(*Client) error { - return func(c *Client) error { - c.version = version - return nil - } -} - -// WithHost overrides the client host with the specified one. -func WithHost(host string) func(*Client) error { - return func(c *Client) error { - hostURL, err := ParseHostURL(host) - if err != nil { - return err - } - c.host = host - c.proto = hostURL.Scheme - c.addr = hostURL.Host - c.basePath = hostURL.Path - if transport, ok := c.client.Transport.(*http.Transport); ok { - return sockets.ConfigureTransport(transport, c.proto, c.addr) - } - return errors.Errorf("cannot apply host to transport: %T", c.client.Transport) - } -} - -// WithHTTPClient overrides the client http client with the specified one -func WithHTTPClient(client *http.Client) func(*Client) error { - return func(c *Client) error { - if client != nil { - c.client = client - } - return nil - } -} - -// WithHTTPHeaders overrides the client default http headers -func WithHTTPHeaders(headers map[string]string) func(*Client) error { - return func(c *Client) error { - c.customHTTPHeaders = headers - return nil - } -} - -// WithScheme overrides the client scheme with the specified one -func WithScheme(scheme string) func(*Client) error { - return func(c *Client) error { - c.scheme = scheme - return nil - } -} - // NewClientWithOpts initializes a new API client with default values. It takes functors // to modify values when creating it, like `NewClientWithOpts(WithVersion(…))` // It also initializes the custom http headers to add to each request. @@ -301,18 +159,6 @@ func defaultHTTPClient(host string) (*http.Client, error) { }, nil } -// NewClient initializes a new API client for the given host and API version. -// It uses the given http client as transport. -// It also initializes the custom http headers to add to each request. -// -// It won't send any version information if the version number is empty. It is -// highly recommended that you set a version or your client may break if the -// server is upgraded. -// Deprecated: use NewClientWithOpts -func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) { - return NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders)) -} - // Close the transport used by the client func (cli *Client) Close() error { if t, ok := cli.client.Transport.(*http.Transport); ok { diff --git a/vendor/github.com/docker/docker/client/client_deprecated.go b/vendor/github.com/docker/docker/client/client_deprecated.go new file mode 100644 index 0000000000..54cdfc29a8 --- /dev/null +++ b/vendor/github.com/docker/docker/client/client_deprecated.go @@ -0,0 +1,23 @@ +package client + +import "net/http" + +// NewClient initializes a new API client for the given host and API version. +// It uses the given http client as transport. +// It also initializes the custom http headers to add to each request. +// +// It won't send any version information if the version number is empty. It is +// highly recommended that you set a version or your client may break if the +// server is upgraded. +// Deprecated: use NewClientWithOpts +func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) { + return NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders)) +} + +// NewEnvClient initializes a new API client based on environment variables. +// See FromEnv for a list of support environment variables. +// +// Deprecated: use NewClientWithOpts(FromEnv) +func NewEnvClient() (*Client, error) { + return NewClientWithOpts(FromEnv) +} diff --git a/vendor/github.com/docker/docker/client/container_copy.go b/vendor/github.com/docker/docker/client/container_copy.go index d706260cee..83504ac3ce 100644 --- a/vendor/github.com/docker/docker/client/container_copy.go +++ b/vendor/github.com/docker/docker/client/container_copy.go @@ -50,6 +50,7 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str } defer ensureReaderClosed(response) + // TODO this code converts non-error status-codes (e.g., "204 No Content") into an error; verify if this is the desired behavior if response.statusCode != http.StatusOK { return fmt.Errorf("unexpected status code from daemon: %d", response.statusCode) } @@ -69,6 +70,7 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath) } + // TODO this code converts non-error status-codes (e.g., "204 No Content") into an error; verify if this is the desired behavior if response.statusCode != http.StatusOK { return nil, types.ContainerPathStat{}, fmt.Errorf("unexpected status code from daemon: %d", response.statusCode) } diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index d269a61894..3c9e9c55b7 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "net/url" - "strings" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" @@ -44,9 +43,6 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config serverResp, err := cli.post(ctx, "/containers/create", query, body, nil) if err != nil { - if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") { - return response, objectNotFoundError{object: "image", id: config.Image} - } return response, err } diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go index 0461af329d..001c102881 100644 --- a/vendor/github.com/docker/docker/client/errors.go +++ b/vendor/github.com/docker/docker/client/errors.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/docker/docker/api/types/versions" + "github.com/docker/docker/errdefs" "github.com/pkg/errors" ) @@ -32,16 +33,19 @@ func ErrorConnectionFailed(host string) error { return errConnectionFailed{host: host} } +// Deprecated: use the errdefs.NotFound() interface instead. Kept for backward compatibility type notFound interface { error - NotFound() bool // Is the error a NotFound error + NotFound() bool } // IsErrNotFound returns true if the error is a NotFound error, which is returned // by the API when some object is not found. func IsErrNotFound(err error) bool { - te, ok := err.(notFound) - return ok && te.NotFound() + if _, ok := err.(notFound); ok { + return ok + } + return errdefs.IsNotFound(err) } type objectNotFoundError struct { @@ -49,9 +53,7 @@ type objectNotFoundError struct { id string } -func (e objectNotFoundError) NotFound() bool { - return true -} +func (e objectNotFoundError) NotFound() {} func (e objectNotFoundError) Error() string { return fmt.Sprintf("Error: No such %s: %s", e.object, e.id) @@ -64,7 +66,7 @@ func wrapResponseError(err error, resp serverResponse, object, id string) error case resp.statusCode == http.StatusNotFound: return objectNotFoundError{object: object, id: id} case resp.statusCode == http.StatusNotImplemented: - return notImplementedError{message: err.Error()} + return errdefs.NotImplemented(err) default: return err } @@ -83,8 +85,10 @@ func (u unauthorizedError) Error() string { // IsErrUnauthorized returns true if the error is caused // when a remote registry authentication fails func IsErrUnauthorized(err error) bool { - _, ok := err.(unauthorizedError) - return ok + if _, ok := err.(unauthorizedError); ok { + return ok + } + return errdefs.IsUnauthorized(err) } type pluginPermissionDenied struct { @@ -118,8 +122,10 @@ func (e notImplementedError) NotImplemented() bool { // This is returned by the API when a requested feature has not been // implemented. func IsErrNotImplemented(err error) bool { - te, ok := err.(notImplementedError) - return ok && te.NotImplemented() + if _, ok := err.(notImplementedError); ok { + return ok + } + return errdefs.IsNotImplemented(err) } // NewVersionError returns an error if the APIVersion required diff --git a/vendor/github.com/docker/docker/client/image_build.go b/vendor/github.com/docker/docker/client/image_build.go index 9add3c10b3..8fcf995036 100644 --- a/vendor/github.com/docker/docker/client/image_build.go +++ b/vendor/github.com/docker/docker/client/image_build.go @@ -134,5 +134,13 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur query.Set("buildid", options.BuildID) } query.Set("version", string(options.Version)) + + if options.Outputs != nil { + outputsJSON, err := json.Marshal(options.Outputs) + if err != nil { + return query, err + } + query.Set("outputs", string(outputsJSON)) + } return query, nil } diff --git a/vendor/github.com/docker/docker/client/image_pull.go b/vendor/github.com/docker/docker/client/image_pull.go index d97aacf8c5..a23975591b 100644 --- a/vendor/github.com/docker/docker/client/image_pull.go +++ b/vendor/github.com/docker/docker/client/image_pull.go @@ -3,12 +3,12 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" - "net/http" "net/url" "strings" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/errdefs" ) // ImagePull requests the docker host to pull an image from a remote registry. @@ -35,7 +35,7 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options types.I } resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { + if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr diff --git a/vendor/github.com/docker/docker/client/image_push.go b/vendor/github.com/docker/docker/client/image_push.go index a15871c2b4..49d412ee37 100644 --- a/vendor/github.com/docker/docker/client/image_push.go +++ b/vendor/github.com/docker/docker/client/image_push.go @@ -4,11 +4,11 @@ import ( "context" "errors" "io" - "net/http" "net/url" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/errdefs" ) // ImagePush requests the docker host to push an image to a remote registry. @@ -36,7 +36,7 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im query.Set("tag", tag) resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { + if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr diff --git a/vendor/github.com/docker/docker/client/image_search.go b/vendor/github.com/docker/docker/client/image_search.go index 176de3c582..bbdf9e153e 100644 --- a/vendor/github.com/docker/docker/client/image_search.go +++ b/vendor/github.com/docker/docker/client/image_search.go @@ -4,12 +4,12 @@ import ( "context" "encoding/json" "fmt" - "net/http" "net/url" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/errdefs" ) // ImageSearch makes the docker host to search by a term in a remote registry. @@ -29,7 +29,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I } resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { + if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return results, privilegeErr diff --git a/vendor/github.com/docker/docker/client/login.go b/vendor/github.com/docker/docker/client/login.go index 7d66181900..472edc9037 100644 --- a/vendor/github.com/docker/docker/client/login.go +++ b/vendor/github.com/docker/docker/client/login.go @@ -3,7 +3,6 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" - "net/http" "net/url" "github.com/docker/docker/api/types" @@ -15,9 +14,6 @@ import ( func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error) { resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil) - if resp.statusCode == http.StatusUnauthorized { - return registry.AuthenticateOKBody{}, unauthorizedError{err} - } if err != nil { return registry.AuthenticateOKBody{}, err } diff --git a/vendor/github.com/docker/docker/client/options.go b/vendor/github.com/docker/docker/client/options.go new file mode 100644 index 0000000000..12eb25b18e --- /dev/null +++ b/vendor/github.com/docker/docker/client/options.go @@ -0,0 +1,144 @@ +package client + +import ( + "context" + "net" + "net/http" + "os" + "path/filepath" + + "github.com/docker/go-connections/sockets" + "github.com/docker/go-connections/tlsconfig" + "github.com/pkg/errors" +) + +// FromEnv configures the client with values from environment variables. +// +// Supported environment variables: +// DOCKER_HOST to set the url to the docker server. +// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest. +// DOCKER_CERT_PATH to load the TLS certificates from. +// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default. +func FromEnv(c *Client) error { + if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" { + options := tlsconfig.Options{ + CAFile: filepath.Join(dockerCertPath, "ca.pem"), + CertFile: filepath.Join(dockerCertPath, "cert.pem"), + KeyFile: filepath.Join(dockerCertPath, "key.pem"), + InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "", + } + tlsc, err := tlsconfig.Client(options) + if err != nil { + return err + } + + c.client = &http.Client{ + Transport: &http.Transport{TLSClientConfig: tlsc}, + CheckRedirect: CheckRedirect, + } + } + + if host := os.Getenv("DOCKER_HOST"); host != "" { + if err := WithHost(host)(c); err != nil { + return err + } + } + + if version := os.Getenv("DOCKER_API_VERSION"); version != "" { + c.version = version + c.manualOverride = true + } + return nil +} + +// WithDialer applies the dialer.DialContext to the client transport. This can be +// used to set the Timeout and KeepAlive settings of the client. +// Deprecated: use WithDialContext +func WithDialer(dialer *net.Dialer) func(*Client) error { + return WithDialContext(dialer.DialContext) +} + +// WithDialContext applies the dialer to the client transport. This can be +// used to set the Timeout and KeepAlive settings of the client. +func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) func(*Client) error { + return func(c *Client) error { + if transport, ok := c.client.Transport.(*http.Transport); ok { + transport.DialContext = dialContext + return nil + } + return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport) + } +} + +// WithHost overrides the client host with the specified one. +func WithHost(host string) func(*Client) error { + return func(c *Client) error { + hostURL, err := ParseHostURL(host) + if err != nil { + return err + } + c.host = host + c.proto = hostURL.Scheme + c.addr = hostURL.Host + c.basePath = hostURL.Path + if transport, ok := c.client.Transport.(*http.Transport); ok { + return sockets.ConfigureTransport(transport, c.proto, c.addr) + } + return errors.Errorf("cannot apply host to transport: %T", c.client.Transport) + } +} + +// WithHTTPClient overrides the client http client with the specified one +func WithHTTPClient(client *http.Client) func(*Client) error { + return func(c *Client) error { + if client != nil { + c.client = client + } + return nil + } +} + +// WithHTTPHeaders overrides the client default http headers +func WithHTTPHeaders(headers map[string]string) func(*Client) error { + return func(c *Client) error { + c.customHTTPHeaders = headers + return nil + } +} + +// WithScheme overrides the client scheme with the specified one +func WithScheme(scheme string) func(*Client) error { + return func(c *Client) error { + c.scheme = scheme + return nil + } +} + +// WithTLSClientConfig applies a tls config to the client transport. +func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error { + return func(c *Client) error { + opts := tlsconfig.Options{ + CAFile: cacertPath, + CertFile: certPath, + KeyFile: keyPath, + ExclusiveRootPools: true, + } + config, err := tlsconfig.Client(opts) + if err != nil { + return errors.Wrap(err, "failed to create tls config") + } + if transport, ok := c.client.Transport.(*http.Transport); ok { + transport.TLSClientConfig = config + return nil + } + return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport) + } +} + +// WithVersion overrides the client version with the specified one +func WithVersion(version string) func(*Client) error { + return func(c *Client) error { + c.version = version + return nil + } +} diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index dec1423e38..5cfadaa206 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -2,34 +2,63 @@ package client // import "github.com/docker/docker/client" import ( "context" + "net/http" "path" "github.com/docker/docker/api/types" + "github.com/docker/docker/errdefs" ) -// Ping pings the server and returns the value of the "Docker-Experimental", "Builder-Version", "OS-Type" & "API-Version" headers +// Ping pings the server and returns the value of the "Docker-Experimental", +// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use +// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported +// by the daemon. func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { var ping types.Ping - req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil) + + // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() + // because ping requests are used during API version negotiation, so we want + // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping + req, err := cli.buildRequest("HEAD", path.Join(cli.basePath, "/_ping"), nil, nil) if err != nil { return ping, err } serverResp, err := cli.doRequest(ctx, req) + if err == nil { + defer ensureReaderClosed(serverResp) + switch serverResp.statusCode { + case http.StatusOK, http.StatusInternalServerError: + // Server handled the request, so parse the response + return parsePingResponse(cli, serverResp) + } + } + + req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil) + if err != nil { + return ping, err + } + serverResp, err = cli.doRequest(ctx, req) if err != nil { return ping, err } defer ensureReaderClosed(serverResp) + return parsePingResponse(cli, serverResp) +} - if serverResp.header != nil { - ping.APIVersion = serverResp.header.Get("API-Version") - - if serverResp.header.Get("Docker-Experimental") == "true" { - ping.Experimental = true - } - ping.OSType = serverResp.header.Get("OSType") - if bv := serverResp.header.Get("Builder-Version"); bv != "" { - ping.BuilderVersion = types.BuilderVersion(bv) - } +func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) { + var ping types.Ping + if resp.header == nil { + err := cli.checkResponseErr(resp) + return ping, errdefs.FromStatusCode(err, resp.statusCode) + } + ping.APIVersion = resp.header.Get("API-Version") + ping.OSType = resp.header.Get("OSType") + if resp.header.Get("Docker-Experimental") == "true" { + ping.Experimental = true + } + if bv := resp.header.Get("Builder-Version"); bv != "" { + ping.BuilderVersion = types.BuilderVersion(bv) } - return ping, cli.checkResponseErr(serverResp) + err := cli.checkResponseErr(resp) + return ping, errdefs.FromStatusCode(err, resp.statusCode) } diff --git a/vendor/github.com/docker/docker/client/plugin_install.go b/vendor/github.com/docker/docker/client/plugin_install.go index 13baa40a9b..012afe61ca 100644 --- a/vendor/github.com/docker/docker/client/plugin_install.go +++ b/vendor/github.com/docker/docker/client/plugin_install.go @@ -4,11 +4,11 @@ import ( "context" "encoding/json" "io" - "net/http" "net/url" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + "github.com/docker/docker/errdefs" "github.com/pkg/errors" ) @@ -78,7 +78,7 @@ func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileg func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) { resp, err := cli.tryPluginPrivileges(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { + if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { // todo: do inspect before to check existing name before checking privileges newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index f1c256ad0e..0afe26d588 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -15,6 +15,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions" + "github.com/docker/docker/errdefs" "github.com/pkg/errors" ) @@ -120,9 +121,10 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u } resp, err := cli.doRequest(ctx, req) if err != nil { - return resp, err + return resp, errdefs.FromStatusCode(err, resp.statusCode) } - return resp, cli.checkResponseErr(resp) + err = cli.checkResponseErr(resp) + return resp, errdefs.FromStatusCode(err, resp.statusCode) } func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResponse, error) { @@ -195,17 +197,21 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error { return nil } - bodyMax := 1 * 1024 * 1024 // 1 MiB - bodyR := &io.LimitedReader{ - R: serverResp.body, - N: int64(bodyMax), - } - body, err := ioutil.ReadAll(bodyR) - if err != nil { - return err - } - if bodyR.N == 0 { - return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL) + var body []byte + var err error + if serverResp.body != nil { + bodyMax := 1 * 1024 * 1024 // 1 MiB + bodyR := &io.LimitedReader{ + R: serverResp.body, + N: int64(bodyMax), + } + body, err = ioutil.ReadAll(bodyR) + if err != nil { + return err + } + if bodyR.N == 0 { + return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL) + } } if len(body) == 0 { return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL) diff --git a/vendor/github.com/docker/docker/errdefs/helpers.go b/vendor/github.com/docker/docker/errdefs/helpers.go index ac71e86ffc..a28881caf5 100644 --- a/vendor/github.com/docker/docker/errdefs/helpers.go +++ b/vendor/github.com/docker/docker/errdefs/helpers.go @@ -12,8 +12,8 @@ func (e errNotFound) Cause() error { // NotFound is a helper to create an error of the class with the same name from any error type func NotFound(err error) error { - if err == nil { - return nil + if err == nil || IsNotFound(err) { + return err } return errNotFound{err} } @@ -28,8 +28,8 @@ func (e errInvalidParameter) Cause() error { // InvalidParameter is a helper to create an error of the class with the same name from any error type func InvalidParameter(err error) error { - if err == nil { - return nil + if err == nil || IsInvalidParameter(err) { + return err } return errInvalidParameter{err} } @@ -44,8 +44,8 @@ func (e errConflict) Cause() error { // Conflict is a helper to create an error of the class with the same name from any error type func Conflict(err error) error { - if err == nil { - return nil + if err == nil || IsConflict(err) { + return err } return errConflict{err} } @@ -60,8 +60,8 @@ func (e errUnauthorized) Cause() error { // Unauthorized is a helper to create an error of the class with the same name from any error type func Unauthorized(err error) error { - if err == nil { - return nil + if err == nil || IsUnauthorized(err) { + return err } return errUnauthorized{err} } @@ -76,8 +76,8 @@ func (e errUnavailable) Cause() error { // Unavailable is a helper to create an error of the class with the same name from any error type func Unavailable(err error) error { - if err == nil { - return nil + if err == nil || IsUnavailable(err) { + return err } return errUnavailable{err} } @@ -92,8 +92,8 @@ func (e errForbidden) Cause() error { // Forbidden is a helper to create an error of the class with the same name from any error type func Forbidden(err error) error { - if err == nil { - return nil + if err == nil || IsForbidden(err) { + return err } return errForbidden{err} } @@ -108,8 +108,8 @@ func (e errSystem) Cause() error { // System is a helper to create an error of the class with the same name from any error type func System(err error) error { - if err == nil { - return nil + if err == nil || IsSystem(err) { + return err } return errSystem{err} } @@ -124,8 +124,8 @@ func (e errNotModified) Cause() error { // NotModified is a helper to create an error of the class with the same name from any error type func NotModified(err error) error { - if err == nil { - return nil + if err == nil || IsNotModified(err) { + return err } return errNotModified{err} } @@ -140,8 +140,8 @@ func (e errAlreadyExists) Cause() error { // AlreadyExists is a helper to create an error of the class with the same name from any error type func AlreadyExists(err error) error { - if err == nil { - return nil + if err == nil || IsAlreadyExists(err) { + return err } return errAlreadyExists{err} } @@ -156,8 +156,8 @@ func (e errNotImplemented) Cause() error { // NotImplemented is a helper to create an error of the class with the same name from any error type func NotImplemented(err error) error { - if err == nil { - return nil + if err == nil || IsNotImplemented(err) { + return err } return errNotImplemented{err} } @@ -172,8 +172,8 @@ func (e errUnknown) Cause() error { // Unknown is a helper to create an error of the class with the same name from any error type func Unknown(err error) error { - if err == nil { - return nil + if err == nil || IsUnknown(err) { + return err } return errUnknown{err} } @@ -188,8 +188,8 @@ func (e errCancelled) Cause() error { // Cancelled is a helper to create an error of the class with the same name from any error type func Cancelled(err error) error { - if err == nil { - return nil + if err == nil || IsCancelled(err) { + return err } return errCancelled{err} } @@ -204,8 +204,8 @@ func (e errDeadline) Cause() error { // Deadline is a helper to create an error of the class with the same name from any error type func Deadline(err error) error { - if err == nil { - return nil + if err == nil || IsDeadline(err) { + return err } return errDeadline{err} } @@ -220,8 +220,8 @@ func (e errDataLoss) Cause() error { // DataLoss is a helper to create an error of the class with the same name from any error type func DataLoss(err error) error { - if err == nil { - return nil + if err == nil || IsDataLoss(err) { + return err } return errDataLoss{err} } diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go new file mode 100644 index 0000000000..9884eb86b9 --- /dev/null +++ b/vendor/github.com/docker/docker/errdefs/http_helpers.go @@ -0,0 +1,172 @@ +package errdefs // import "github.com/docker/docker/errdefs" + +import ( + "fmt" + "net/http" + + "github.com/docker/distribution/registry/api/errcode" + "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// GetHTTPErrorStatusCode retrieves status code from error message. +func GetHTTPErrorStatusCode(err error) int { + if err == nil { + logrus.WithFields(logrus.Fields{"error": err}).Error("unexpected HTTP error handling") + return http.StatusInternalServerError + } + + var statusCode int + + // Stop right there + // Are you sure you should be adding a new error class here? Do one of the existing ones work? + + // Note that the below functions are already checking the error causal chain for matches. + switch { + case IsNotFound(err): + statusCode = http.StatusNotFound + case IsInvalidParameter(err): + statusCode = http.StatusBadRequest + case IsConflict(err) || IsAlreadyExists(err): + statusCode = http.StatusConflict + case IsUnauthorized(err): + statusCode = http.StatusUnauthorized + case IsUnavailable(err): + statusCode = http.StatusServiceUnavailable + case IsForbidden(err): + statusCode = http.StatusForbidden + case IsNotModified(err): + statusCode = http.StatusNotModified + case IsNotImplemented(err): + statusCode = http.StatusNotImplemented + case IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) || IsCancelled(err): + statusCode = http.StatusInternalServerError + default: + statusCode = statusCodeFromGRPCError(err) + if statusCode != http.StatusInternalServerError { + return statusCode + } + statusCode = statusCodeFromDistributionError(err) + if statusCode != http.StatusInternalServerError { + return statusCode + } + if e, ok := err.(causer); ok { + return GetHTTPErrorStatusCode(e.Cause()) + } + + logrus.WithFields(logrus.Fields{ + "module": "api", + "error_type": fmt.Sprintf("%T", err), + }).Debugf("FIXME: Got an API for which error does not match any expected type!!!: %+v", err) + } + + if statusCode == 0 { + statusCode = http.StatusInternalServerError + } + + return statusCode +} + +// FromStatusCode creates an errdef error, based on the provided HTTP status-code +func FromStatusCode(err error, statusCode int) error { + if err == nil { + return err + } + switch statusCode { + case http.StatusNotFound: + err = NotFound(err) + case http.StatusBadRequest: + err = InvalidParameter(err) + case http.StatusConflict: + err = Conflict(err) + case http.StatusUnauthorized: + err = Unauthorized(err) + case http.StatusServiceUnavailable: + err = Unavailable(err) + case http.StatusForbidden: + err = Forbidden(err) + case http.StatusNotModified: + err = NotModified(err) + case http.StatusNotImplemented: + err = NotImplemented(err) + case http.StatusInternalServerError: + if !IsSystem(err) && !IsUnknown(err) && !IsDataLoss(err) && !IsDeadline(err) && !IsCancelled(err) { + err = System(err) + } + default: + logrus.WithFields(logrus.Fields{ + "module": "api", + "status_code": fmt.Sprintf("%d", statusCode), + }).Debugf("FIXME: Got an status-code for which error does not match any expected type!!!: %d", statusCode) + + switch { + case statusCode >= 200 && statusCode < 400: + // it's a client error + case statusCode >= 400 && statusCode < 500: + err = InvalidParameter(err) + case statusCode >= 500 && statusCode < 600: + err = System(err) + default: + err = Unknown(err) + } + } + return err +} + +// statusCodeFromGRPCError returns status code according to gRPC error +func statusCodeFromGRPCError(err error) int { + switch status.Code(err) { + case codes.InvalidArgument: // code 3 + return http.StatusBadRequest + case codes.NotFound: // code 5 + return http.StatusNotFound + case codes.AlreadyExists: // code 6 + return http.StatusConflict + case codes.PermissionDenied: // code 7 + return http.StatusForbidden + case codes.FailedPrecondition: // code 9 + return http.StatusBadRequest + case codes.Unauthenticated: // code 16 + return http.StatusUnauthorized + case codes.OutOfRange: // code 11 + return http.StatusBadRequest + case codes.Unimplemented: // code 12 + return http.StatusNotImplemented + case codes.Unavailable: // code 14 + return http.StatusServiceUnavailable + default: + if e, ok := err.(causer); ok { + return statusCodeFromGRPCError(e.Cause()) + } + // codes.Canceled(1) + // codes.Unknown(2) + // codes.DeadlineExceeded(4) + // codes.ResourceExhausted(8) + // codes.Aborted(10) + // codes.Internal(13) + // codes.DataLoss(15) + return http.StatusInternalServerError + } +} + +// statusCodeFromDistributionError returns status code according to registry errcode +// code is loosely based on errcode.ServeJSON() in docker/distribution +func statusCodeFromDistributionError(err error) int { + switch errs := err.(type) { + case errcode.Errors: + if len(errs) < 1 { + return http.StatusInternalServerError + } + if _, ok := errs[0].(errcode.ErrorCoder); ok { + return statusCodeFromDistributionError(errs[0]) + } + case errcode.ErrorCoder: + return errs.ErrorCode().Descriptor().HTTPStatusCode + default: + if e, ok := err.(causer); ok { + return statusCodeFromDistributionError(e.Cause()) + } + } + return http.StatusInternalServerError +} diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf index 2d3ca977da..54135caa01 100644 --- a/vendor/github.com/docker/docker/vendor.conf +++ b/vendor/github.com/docker/docker/vendor.conf @@ -1,12 +1,12 @@ # the following lines are in sorted order, FYI github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 -github.com/Microsoft/hcsshim v0.8.3 +github.com/Microsoft/hcsshim v0.8.6 github.com/Microsoft/go-winio v0.4.11 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a -github.com/gorilla/context v1.1 -github.com/gorilla/mux v1.6.2 +github.com/google/uuid v1.1.1 +github.com/gorilla/mux v1.7.0 github.com/Microsoft/opengcs v0.3.9 github.com/kr/pty 5cf931ef8f github.com/mattn/go-shellwords v1.0.3 @@ -14,7 +14,7 @@ github.com/sirupsen/logrus v1.0.6 github.com/tchap/go-patricia v2.2.6 github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 golang.org/x/net a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1 -golang.org/x/sys 90868a75fefd03942536221d7c0e2f84ec62a668 +golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba github.com/docker/go-units 47565b4f722fb6ceae66b95f853feed578a4a51c # v0.3.3 github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0 @@ -26,13 +26,14 @@ github.com/imdario/mergo v0.3.6 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca # buildkit -github.com/moby/buildkit d9f75920678e35090025bb89344c5370e2efc8e7 -github.com/tonistiigi/fsutil 2862f6bc5ac9b97124e552a5c108230b38a1b0ca +github.com/moby/buildkit c35410878ab9070498c66f6c67d3e8bc3b92241f +github.com/tonistiigi/fsutil 1ec1983587cde7e8ac2978e354ff5360af622464 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 github.com/google/shlex 6f45313302b9c56850fc17f99e40caebce98c716 github.com/opentracing-contrib/go-stdlib b1a47cfbdd7543e70e9ef3e73d0802ad306cc1cc github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b +github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0d3388b300c53 # v0.7.0 #get libnetwork packages @@ -64,7 +65,7 @@ github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb go.etcd.io/bbolt v1.3.1-etcd.8 # get graph and distribution packages -github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5 +github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 github.com/vbatts/tar-split v0.11.0 github.com/opencontainers/go-digest v1.0.0-rc1 @@ -79,8 +80,8 @@ google.golang.org/grpc v1.12.0 # the containerd project first, and update both after that is merged. # This commit does not need to match RUNC_COMMIT as it is used for helper # packages but should be newer or equal. -github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb -github.com/opencontainers/runtime-spec 5684b8af48c1ac3b1451fa499724e30e3c20a294 # v1.0.1-49-g5684b8a +github.com/opencontainers/runc 2b18fe1d885ee5083ef9f0838fee39b62d653e30 +github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db github.com/opencontainers/image-spec v1.0.1 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 @@ -88,7 +89,7 @@ github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 github.com/coreos/go-systemd v17 github.com/godbus/dbus v4.0.0 github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852 -github.com/golang/protobuf v1.1.0 +github.com/golang/protobuf v1.2.0 # gelf logging driver deps github.com/Graylog2/go-gelf 4143646226541087117ff2f83334ea48b3201841 @@ -118,20 +119,19 @@ github.com/googleapis/gax-go v2.0.0 google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9 # containerd -github.com/containerd/containerd aa5e000c963756778ab3ebd1a12c67449c503a34 # v1.2.1+ +github.com/containerd/containerd a15b6e2097c48b632dbdc63254bad4c62b69e709 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d -github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2 +github.com/containerd/cgroups dbea6f2bd41658b84b00417ceefa416b979cbf10 github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23 -github.com/containerd/cri 0ca1e3c2b73b5c38e72f29bb76338d0078b23d6c # release/1.2 branch github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 -github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a +github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6 github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef # cluster -github.com/docker/swarmkit 8af8c420f491f006ab1730e08d446a795b1667d7 -github.com/gogo/protobuf v1.0.0 +github.com/docker/swarmkit 415dc72789e2b733ea884f09188c286ca187d8ec +github.com/gogo/protobuf v1.2.0 github.com/cloudflare/cfssl 1.3.2 github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2 github.com/google/certificate-transparency-go v1.0.20 @@ -155,7 +155,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.1 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0 -github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty +github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b # metrics github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18 From 18d91706dd7b821232140543c214b0429cb6bbc0 Mon Sep 17 00:00:00 2001 From: Olli Janatuinen Date: Sat, 15 Dec 2018 14:23:32 +0200 Subject: [PATCH 2/2] Add capabilities list to container specification Signed-off-by: Olli Janatuinen --- agent/exec/dockerapi/container.go | 1 + agent/exec/dockerapi/container_test.go | 20 ++ api/api.pb.txt | 7 + api/specs.pb.go | 335 +++++++++++------- api/specs.proto | 3 + cmd/swarmctl/service/flagparser/capability.go | 72 ++++ cmd/swarmctl/service/update.go | 9 + 7 files changed, 310 insertions(+), 137 deletions(-) create mode 100644 cmd/swarmctl/service/flagparser/capability.go diff --git a/agent/exec/dockerapi/container.go b/agent/exec/dockerapi/container.go index 51fbf9d2ba..61695d8fe7 100644 --- a/agent/exec/dockerapi/container.go +++ b/agent/exec/dockerapi/container.go @@ -209,6 +209,7 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig { PortBindings: c.portBindings(), Init: c.init(), Isolation: c.isolation(), + Capabilities: c.spec().Capabilities, } // The format of extra hosts on swarmkit is specified in: diff --git a/agent/exec/dockerapi/container_test.go b/agent/exec/dockerapi/container_test.go index 9dfe79a908..bd11f5c3ac 100644 --- a/agent/exec/dockerapi/container_test.go +++ b/agent/exec/dockerapi/container_test.go @@ -256,3 +256,23 @@ func TestIsolation(t *testing.T) { t.Fatalf("expected %s, got %s", expected, actual) } } + +func TestCapabilities(t *testing.T) { + c := containerConfig{ + task: &api.Task{ + Spec: api.TaskSpec{ + Runtime: &api.TaskSpec_Container{ + Container: &api.ContainerSpec{ + Capabilities: []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"}, + }, + }, + }, + }, + } + + expected := []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"} + actual := c.hostConfig().Capabilities + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("expected %s, got %s", expected, actual) + } +} diff --git a/api/api.pb.txt b/api/api.pb.txt index 23f5069e09..bc756e4db9 100755 --- a/api/api.pb.txt +++ b/api/api.pb.txt @@ -4951,6 +4951,13 @@ file { type_name: ".docker.swarmkit.v1.ContainerSpec.SysctlsEntry" json_name: "sysctls" } + field { + name: "capabilities" + number: 27 + label: LABEL_REPEATED + type: TYPE_STRING + json_name: "capabilities" + } nested_type { name: "LabelsEntry" field { diff --git a/api/specs.pb.go b/api/specs.pb.go index dfab9e3910..660e59ca2a 100644 --- a/api/specs.pb.go +++ b/api/specs.pb.go @@ -636,6 +636,8 @@ type ContainerSpec struct { // // https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime Sysctls map[string]string `protobuf:"bytes,26,rep,name=sysctls" json:"sysctls,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Capabilities is the list of Linux capabilities to be available for container (this overrides the default set of capabilities) + Capabilities []string `protobuf:"bytes,27,rep,name=capabilities" json:"capabilities,omitempty"` } func (m *ContainerSpec) Reset() { *m = ContainerSpec{} } @@ -1197,6 +1199,11 @@ func (m *ContainerSpec) CopyFrom(src interface{}) { } } + if o.Capabilities != nil { + m.Capabilities = make([]string, len(o.Capabilities)) + copy(m.Capabilities, o.Capabilities) + } + } func (m *ContainerSpec_PullOptions) Copy() *ContainerSpec_PullOptions { @@ -2104,6 +2111,23 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], v) } } + if len(m.Capabilities) > 0 { + for _, s := range m.Capabilities { + dAtA[i] = 0xda + i++ + dAtA[i] = 0x1 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } @@ -2829,6 +2853,12 @@ func (m *ContainerSpec) Size() (n int) { n += mapEntrySize + 2 + sovSpecs(uint64(mapEntrySize)) } } + if len(m.Capabilities) > 0 { + for _, s := range m.Capabilities { + l = len(s) + n += 2 + l + sovSpecs(uint64(l)) + } + } return n } @@ -3188,6 +3218,7 @@ func (this *ContainerSpec) String() string { `Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`, `PidsLimit:` + fmt.Sprintf("%v", this.PidsLimit) + `,`, `Sysctls:` + mapStringForSysctls + `,`, + `Capabilities:` + fmt.Sprintf("%v", this.Capabilities) + `,`, `}`, }, "") return s @@ -5454,6 +5485,35 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error { } m.Sysctls[mapkey] = mapvalue iNdEx = postIndex + case 27: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capabilities", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Capabilities = append(m.Capabilities, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -6765,141 +6825,142 @@ var ( func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) } var fileDescriptorSpecs = []byte{ - // 2166 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0x1b, 0xc9, - 0xd1, 0x16, 0x25, 0x8a, 0x1f, 0x35, 0x94, 0x4d, 0xf5, 0xda, 0xde, 0x11, 0x6d, 0x4b, 0x34, 0xd7, - 0xeb, 0x57, 0xbb, 0x8b, 0x97, 0x42, 0x94, 0xc5, 0xc6, 0x6b, 0x67, 0x93, 0x90, 0x22, 0x57, 0x62, - 0x6c, 0x4b, 0x44, 0x53, 0x56, 0x62, 0x20, 0x00, 0xd1, 0x9a, 0x69, 0x91, 0x03, 0x0d, 0xa7, 0x27, - 0xdd, 0x4d, 0x19, 0xbc, 0xe5, 0xb8, 0x50, 0x7e, 0x83, 0x90, 0x43, 0x90, 0x7b, 0xf2, 0x2f, 0x7c, - 0xcc, 0x31, 0xb9, 0x08, 0x59, 0x1d, 0xf2, 0x07, 0x72, 0xcb, 0x25, 0x41, 0xf7, 0xf4, 0xf0, 0x43, - 0x1e, 0x59, 0x0e, 0xe2, 0x43, 0x6e, 0xdd, 0x35, 0xcf, 0x53, 0xfd, 0xf5, 0x54, 0x75, 0xf5, 0xc0, - 0xe7, 0x3d, 0x4f, 0xf6, 0x87, 0x87, 0x55, 0x87, 0x0d, 0x36, 0x5c, 0xe6, 0x1c, 0x53, 0xbe, 0x21, - 0x5e, 0x13, 0x3e, 0x38, 0xf6, 0xe4, 0x06, 0x09, 0xbd, 0x0d, 0x11, 0x52, 0x47, 0x54, 0x43, 0xce, - 0x24, 0x43, 0x28, 0x02, 0x54, 0x63, 0x40, 0xf5, 0xe4, 0x07, 0xa5, 0xeb, 0xf8, 0x72, 0x14, 0x52, - 0xc3, 0x2f, 0xdd, 0xea, 0xb1, 0x1e, 0xd3, 0xcd, 0x0d, 0xd5, 0x32, 0xd6, 0xd5, 0x1e, 0x63, 0x3d, - 0x9f, 0x6e, 0xe8, 0xde, 0xe1, 0xf0, 0x68, 0xc3, 0x1d, 0x72, 0x22, 0x3d, 0x16, 0x98, 0xef, 0x2b, - 0x97, 0xbf, 0x93, 0x60, 0x74, 0x15, 0xf5, 0x35, 0x27, 0x61, 0x48, 0xb9, 0x19, 0xb0, 0x72, 0x96, - 0x86, 0xdc, 0x2e, 0x73, 0x69, 0x27, 0xa4, 0x0e, 0xda, 0x06, 0x8b, 0x04, 0x01, 0x93, 0xda, 0xb7, - 0xb0, 0x53, 0xe5, 0xd4, 0xba, 0xb5, 0xb9, 0x56, 0x7d, 0x7b, 0x4d, 0xd5, 0xda, 0x04, 0x56, 0x4f, - 0xbf, 0x39, 0x5f, 0x9b, 0xc3, 0xd3, 0x4c, 0xf4, 0x53, 0x28, 0xb8, 0x54, 0x78, 0x9c, 0xba, 0x5d, - 0xce, 0x7c, 0x6a, 0xcf, 0x97, 0x53, 0xeb, 0x37, 0x36, 0xef, 0x25, 0x79, 0x52, 0x83, 0x63, 0xe6, - 0x53, 0x6c, 0x19, 0x86, 0xea, 0xa0, 0x6d, 0x80, 0x01, 0x1d, 0x1c, 0x52, 0x2e, 0xfa, 0x5e, 0x68, - 0x2f, 0x68, 0xfa, 0xff, 0x5d, 0x45, 0x57, 0x73, 0xaf, 0xbe, 0x18, 0xc3, 0xf1, 0x14, 0x15, 0xbd, - 0x80, 0x02, 0x39, 0x21, 0x9e, 0x4f, 0x0e, 0x3d, 0xdf, 0x93, 0x23, 0x3b, 0xad, 0x5d, 0x7d, 0xf6, - 0x4e, 0x57, 0xb5, 0x29, 0x02, 0x9e, 0xa1, 0x57, 0x5c, 0x80, 0xc9, 0x40, 0xe8, 0x11, 0x64, 0xdb, - 0xcd, 0xdd, 0x46, 0x6b, 0x77, 0xbb, 0x38, 0x57, 0x5a, 0x39, 0x3d, 0x2b, 0xdf, 0x56, 0x3e, 0x26, - 0x80, 0x36, 0x0d, 0x5c, 0x2f, 0xe8, 0xa1, 0x75, 0xc8, 0xd5, 0xb6, 0xb6, 0x9a, 0xed, 0xfd, 0x66, - 0xa3, 0x98, 0x2a, 0x95, 0x4e, 0xcf, 0xca, 0x77, 0x66, 0x81, 0x35, 0xc7, 0xa1, 0xa1, 0xa4, 0x6e, - 0x29, 0xfd, 0xdd, 0xef, 0x57, 0xe7, 0x2a, 0xdf, 0xa5, 0xa0, 0x30, 0x3d, 0x09, 0xf4, 0x08, 0x32, - 0xb5, 0xad, 0xfd, 0xd6, 0x41, 0xb3, 0x38, 0x37, 0xa1, 0x4f, 0x23, 0x6a, 0x8e, 0xf4, 0x4e, 0x28, - 0x7a, 0x08, 0x8b, 0xed, 0xda, 0xcb, 0x4e, 0xb3, 0x98, 0x9a, 0x4c, 0x67, 0x1a, 0xd6, 0x26, 0x43, - 0xa1, 0x51, 0x0d, 0x5c, 0x6b, 0xed, 0x16, 0xe7, 0x93, 0x51, 0x0d, 0x4e, 0xbc, 0xc0, 0x4c, 0xe5, - 0x77, 0x69, 0xb0, 0x3a, 0x94, 0x9f, 0x78, 0xce, 0x07, 0x96, 0xc8, 0x57, 0x90, 0x96, 0x44, 0x1c, - 0x6b, 0x69, 0x58, 0xc9, 0xd2, 0xd8, 0x27, 0xe2, 0x58, 0x0d, 0x6a, 0xe8, 0x1a, 0xaf, 0x94, 0xc1, - 0x69, 0xe8, 0x7b, 0x0e, 0x91, 0xd4, 0xd5, 0xca, 0xb0, 0x36, 0x3f, 0x4d, 0x62, 0xe3, 0x31, 0xca, - 0xcc, 0x7f, 0x67, 0x0e, 0x4f, 0x51, 0xd1, 0x53, 0xc8, 0xf4, 0x7c, 0x76, 0x48, 0x7c, 0xad, 0x09, - 0x6b, 0xf3, 0x41, 0x92, 0x93, 0x6d, 0x8d, 0x98, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x32, 0xc3, 0xd0, - 0x25, 0x92, 0xda, 0x19, 0x4d, 0x2e, 0x27, 0x91, 0x5f, 0x6a, 0xc4, 0x16, 0x0b, 0x8e, 0xbc, 0x1e, - 0x36, 0x78, 0xf4, 0x0c, 0x72, 0x01, 0x95, 0xaf, 0x19, 0x3f, 0x16, 0x76, 0xb6, 0xbc, 0xb0, 0x6e, - 0x6d, 0x7e, 0x91, 0x28, 0xc6, 0x08, 0x53, 0x93, 0x92, 0x38, 0xfd, 0x01, 0x0d, 0x64, 0xe4, 0xa6, - 0x3e, 0x6f, 0xa7, 0xf0, 0xd8, 0x01, 0xfa, 0x31, 0xe4, 0x68, 0xe0, 0x86, 0xcc, 0x0b, 0xa4, 0x9d, - 0xbb, 0x7a, 0x22, 0x4d, 0x83, 0x51, 0x9b, 0x89, 0xc7, 0x0c, 0xc5, 0xe6, 0xcc, 0xf7, 0x0f, 0x89, - 0x73, 0x6c, 0xe7, 0xdf, 0x73, 0x19, 0x63, 0x46, 0x3d, 0x03, 0xe9, 0x01, 0x73, 0x69, 0x65, 0x03, - 0x96, 0xdf, 0xda, 0x6a, 0x54, 0x82, 0x9c, 0xd9, 0xea, 0x48, 0x23, 0x69, 0x3c, 0xee, 0x57, 0x6e, - 0xc2, 0xd2, 0xcc, 0xb6, 0x56, 0xfe, 0xb8, 0x08, 0xb9, 0xf8, 0xac, 0x51, 0x0d, 0xf2, 0x0e, 0x0b, - 0x24, 0xf1, 0x02, 0xca, 0x8d, 0xbc, 0x12, 0x4f, 0x66, 0x2b, 0x06, 0x29, 0xd6, 0xce, 0x1c, 0x9e, - 0xb0, 0xd0, 0xb7, 0x90, 0xe7, 0x54, 0xb0, 0x21, 0x77, 0xa8, 0x30, 0xfa, 0x5a, 0x4f, 0x56, 0x48, - 0x04, 0xc2, 0xf4, 0xd7, 0x43, 0x8f, 0x53, 0xb5, 0xcb, 0x02, 0x4f, 0xa8, 0xe8, 0x29, 0x64, 0x39, - 0x15, 0x92, 0x70, 0xf9, 0x2e, 0x89, 0xe0, 0x08, 0xd2, 0x66, 0xbe, 0xe7, 0x8c, 0x70, 0xcc, 0x40, - 0x4f, 0x21, 0x1f, 0xfa, 0xc4, 0xd1, 0x5e, 0xed, 0x45, 0x4d, 0xbf, 0x9f, 0x44, 0x6f, 0xc7, 0x20, - 0x3c, 0xc1, 0xa3, 0xaf, 0x01, 0x7c, 0xd6, 0xeb, 0xba, 0xdc, 0x3b, 0xa1, 0xdc, 0x48, 0xac, 0x94, - 0xc4, 0x6e, 0x68, 0x04, 0xce, 0xfb, 0xac, 0x17, 0x35, 0xd1, 0xf6, 0x7f, 0xa5, 0xaf, 0x29, 0x6d, - 0x3d, 0x03, 0x20, 0xe3, 0xaf, 0x46, 0x5d, 0x9f, 0xbd, 0x97, 0x2b, 0x73, 0x22, 0x53, 0x74, 0xf4, - 0x00, 0x0a, 0x47, 0x8c, 0x3b, 0xb4, 0x6b, 0xa2, 0x26, 0xaf, 0x35, 0x61, 0x69, 0x5b, 0xa4, 0x2f, - 0x54, 0x87, 0x6c, 0x8f, 0x06, 0x94, 0x7b, 0x8e, 0x0d, 0x7a, 0xb0, 0x47, 0x89, 0x01, 0x19, 0x41, - 0xf0, 0x30, 0x90, 0xde, 0x80, 0x9a, 0x91, 0x62, 0x22, 0xfa, 0x15, 0x7c, 0x14, 0x1f, 0x5f, 0x97, - 0xd3, 0x23, 0xca, 0x69, 0xa0, 0x34, 0x60, 0xe9, 0x7d, 0xf8, 0xf4, 0xdd, 0x1a, 0x30, 0x68, 0x93, - 0x6c, 0x10, 0xbf, 0xfc, 0x41, 0xd4, 0xf3, 0x90, 0xe5, 0xd1, 0xb8, 0x95, 0xdf, 0xa6, 0x94, 0xea, - 0x2f, 0x21, 0xd0, 0x06, 0x58, 0xe3, 0xe1, 0x3d, 0x57, 0xab, 0x37, 0x5f, 0xbf, 0x71, 0x71, 0xbe, - 0x06, 0x31, 0xb6, 0xd5, 0x50, 0x39, 0xc8, 0xb4, 0x5d, 0xd4, 0x84, 0xa5, 0x31, 0x41, 0x95, 0x01, - 0xe6, 0xa2, 0x2c, 0xbf, 0x6b, 0xa6, 0xfb, 0xa3, 0x90, 0xe2, 0x02, 0x9f, 0xea, 0x55, 0x7e, 0x09, - 0xe8, 0xed, 0x7d, 0x41, 0x08, 0xd2, 0xc7, 0x5e, 0x60, 0xa6, 0x81, 0x75, 0x1b, 0x55, 0x21, 0x1b, - 0x92, 0x91, 0xcf, 0x88, 0x6b, 0x02, 0xe3, 0x56, 0x35, 0x2a, 0x10, 0xaa, 0x71, 0x81, 0x50, 0xad, - 0x05, 0x23, 0x1c, 0x83, 0x2a, 0xcf, 0xe0, 0x76, 0xe2, 0xf1, 0xa2, 0x4d, 0x28, 0x8c, 0x03, 0x6e, - 0xb2, 0xd6, 0x9b, 0x17, 0xe7, 0x6b, 0xd6, 0x38, 0x32, 0x5b, 0x0d, 0x6c, 0x8d, 0x41, 0x2d, 0xb7, - 0xf2, 0xf7, 0x02, 0x2c, 0xcd, 0x84, 0x2d, 0xba, 0x05, 0x8b, 0xde, 0x80, 0xf4, 0xa8, 0x99, 0x63, - 0xd4, 0x41, 0x4d, 0xc8, 0xf8, 0xe4, 0x90, 0xfa, 0x2a, 0x78, 0xd5, 0xc1, 0xfd, 0xff, 0xb5, 0xf1, - 0x5f, 0x7d, 0xae, 0xf1, 0xcd, 0x40, 0xf2, 0x11, 0x36, 0x64, 0x64, 0x43, 0xd6, 0x61, 0x83, 0x01, - 0x09, 0xd4, 0x35, 0xb1, 0xb0, 0x9e, 0xc7, 0x71, 0x57, 0xed, 0x0c, 0xe1, 0x3d, 0x61, 0xa7, 0xb5, - 0x59, 0xb7, 0x51, 0x11, 0x16, 0x68, 0x70, 0x62, 0x2f, 0x6a, 0x93, 0x6a, 0x2a, 0x8b, 0xeb, 0x45, - 0xd1, 0x97, 0xc7, 0xaa, 0xa9, 0x78, 0x43, 0x41, 0xb9, 0x9d, 0x8d, 0x76, 0x54, 0xb5, 0xd1, 0x8f, - 0x20, 0x33, 0x60, 0xc3, 0x40, 0x0a, 0x3b, 0xa7, 0x27, 0xbb, 0x92, 0x34, 0xd9, 0x17, 0x0a, 0x61, - 0x94, 0x65, 0xe0, 0xa8, 0x09, 0xcb, 0x42, 0xb2, 0xb0, 0xdb, 0xe3, 0xc4, 0xa1, 0xdd, 0x90, 0x72, - 0x8f, 0xb9, 0x26, 0x0d, 0xaf, 0xbc, 0x75, 0x28, 0x0d, 0x53, 0xf0, 0xe1, 0x9b, 0x8a, 0xb3, 0xad, - 0x28, 0x6d, 0xcd, 0x40, 0x6d, 0x28, 0x84, 0x43, 0xdf, 0xef, 0xb2, 0x30, 0xba, 0x91, 0xa3, 0xd8, - 0x79, 0x8f, 0x2d, 0x6b, 0x0f, 0x7d, 0x7f, 0x2f, 0x22, 0x61, 0x2b, 0x9c, 0x74, 0xd0, 0x1d, 0xc8, - 0xf4, 0x38, 0x1b, 0x86, 0x51, 0xdc, 0xe4, 0xb1, 0xe9, 0xa1, 0x6f, 0x20, 0x2b, 0xa8, 0xc3, 0xa9, - 0x14, 0x76, 0x41, 0x2f, 0xf5, 0x93, 0xa4, 0x41, 0x3a, 0x1a, 0x32, 0x8e, 0x09, 0x1c, 0x73, 0xd0, - 0x0a, 0x2c, 0x48, 0x39, 0xb2, 0x97, 0xca, 0xa9, 0xf5, 0x5c, 0x3d, 0x7b, 0x71, 0xbe, 0xb6, 0xb0, - 0xbf, 0xff, 0x0a, 0x2b, 0x9b, 0xba, 0x2d, 0xfa, 0x4c, 0xc8, 0x80, 0x0c, 0xa8, 0x7d, 0x43, 0xef, - 0xed, 0xb8, 0x8f, 0x5e, 0x01, 0xb8, 0x81, 0xe8, 0x3a, 0x3a, 0x3d, 0xd9, 0x37, 0xf5, 0xea, 0xbe, - 0xb8, 0x7e, 0x75, 0x8d, 0xdd, 0x8e, 0xb9, 0x31, 0x97, 0x2e, 0xce, 0xd7, 0xf2, 0xe3, 0x2e, 0xce, - 0xbb, 0x81, 0x88, 0x9a, 0xa8, 0x0e, 0x56, 0x9f, 0x12, 0x5f, 0xf6, 0x9d, 0x3e, 0x75, 0x8e, 0xed, - 0xe2, 0xd5, 0x57, 0xe0, 0x8e, 0x86, 0x19, 0x0f, 0xd3, 0x24, 0xa5, 0x60, 0x35, 0x55, 0x61, 0x2f, - 0xeb, 0xbd, 0x8a, 0x3a, 0xe8, 0x3e, 0x00, 0x0b, 0x69, 0xd0, 0x15, 0xd2, 0xf5, 0x02, 0x1b, 0xa9, - 0x25, 0xe3, 0xbc, 0xb2, 0x74, 0x94, 0x01, 0xdd, 0x55, 0x17, 0x14, 0x71, 0xbb, 0x2c, 0xf0, 0x47, - 0xf6, 0x47, 0xfa, 0x6b, 0x4e, 0x19, 0xf6, 0x02, 0x7f, 0x84, 0xd6, 0xc0, 0xd2, 0xba, 0x10, 0x5e, - 0x2f, 0x20, 0xbe, 0x7d, 0x4b, 0xef, 0x07, 0x28, 0x53, 0x47, 0x5b, 0xd4, 0x39, 0x44, 0xbb, 0x21, - 0xec, 0xdb, 0x57, 0x9f, 0x83, 0x99, 0xec, 0xe4, 0x1c, 0x0c, 0x07, 0xfd, 0x04, 0x20, 0xe4, 0xde, - 0x89, 0xe7, 0xd3, 0x1e, 0x15, 0xf6, 0x1d, 0xbd, 0xe8, 0xd5, 0xc4, 0x9b, 0x69, 0x8c, 0xc2, 0x53, - 0x0c, 0x54, 0x85, 0xb4, 0x17, 0x78, 0xd2, 0xfe, 0xd8, 0xdc, 0x4a, 0x97, 0xa5, 0x5a, 0x67, 0xcc, - 0x3f, 0x20, 0xfe, 0x90, 0x62, 0x8d, 0x43, 0x2d, 0xc8, 0x7b, 0x82, 0xf9, 0x5a, 0xbe, 0xb6, 0xad, - 0xf3, 0xdb, 0x7b, 0x9c, 0x5f, 0x2b, 0xa6, 0xe0, 0x09, 0x1b, 0xdd, 0x83, 0x7c, 0xe8, 0xb9, 0xe2, - 0xb9, 0x37, 0xf0, 0xa4, 0xbd, 0x52, 0x4e, 0xad, 0x2f, 0xe0, 0x89, 0x01, 0xed, 0x40, 0x56, 0x8c, - 0x84, 0x23, 0x7d, 0x61, 0x97, 0xf4, 0xbe, 0x54, 0xaf, 0x1f, 0xa6, 0x13, 0x11, 0xa2, 0xc4, 0x11, - 0xd3, 0x4b, 0x5f, 0x83, 0x35, 0x95, 0x50, 0x54, 0x22, 0x38, 0xa6, 0x23, 0x93, 0xa3, 0x54, 0x53, - 0x9d, 0xfa, 0x89, 0x5a, 0xa2, 0x4e, 0xa2, 0x79, 0x1c, 0x75, 0x9e, 0xcc, 0x3f, 0x4e, 0x95, 0x36, - 0xc1, 0x9a, 0x0a, 0x2c, 0xf4, 0x89, 0x4a, 0xf0, 0x3d, 0x4f, 0x48, 0x3e, 0xea, 0x92, 0xa1, 0xec, - 0xdb, 0x3f, 0xd3, 0x84, 0x42, 0x6c, 0xac, 0x0d, 0x65, 0xbf, 0xd4, 0x85, 0x89, 0x3e, 0x51, 0x19, - 0x2c, 0xa5, 0x7b, 0x41, 0xf9, 0x09, 0xe5, 0xaa, 0x78, 0x52, 0xb2, 0x9a, 0x36, 0xa9, 0xf8, 0x14, - 0x94, 0x70, 0xa7, 0xaf, 0xd3, 0x63, 0x1e, 0x9b, 0x9e, 0xca, 0x77, 0x71, 0x12, 0x30, 0xf9, 0xce, - 0x74, 0x4b, 0x4f, 0xa0, 0x30, 0xbd, 0xd0, 0xff, 0x64, 0x41, 0x95, 0x3f, 0xa5, 0x20, 0x3f, 0x3e, - 0x0c, 0xf4, 0x25, 0x2c, 0xb7, 0x3a, 0x7b, 0xcf, 0x6b, 0xfb, 0xad, 0xbd, 0xdd, 0x6e, 0xa3, 0xf9, - 0x6d, 0xed, 0xe5, 0xf3, 0xfd, 0xe2, 0x5c, 0xe9, 0xfe, 0xe9, 0x59, 0x79, 0x65, 0x92, 0xf7, 0x63, - 0x78, 0x83, 0x1e, 0x91, 0xa1, 0x2f, 0x67, 0x59, 0x6d, 0xbc, 0xb7, 0xd5, 0xec, 0x74, 0x8a, 0xa9, - 0xab, 0x58, 0x6d, 0xce, 0x1c, 0x2a, 0x04, 0xda, 0x84, 0xe2, 0x84, 0xb5, 0xf3, 0xaa, 0xdd, 0xc4, - 0x07, 0xc5, 0xf9, 0xd2, 0xbd, 0xd3, 0xb3, 0xb2, 0xfd, 0x36, 0x69, 0x67, 0x14, 0x52, 0x7e, 0x60, - 0x1e, 0x2d, 0xff, 0x48, 0x41, 0x61, 0xba, 0xe6, 0x45, 0x5b, 0x51, 0xad, 0xaa, 0x57, 0x7c, 0x63, - 0x73, 0xe3, 0xba, 0x1a, 0x59, 0xdf, 0xb5, 0xfe, 0x50, 0xf9, 0x7d, 0xa1, 0x9e, 0xa7, 0x9a, 0x8c, - 0xbe, 0x84, 0xc5, 0x90, 0x71, 0x19, 0xdf, 0x4a, 0xc9, 0x31, 0xc3, 0x78, 0x5c, 0x49, 0x45, 0xe0, - 0x4a, 0x1f, 0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x61, 0xe1, 0xa0, 0xd5, 0x2e, 0xce, 0x95, 0xee, 0x9e, - 0x9e, 0x95, 0x3f, 0x9e, 0xfd, 0x78, 0xe0, 0x71, 0x39, 0x24, 0x7e, 0xab, 0x8d, 0x3e, 0x87, 0xc5, - 0xc6, 0x6e, 0x07, 0xe3, 0x62, 0xaa, 0xb4, 0x76, 0x7a, 0x56, 0xbe, 0x3b, 0x8b, 0x53, 0x9f, 0xd8, - 0x30, 0x70, 0x31, 0x3b, 0x1c, 0x3f, 0xd5, 0xfe, 0x39, 0x0f, 0x96, 0xb9, 0xac, 0x3f, 0xf4, 0x6b, - 0x7e, 0x29, 0xaa, 0x44, 0xe3, 0x2c, 0x3c, 0x7f, 0x6d, 0x41, 0x5a, 0x88, 0x08, 0x46, 0xd3, 0x0f, - 0xa0, 0xe0, 0x85, 0x27, 0x5f, 0x75, 0x69, 0x40, 0x0e, 0x7d, 0xf3, 0x6a, 0xcb, 0x61, 0x4b, 0xd9, - 0x9a, 0x91, 0x49, 0x5d, 0x01, 0x5e, 0x20, 0x29, 0x0f, 0xcc, 0x7b, 0x2c, 0x87, 0xc7, 0x7d, 0xf4, - 0x0d, 0xa4, 0xbd, 0x90, 0x0c, 0x4c, 0x15, 0x9d, 0xb8, 0x82, 0x56, 0xbb, 0xf6, 0xc2, 0xc4, 0x5c, - 0x3d, 0x77, 0x71, 0xbe, 0x96, 0x56, 0x06, 0xac, 0x69, 0x68, 0x35, 0x2e, 0x64, 0xd5, 0x48, 0xfa, - 0x3a, 0xcf, 0xe1, 0x29, 0x8b, 0x8a, 0x1b, 0x2f, 0xe8, 0x71, 0x2a, 0x84, 0xbe, 0xd8, 0x73, 0x38, - 0xee, 0xa2, 0x12, 0x64, 0x4d, 0x39, 0xac, 0xeb, 0xdf, 0xbc, 0x2a, 0x35, 0x8d, 0xa1, 0xbe, 0x04, - 0x56, 0xb4, 0x1b, 0xdd, 0x23, 0xce, 0x06, 0x95, 0x7f, 0xa5, 0xc1, 0xda, 0xf2, 0x87, 0x42, 0x9a, - 0xca, 0xe6, 0x83, 0x6d, 0xfe, 0x2b, 0x58, 0x26, 0xfa, 0xef, 0x00, 0x09, 0x54, 0x99, 0xa0, 0x5f, - 0x19, 0xe6, 0x00, 0x1e, 0x26, 0xba, 0x1b, 0x83, 0xa3, 0x17, 0x49, 0x3d, 0xa3, 0x7c, 0xda, 0x29, - 0x5c, 0x24, 0x97, 0xbe, 0xa0, 0x0e, 0x2c, 0x31, 0xee, 0xf4, 0xa9, 0x90, 0x51, 0x71, 0x61, 0x5e, - 0xd3, 0x89, 0xff, 0x59, 0xf6, 0xa6, 0x81, 0xe6, 0x66, 0x8d, 0x66, 0x3b, 0xeb, 0x03, 0x3d, 0x86, - 0x34, 0x27, 0x47, 0xf1, 0x8b, 0x29, 0x31, 0x48, 0x30, 0x39, 0x92, 0x33, 0x2e, 0x34, 0x03, 0xfd, - 0x1c, 0xc0, 0xf5, 0x44, 0x48, 0xa4, 0xd3, 0xa7, 0xdc, 0x1c, 0x76, 0xe2, 0x12, 0x1b, 0x63, 0xd4, - 0x8c, 0x97, 0x29, 0x36, 0x7a, 0x06, 0x79, 0x87, 0xc4, 0x72, 0xcd, 0x5c, 0xfd, 0x8b, 0x61, 0xab, - 0x66, 0x5c, 0x14, 0x95, 0x8b, 0x8b, 0xf3, 0xb5, 0x5c, 0x6c, 0xc1, 0x39, 0x87, 0x18, 0xf9, 0x3e, - 0x83, 0x25, 0x49, 0xc4, 0x71, 0xd7, 0x8d, 0xd2, 0x59, 0x24, 0x93, 0x2b, 0x2a, 0x05, 0xf5, 0x8e, - 0x35, 0x69, 0x2f, 0x3e, 0xce, 0x82, 0x9c, 0xb2, 0xa1, 0x5f, 0xc0, 0x32, 0x0d, 0x1c, 0x3e, 0xd2, - 0x62, 0x8d, 0x67, 0x98, 0xbb, 0x7a, 0xb1, 0xcd, 0x31, 0x78, 0x66, 0xb1, 0x45, 0x7a, 0xc9, 0x5e, - 0xf9, 0x6b, 0x0a, 0x20, 0x2a, 0xbe, 0x3e, 0xac, 0x00, 0x11, 0xa4, 0x5d, 0x22, 0x89, 0xd6, 0x5c, - 0x01, 0xeb, 0x36, 0x7a, 0x02, 0x20, 0xe9, 0x20, 0x54, 0xa9, 0x37, 0xe8, 0x19, 0xd9, 0xbc, 0x2b, - 0x1d, 0x4c, 0xa1, 0xd1, 0x26, 0x64, 0xcc, 0xbb, 0x36, 0x7d, 0x2d, 0xcf, 0x20, 0x2b, 0x7f, 0x48, - 0x01, 0x44, 0xcb, 0xfc, 0x9f, 0x5e, 0x5b, 0xdd, 0x7e, 0xf3, 0xfd, 0xea, 0xdc, 0x5f, 0xbe, 0x5f, - 0x9d, 0xfb, 0xcd, 0xc5, 0x6a, 0xea, 0xcd, 0xc5, 0x6a, 0xea, 0xcf, 0x17, 0xab, 0xa9, 0xbf, 0x5d, - 0xac, 0xa6, 0x0e, 0x33, 0xba, 0x3e, 0xfa, 0xe1, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x32, 0x89, - 0x54, 0x8a, 0x4d, 0x16, 0x00, 0x00, + // 2178 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0x1b, 0xb9, + 0x15, 0xb7, 0x6c, 0x59, 0x7f, 0x9e, 0xe4, 0x44, 0xe6, 0x26, 0xd9, 0xb1, 0x92, 0xd8, 0x8a, 0x36, + 0x9b, 0x7a, 0x77, 0x51, 0x19, 0x75, 0x17, 0xdb, 0x6c, 0xd2, 0x6d, 0x2b, 0x59, 0x5a, 0x5b, 0x4d, + 0x62, 0x0b, 0x94, 0xe3, 0x36, 0x40, 0x01, 0x81, 0x9e, 0xa1, 0x25, 0xc2, 0xa3, 0xe1, 0x94, 0xa4, + 0x1c, 0xe8, 0xd6, 0xe3, 0xc2, 0xfd, 0x0c, 0x46, 0x0f, 0x45, 0xef, 0xed, 0xb7, 0xc8, 0xb1, 0xc7, + 0xf6, 0x62, 0x74, 0xfd, 0x15, 0x7a, 0xeb, 0xa5, 0x05, 0x39, 0x1c, 0xfd, 0x71, 0xe4, 0x38, 0x45, + 0x73, 0xe8, 0x8d, 0x7c, 0xf3, 0xfb, 0x3d, 0xfe, 0xfb, 0xbd, 0xc7, 0xc7, 0x81, 0xcf, 0xbb, 0x4c, + 0xf5, 0x06, 0x87, 0x15, 0x97, 0xf7, 0x37, 0x3c, 0xee, 0x1e, 0x53, 0xb1, 0x21, 0x5f, 0x13, 0xd1, + 0x3f, 0x66, 0x6a, 0x83, 0x84, 0x6c, 0x43, 0x86, 0xd4, 0x95, 0x95, 0x50, 0x70, 0xc5, 0x11, 0x8a, + 0x00, 0x95, 0x18, 0x50, 0x39, 0xf9, 0x51, 0xf1, 0x3a, 0xbe, 0x1a, 0x86, 0xd4, 0xf2, 0x8b, 0xb7, + 0xba, 0xbc, 0xcb, 0x4d, 0x73, 0x43, 0xb7, 0xac, 0x75, 0xb5, 0xcb, 0x79, 0xd7, 0xa7, 0x1b, 0xa6, + 0x77, 0x38, 0x38, 0xda, 0xf0, 0x06, 0x82, 0x28, 0xc6, 0x03, 0xfb, 0x7d, 0xe5, 0xf2, 0x77, 0x12, + 0x0c, 0xaf, 0xa2, 0xbe, 0x16, 0x24, 0x0c, 0xa9, 0xb0, 0x03, 0x96, 0xcf, 0x92, 0x90, 0xd9, 0xe5, + 0x1e, 0x6d, 0x87, 0xd4, 0x45, 0xdb, 0x90, 0x23, 0x41, 0xc0, 0x95, 0xf1, 0x2d, 0x9d, 0x44, 0x29, + 0xb1, 0x9e, 0xdb, 0x5c, 0xab, 0xbc, 0xbd, 0xa6, 0x4a, 0x75, 0x0c, 0xab, 0x25, 0xdf, 0x9c, 0xaf, + 0xcd, 0xe1, 0x49, 0x26, 0xfa, 0x39, 0xe4, 0x3d, 0x2a, 0x99, 0xa0, 0x5e, 0x47, 0x70, 0x9f, 0x3a, + 0xf3, 0xa5, 0xc4, 0xfa, 0x8d, 0xcd, 0x7b, 0xb3, 0x3c, 0xe9, 0xc1, 0x31, 0xf7, 0x29, 0xce, 0x59, + 0x86, 0xee, 0xa0, 0x6d, 0x80, 0x3e, 0xed, 0x1f, 0x52, 0x21, 0x7b, 0x2c, 0x74, 0x16, 0x0c, 0xfd, + 0x07, 0x57, 0xd1, 0xf5, 0xdc, 0x2b, 0x2f, 0x46, 0x70, 0x3c, 0x41, 0x45, 0x2f, 0x20, 0x4f, 0x4e, + 0x08, 0xf3, 0xc9, 0x21, 0xf3, 0x99, 0x1a, 0x3a, 0x49, 0xe3, 0xea, 0xb3, 0x77, 0xba, 0xaa, 0x4e, + 0x10, 0xf0, 0x14, 0xbd, 0xec, 0x01, 0x8c, 0x07, 0x42, 0x8f, 0x20, 0xdd, 0x6a, 0xec, 0xd6, 0x9b, + 0xbb, 0xdb, 0x85, 0xb9, 0xe2, 0xca, 0xe9, 0x59, 0xe9, 0xb6, 0xf6, 0x31, 0x06, 0xb4, 0x68, 0xe0, + 0xb1, 0xa0, 0x8b, 0xd6, 0x21, 0x53, 0xdd, 0xda, 0x6a, 0xb4, 0xf6, 0x1b, 0xf5, 0x42, 0xa2, 0x58, + 0x3c, 0x3d, 0x2b, 0xdd, 0x99, 0x06, 0x56, 0x5d, 0x97, 0x86, 0x8a, 0x7a, 0xc5, 0xe4, 0x77, 0x7f, + 0x5c, 0x9d, 0x2b, 0x7f, 0x97, 0x80, 0xfc, 0xe4, 0x24, 0xd0, 0x23, 0x48, 0x55, 0xb7, 0xf6, 0x9b, + 0x07, 0x8d, 0xc2, 0xdc, 0x98, 0x3e, 0x89, 0xa8, 0xba, 0x8a, 0x9d, 0x50, 0xf4, 0x10, 0x16, 0x5b, + 0xd5, 0x97, 0xed, 0x46, 0x21, 0x31, 0x9e, 0xce, 0x24, 0xac, 0x45, 0x06, 0xd2, 0xa0, 0xea, 0xb8, + 0xda, 0xdc, 0x2d, 0xcc, 0xcf, 0x46, 0xd5, 0x05, 0x61, 0x81, 0x9d, 0xca, 0x1f, 0x92, 0x90, 0x6b, + 0x53, 0x71, 0xc2, 0xdc, 0x0f, 0x2c, 0x91, 0xaf, 0x20, 0xa9, 0x88, 0x3c, 0x36, 0xd2, 0xc8, 0xcd, + 0x96, 0xc6, 0x3e, 0x91, 0xc7, 0x7a, 0x50, 0x4b, 0x37, 0x78, 0xad, 0x0c, 0x41, 0x43, 0x9f, 0xb9, + 0x44, 0x51, 0xcf, 0x28, 0x23, 0xb7, 0xf9, 0xe9, 0x2c, 0x36, 0x1e, 0xa1, 0xec, 0xfc, 0x77, 0xe6, + 0xf0, 0x04, 0x15, 0x3d, 0x85, 0x54, 0xd7, 0xe7, 0x87, 0xc4, 0x37, 0x9a, 0xc8, 0x6d, 0x3e, 0x98, + 0xe5, 0x64, 0xdb, 0x20, 0xc6, 0x0e, 0x2c, 0x05, 0x3d, 0x86, 0xd4, 0x20, 0xf4, 0x88, 0xa2, 0x4e, + 0xca, 0x90, 0x4b, 0xb3, 0xc8, 0x2f, 0x0d, 0x62, 0x8b, 0x07, 0x47, 0xac, 0x8b, 0x2d, 0x1e, 0x3d, + 0x83, 0x4c, 0x40, 0xd5, 0x6b, 0x2e, 0x8e, 0xa5, 0x93, 0x2e, 0x2d, 0xac, 0xe7, 0x36, 0xbf, 0x98, + 0x29, 0xc6, 0x08, 0x53, 0x55, 0x8a, 0xb8, 0xbd, 0x3e, 0x0d, 0x54, 0xe4, 0xa6, 0x36, 0xef, 0x24, + 0xf0, 0xc8, 0x01, 0xfa, 0x29, 0x64, 0x68, 0xe0, 0x85, 0x9c, 0x05, 0xca, 0xc9, 0x5c, 0x3d, 0x91, + 0x86, 0xc5, 0xe8, 0xcd, 0xc4, 0x23, 0x86, 0x66, 0x0b, 0xee, 0xfb, 0x87, 0xc4, 0x3d, 0x76, 0xb2, + 0xef, 0xb9, 0x8c, 0x11, 0xa3, 0x96, 0x82, 0x64, 0x9f, 0x7b, 0xb4, 0xbc, 0x01, 0xcb, 0x6f, 0x6d, + 0x35, 0x2a, 0x42, 0xc6, 0x6e, 0x75, 0xa4, 0x91, 0x24, 0x1e, 0xf5, 0xcb, 0x37, 0x61, 0x69, 0x6a, + 0x5b, 0xcb, 0x7f, 0x5e, 0x84, 0x4c, 0x7c, 0xd6, 0xa8, 0x0a, 0x59, 0x97, 0x07, 0x8a, 0xb0, 0x80, + 0x0a, 0x2b, 0xaf, 0x99, 0x27, 0xb3, 0x15, 0x83, 0x34, 0x6b, 0x67, 0x0e, 0x8f, 0x59, 0xe8, 0x5b, + 0xc8, 0x0a, 0x2a, 0xf9, 0x40, 0xb8, 0x54, 0x5a, 0x7d, 0xad, 0xcf, 0x56, 0x48, 0x04, 0xc2, 0xf4, + 0xb7, 0x03, 0x26, 0xa8, 0xde, 0x65, 0x89, 0xc7, 0x54, 0xf4, 0x14, 0xd2, 0x82, 0x4a, 0x45, 0x84, + 0x7a, 0x97, 0x44, 0x70, 0x04, 0x69, 0x71, 0x9f, 0xb9, 0x43, 0x1c, 0x33, 0xd0, 0x53, 0xc8, 0x86, + 0x3e, 0x71, 0x8d, 0x57, 0x67, 0xd1, 0xd0, 0xef, 0xcf, 0xa2, 0xb7, 0x62, 0x10, 0x1e, 0xe3, 0xd1, + 0xd7, 0x00, 0x3e, 0xef, 0x76, 0x3c, 0xc1, 0x4e, 0xa8, 0xb0, 0x12, 0x2b, 0xce, 0x62, 0xd7, 0x0d, + 0x02, 0x67, 0x7d, 0xde, 0x8d, 0x9a, 0x68, 0xfb, 0x7f, 0xd2, 0xd7, 0x84, 0xb6, 0x9e, 0x01, 0x90, + 0xd1, 0x57, 0xab, 0xae, 0xcf, 0xde, 0xcb, 0x95, 0x3d, 0x91, 0x09, 0x3a, 0x7a, 0x00, 0xf9, 0x23, + 0x2e, 0x5c, 0xda, 0xb1, 0x51, 0x93, 0x35, 0x9a, 0xc8, 0x19, 0x5b, 0xa4, 0x2f, 0x54, 0x83, 0x74, + 0x97, 0x06, 0x54, 0x30, 0xd7, 0x01, 0x33, 0xd8, 0xa3, 0x99, 0x01, 0x19, 0x41, 0xf0, 0x20, 0x50, + 0xac, 0x4f, 0xed, 0x48, 0x31, 0x11, 0xfd, 0x06, 0x3e, 0x8a, 0x8f, 0xaf, 0x23, 0xe8, 0x11, 0x15, + 0x34, 0xd0, 0x1a, 0xc8, 0x99, 0x7d, 0xf8, 0xf4, 0xdd, 0x1a, 0xb0, 0x68, 0x9b, 0x6c, 0x90, 0xb8, + 0xfc, 0x41, 0xd6, 0xb2, 0x90, 0x16, 0xd1, 0xb8, 0xe5, 0xdf, 0x27, 0xb4, 0xea, 0x2f, 0x21, 0xd0, + 0x06, 0xe4, 0x46, 0xc3, 0x33, 0xcf, 0xa8, 0x37, 0x5b, 0xbb, 0x71, 0x71, 0xbe, 0x06, 0x31, 0xb6, + 0x59, 0xd7, 0x39, 0xc8, 0xb6, 0x3d, 0xd4, 0x80, 0xa5, 0x11, 0x41, 0x97, 0x01, 0xf6, 0xa2, 0x2c, + 0xbd, 0x6b, 0xa6, 0xfb, 0xc3, 0x90, 0xe2, 0xbc, 0x98, 0xe8, 0x95, 0x7f, 0x0d, 0xe8, 0xed, 0x7d, + 0x41, 0x08, 0x92, 0xc7, 0x2c, 0xb0, 0xd3, 0xc0, 0xa6, 0x8d, 0x2a, 0x90, 0x0e, 0xc9, 0xd0, 0xe7, + 0xc4, 0xb3, 0x81, 0x71, 0xab, 0x12, 0x15, 0x08, 0x95, 0xb8, 0x40, 0xa8, 0x54, 0x83, 0x21, 0x8e, + 0x41, 0xe5, 0x67, 0x70, 0x7b, 0xe6, 0xf1, 0xa2, 0x4d, 0xc8, 0x8f, 0x02, 0x6e, 0xbc, 0xd6, 0x9b, + 0x17, 0xe7, 0x6b, 0xb9, 0x51, 0x64, 0x36, 0xeb, 0x38, 0x37, 0x02, 0x35, 0xbd, 0xf2, 0xe9, 0x12, + 0x2c, 0x4d, 0x85, 0x2d, 0xba, 0x05, 0x8b, 0xac, 0x4f, 0xba, 0xd4, 0xce, 0x31, 0xea, 0xa0, 0x06, + 0xa4, 0x7c, 0x72, 0x48, 0x7d, 0x1d, 0xbc, 0xfa, 0xe0, 0x7e, 0x78, 0x6d, 0xfc, 0x57, 0x9e, 0x1b, + 0x7c, 0x23, 0x50, 0x62, 0x88, 0x2d, 0x19, 0x39, 0x90, 0x76, 0x79, 0xbf, 0x4f, 0x02, 0x7d, 0x4d, + 0x2c, 0xac, 0x67, 0x71, 0xdc, 0xd5, 0x3b, 0x43, 0x44, 0x57, 0x3a, 0x49, 0x63, 0x36, 0x6d, 0x54, + 0x80, 0x05, 0x1a, 0x9c, 0x38, 0x8b, 0xc6, 0xa4, 0x9b, 0xda, 0xe2, 0xb1, 0x28, 0xfa, 0xb2, 0x58, + 0x37, 0x35, 0x6f, 0x20, 0xa9, 0x70, 0xd2, 0xd1, 0x8e, 0xea, 0x36, 0xfa, 0x09, 0xa4, 0xfa, 0x7c, + 0x10, 0x28, 0xe9, 0x64, 0xcc, 0x64, 0x57, 0x66, 0x4d, 0xf6, 0x85, 0x46, 0x58, 0x65, 0x59, 0x38, + 0x6a, 0xc0, 0xb2, 0x54, 0x3c, 0xec, 0x74, 0x05, 0x71, 0x69, 0x27, 0xa4, 0x82, 0x71, 0xcf, 0xa6, + 0xe1, 0x95, 0xb7, 0x0e, 0xa5, 0x6e, 0x0b, 0x3e, 0x7c, 0x53, 0x73, 0xb6, 0x35, 0xa5, 0x65, 0x18, + 0xa8, 0x05, 0xf9, 0x70, 0xe0, 0xfb, 0x1d, 0x1e, 0x46, 0x37, 0x72, 0x14, 0x3b, 0xef, 0xb1, 0x65, + 0xad, 0x81, 0xef, 0xef, 0x45, 0x24, 0x9c, 0x0b, 0xc7, 0x1d, 0x74, 0x07, 0x52, 0x5d, 0xc1, 0x07, + 0x61, 0x14, 0x37, 0x59, 0x6c, 0x7b, 0xe8, 0x1b, 0x48, 0x4b, 0xea, 0x0a, 0xaa, 0xa4, 0x93, 0x37, + 0x4b, 0xfd, 0x64, 0xd6, 0x20, 0x6d, 0x03, 0x19, 0xc5, 0x04, 0x8e, 0x39, 0x68, 0x05, 0x16, 0x94, + 0x1a, 0x3a, 0x4b, 0xa5, 0xc4, 0x7a, 0xa6, 0x96, 0xbe, 0x38, 0x5f, 0x5b, 0xd8, 0xdf, 0x7f, 0x85, + 0xb5, 0x4d, 0xdf, 0x16, 0x3d, 0x2e, 0x55, 0x40, 0xfa, 0xd4, 0xb9, 0x61, 0xf6, 0x76, 0xd4, 0x47, + 0xaf, 0x00, 0xbc, 0x40, 0x76, 0x5c, 0x93, 0x9e, 0x9c, 0x9b, 0x66, 0x75, 0x5f, 0x5c, 0xbf, 0xba, + 0xfa, 0x6e, 0xdb, 0xde, 0x98, 0x4b, 0x17, 0xe7, 0x6b, 0xd9, 0x51, 0x17, 0x67, 0xbd, 0x40, 0x46, + 0x4d, 0x54, 0x83, 0x5c, 0x8f, 0x12, 0x5f, 0xf5, 0xdc, 0x1e, 0x75, 0x8f, 0x9d, 0xc2, 0xd5, 0x57, + 0xe0, 0x8e, 0x81, 0x59, 0x0f, 0x93, 0x24, 0xad, 0x60, 0x3d, 0x55, 0xe9, 0x2c, 0x9b, 0xbd, 0x8a, + 0x3a, 0xe8, 0x3e, 0x00, 0x0f, 0x69, 0xd0, 0x91, 0xca, 0x63, 0x81, 0x83, 0xf4, 0x92, 0x71, 0x56, + 0x5b, 0xda, 0xda, 0x80, 0xee, 0xea, 0x0b, 0x8a, 0x78, 0x1d, 0x1e, 0xf8, 0x43, 0xe7, 0x23, 0xf3, + 0x35, 0xa3, 0x0d, 0x7b, 0x81, 0x3f, 0x44, 0x6b, 0x90, 0x33, 0xba, 0x90, 0xac, 0x1b, 0x10, 0xdf, + 0xb9, 0x65, 0xf6, 0x03, 0xb4, 0xa9, 0x6d, 0x2c, 0xfa, 0x1c, 0xa2, 0xdd, 0x90, 0xce, 0xed, 0xab, + 0xcf, 0xc1, 0x4e, 0x76, 0x7c, 0x0e, 0x96, 0x83, 0x7e, 0x06, 0x10, 0x0a, 0x76, 0xc2, 0x7c, 0xda, + 0xa5, 0xd2, 0xb9, 0x63, 0x16, 0xbd, 0x3a, 0xf3, 0x66, 0x1a, 0xa1, 0xf0, 0x04, 0x03, 0x55, 0x20, + 0xc9, 0x02, 0xa6, 0x9c, 0x8f, 0xed, 0xad, 0x74, 0x59, 0xaa, 0x35, 0xce, 0xfd, 0x03, 0xe2, 0x0f, + 0x28, 0x36, 0x38, 0xd4, 0x84, 0x2c, 0x93, 0xdc, 0x37, 0xf2, 0x75, 0x1c, 0x93, 0xdf, 0xde, 0xe3, + 0xfc, 0x9a, 0x31, 0x05, 0x8f, 0xd9, 0xe8, 0x1e, 0x64, 0x43, 0xe6, 0xc9, 0xe7, 0xac, 0xcf, 0x94, + 0xb3, 0x52, 0x4a, 0xac, 0x2f, 0xe0, 0xb1, 0x01, 0xed, 0x40, 0x5a, 0x0e, 0xa5, 0xab, 0x7c, 0xe9, + 0x14, 0xcd, 0xbe, 0x54, 0xae, 0x1f, 0xa6, 0x1d, 0x11, 0xa2, 0xc4, 0x11, 0xd3, 0x51, 0x19, 0xf2, + 0x2e, 0x09, 0xa3, 0x6a, 0x98, 0x51, 0xe9, 0xdc, 0x35, 0x67, 0x3b, 0x65, 0x2b, 0x7e, 0x0d, 0xb9, + 0x89, 0xa4, 0xa3, 0x93, 0xc5, 0x31, 0x1d, 0xda, 0x3c, 0xa6, 0x9b, 0x5a, 0x19, 0x27, 0x7a, 0x1b, + 0x4c, 0xa2, 0xcd, 0xe2, 0xa8, 0xf3, 0x64, 0xfe, 0x71, 0xa2, 0xb8, 0x09, 0xb9, 0x89, 0xe0, 0x43, + 0x9f, 0xe8, 0x4b, 0xa0, 0xcb, 0xa4, 0x12, 0xc3, 0x0e, 0x19, 0xa8, 0x9e, 0xf3, 0x0b, 0x43, 0xc8, + 0xc7, 0xc6, 0xea, 0x40, 0xf5, 0x8a, 0x1d, 0x18, 0x6b, 0x18, 0x95, 0x20, 0xa7, 0x63, 0x43, 0x52, + 0x71, 0x42, 0x85, 0x2e, 0xb0, 0xf4, 0xf4, 0x26, 0x4d, 0x3a, 0x86, 0x25, 0x25, 0xc2, 0xed, 0x99, + 0x14, 0x9a, 0xc5, 0xb6, 0xa7, 0x73, 0x62, 0x9c, 0x28, 0x6c, 0x4e, 0xb4, 0xdd, 0xe2, 0x13, 0xc8, + 0x4f, 0x6e, 0xc6, 0x7f, 0xb3, 0xa0, 0xf2, 0x5f, 0x12, 0x90, 0x1d, 0x1d, 0x18, 0xfa, 0x12, 0x96, + 0x9b, 0xed, 0xbd, 0xe7, 0xd5, 0xfd, 0xe6, 0xde, 0x6e, 0xa7, 0xde, 0xf8, 0xb6, 0xfa, 0xf2, 0xf9, + 0x7e, 0x61, 0xae, 0x78, 0xff, 0xf4, 0xac, 0xb4, 0x32, 0xbe, 0x1b, 0x62, 0x78, 0x9d, 0x1e, 0x91, + 0x81, 0xaf, 0xa6, 0x59, 0x2d, 0xbc, 0xb7, 0xd5, 0x68, 0xb7, 0x0b, 0x89, 0xab, 0x58, 0x2d, 0xc1, + 0x5d, 0x2a, 0x25, 0xda, 0x84, 0xc2, 0x98, 0xb5, 0xf3, 0xaa, 0xd5, 0xc0, 0x07, 0x85, 0xf9, 0xe2, + 0xbd, 0xd3, 0xb3, 0x92, 0xf3, 0x36, 0x69, 0x67, 0x18, 0x52, 0x71, 0x60, 0x1f, 0x36, 0xff, 0x4c, + 0x40, 0x7e, 0xb2, 0x2e, 0x46, 0x5b, 0x51, 0x3d, 0x6b, 0x56, 0x7c, 0x63, 0x73, 0xe3, 0xba, 0x3a, + 0xda, 0xdc, 0xc7, 0xfe, 0x40, 0xfb, 0x7d, 0xa1, 0x9f, 0xb0, 0x86, 0x8c, 0xbe, 0x84, 0xc5, 0x90, + 0x0b, 0x15, 0xdf, 0x5c, 0xb3, 0xe3, 0x8a, 0x8b, 0xb8, 0xda, 0x8a, 0xc0, 0xe5, 0x1e, 0xdc, 0x98, + 0xf6, 0x86, 0x1e, 0xc2, 0xc2, 0x41, 0xb3, 0x55, 0x98, 0x2b, 0xde, 0x3d, 0x3d, 0x2b, 0x7d, 0x3c, + 0xfd, 0xf1, 0x80, 0x09, 0x35, 0x20, 0x7e, 0xb3, 0x85, 0x3e, 0x87, 0xc5, 0xfa, 0x6e, 0x1b, 0xe3, + 0x42, 0xa2, 0xb8, 0x76, 0x7a, 0x56, 0xba, 0x3b, 0x8d, 0xd3, 0x9f, 0xf8, 0x20, 0xf0, 0x30, 0x3f, + 0x1c, 0x3d, 0xe7, 0xfe, 0x35, 0x0f, 0x39, 0x7b, 0xa1, 0x7f, 0xe8, 0x17, 0xff, 0x52, 0x54, 0xad, + 0xc6, 0x99, 0x7a, 0xfe, 0xda, 0xa2, 0x35, 0x1f, 0x11, 0xac, 0xa6, 0x1f, 0x40, 0x9e, 0x85, 0x27, + 0x5f, 0x75, 0x68, 0x40, 0x0e, 0x7d, 0xfb, 0xb2, 0xcb, 0xe0, 0x9c, 0xb6, 0x35, 0x22, 0x93, 0xbe, + 0x26, 0x58, 0xa0, 0xa8, 0x08, 0xec, 0x9b, 0x2d, 0x83, 0x47, 0x7d, 0xf4, 0x0d, 0x24, 0x59, 0x48, + 0xfa, 0xb6, 0xd2, 0x9e, 0xb9, 0x82, 0x66, 0xab, 0xfa, 0xc2, 0xc6, 0x5c, 0x2d, 0x73, 0x71, 0xbe, + 0x96, 0xd4, 0x06, 0x6c, 0x68, 0x68, 0x35, 0x2e, 0x76, 0xf5, 0x48, 0xe6, 0xca, 0xcf, 0xe0, 0x09, + 0x8b, 0x8e, 0x1b, 0x16, 0x74, 0x05, 0x95, 0xd2, 0x5c, 0xfe, 0x19, 0x1c, 0x77, 0x51, 0x11, 0xd2, + 0xb6, 0x64, 0x36, 0x35, 0x72, 0x56, 0x97, 0xa3, 0xd6, 0x50, 0x5b, 0x82, 0x5c, 0xb4, 0x1b, 0x9d, + 0x23, 0xc1, 0xfb, 0xe5, 0x7f, 0x27, 0x21, 0xb7, 0xe5, 0x0f, 0xa4, 0xb2, 0xd5, 0xcf, 0x07, 0xdb, + 0xfc, 0x57, 0xb0, 0x4c, 0xcc, 0x1f, 0x04, 0x12, 0xe8, 0x52, 0xc2, 0xbc, 0x44, 0xec, 0x01, 0x3c, + 0x9c, 0xe9, 0x6e, 0x04, 0x8e, 0x5e, 0x2d, 0xb5, 0x94, 0xf6, 0xe9, 0x24, 0x70, 0x81, 0x5c, 0xfa, + 0x82, 0xda, 0xb0, 0xc4, 0x85, 0xdb, 0xa3, 0x52, 0x45, 0x05, 0x88, 0x7d, 0x71, 0xcf, 0xfc, 0x17, + 0xb3, 0x37, 0x09, 0xb4, 0xb7, 0x6f, 0x34, 0xdb, 0x69, 0x1f, 0xe8, 0x31, 0x24, 0x05, 0x39, 0x8a, + 0x5f, 0x55, 0x33, 0x83, 0x04, 0x93, 0x23, 0x35, 0xe5, 0xc2, 0x30, 0xd0, 0x2f, 0x01, 0x3c, 0x26, + 0x43, 0xa2, 0xdc, 0x1e, 0x15, 0xf6, 0xb0, 0x67, 0x2e, 0xb1, 0x3e, 0x42, 0x4d, 0x79, 0x99, 0x60, + 0xa3, 0x67, 0x90, 0x75, 0x49, 0x2c, 0xd7, 0xd4, 0xd5, 0xbf, 0x21, 0xb6, 0xaa, 0xd6, 0x45, 0x41, + 0xbb, 0xb8, 0x38, 0x5f, 0xcb, 0xc4, 0x16, 0x9c, 0x71, 0x89, 0x95, 0xef, 0x33, 0x58, 0x52, 0x44, + 0x1e, 0x77, 0xbc, 0x28, 0x9d, 0x45, 0x32, 0xb9, 0xa2, 0x9a, 0xd0, 0x6f, 0x5d, 0x9b, 0xf6, 0xe2, + 0xe3, 0xcc, 0xab, 0x09, 0x1b, 0xfa, 0x15, 0x2c, 0xd3, 0xc0, 0x15, 0x43, 0x23, 0xd6, 0x78, 0x86, + 0x99, 0xab, 0x17, 0xdb, 0x18, 0x81, 0xa7, 0x16, 0x5b, 0xa0, 0x97, 0xec, 0xe5, 0xbf, 0x27, 0x00, + 0xa2, 0x02, 0xed, 0xc3, 0x0a, 0x10, 0x41, 0xd2, 0x23, 0x8a, 0x18, 0xcd, 0xe5, 0xb1, 0x69, 0xa3, + 0x27, 0x00, 0x8a, 0xf6, 0x43, 0x9d, 0x7a, 0x83, 0xae, 0x95, 0xcd, 0xbb, 0xd2, 0xc1, 0x04, 0x1a, + 0x6d, 0x42, 0xca, 0xbe, 0x7d, 0x93, 0xd7, 0xf2, 0x2c, 0xb2, 0xfc, 0xa7, 0x04, 0x40, 0xb4, 0xcc, + 0xff, 0xeb, 0xb5, 0xd5, 0x9c, 0x37, 0xdf, 0xaf, 0xce, 0xfd, 0xed, 0xfb, 0xd5, 0xb9, 0xdf, 0x5d, + 0xac, 0x26, 0xde, 0x5c, 0xac, 0x26, 0xfe, 0x7a, 0xb1, 0x9a, 0xf8, 0xc7, 0xc5, 0x6a, 0xe2, 0x30, + 0x65, 0x6a, 0xa8, 0x1f, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x13, 0x42, 0x73, 0x71, 0x16, + 0x00, 0x00, } diff --git a/api/specs.proto b/api/specs.proto index f464542609..6858a30b3e 100644 --- a/api/specs.proto +++ b/api/specs.proto @@ -333,6 +333,9 @@ message ContainerSpec { // // https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime map sysctls = 26; + + // Capabilities is the list of Linux capabilities to be available for container (this overrides the default set of capabilities) + repeated string capabilities = 27; } // EndpointSpec defines the properties that can be configured to diff --git a/cmd/swarmctl/service/flagparser/capability.go b/cmd/swarmctl/service/flagparser/capability.go new file mode 100644 index 0000000000..f35e2f7567 --- /dev/null +++ b/cmd/swarmctl/service/flagparser/capability.go @@ -0,0 +1,72 @@ +package flagparser + +import ( + "github.com/docker/swarmkit/api" + "github.com/spf13/cobra" +) + +// ParseAddCapability validates capabilities passed on the command line +func ParseAddCapability(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error { + flags := cmd.Flags() + + if flags.Changed(flagName) { + capabilities, err := flags.GetStringSlice(flagName) + if err != nil { + return err + } + + container := spec.Task.GetContainer() + if container == nil { + return nil + } + + oldCapabilities := make(map[string]struct{}) + for _, capability := range container.Capabilities { + oldCapabilities[capability] = struct{}{} + } + + var newCapabilities = container.Capabilities + for _, capability := range capabilities { + if _, ok := oldCapabilities[capability]; ok { + continue + } + newCapabilities = append(newCapabilities, capability) + } + container.Capabilities = newCapabilities + } + + return nil +} + +// ParseRemoveCapability removes a set of capabilities from the task spec's capability references +func ParseRemoveCapability(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error { + flags := cmd.Flags() + + if flags.Changed(flagName) { + capabilities, err := flags.GetStringSlice(flagName) + if err != nil { + return err + } + + container := spec.Task.GetContainer() + if container == nil { + return nil + } + + wantToDelete := make(map[string]struct{}) + for _, capability := range capabilities { + wantToDelete[capability] = struct{}{} + } + + var newCapabilities []string + for _, capabilityRef := range container.Capabilities { + if _, ok := wantToDelete[capabilityRef]; ok { + continue + } + newCapabilities = append(newCapabilities, capabilityRef) + } + container.Capabilities = newCapabilities + } + + return nil +} diff --git a/cmd/swarmctl/service/update.go b/cmd/swarmctl/service/update.go index 6f15cc2232..9dc3df35ba 100644 --- a/cmd/swarmctl/service/update.go +++ b/cmd/swarmctl/service/update.go @@ -54,6 +54,13 @@ var ( return err } + if err := flagparser.ParseAddCapability(cmd, spec, "add-capability"); err != nil { + return err + } + if err := flagparser.ParseRemoveCapability(cmd, spec, "rm-capability"); err != nil { + return err + } + if reflect.DeepEqual(spec, &service.Spec) { return errors.New("no changes detected") } @@ -77,6 +84,8 @@ func init() { updateCmd.Flags().StringSlice("rm-secret", nil, "remove a secret from the service") updateCmd.Flags().StringSlice("add-config", nil, "add a new config to the service") updateCmd.Flags().StringSlice("rm-config", nil, "remove a config from the service") + updateCmd.Flags().StringSlice("add-capability", nil, "add a new capability to the service") + updateCmd.Flags().StringSlice("rm-capability", nil, "remove a capability from the service") updateCmd.Flags().Bool("force", false, "force tasks to restart even if nothing has changed") flagparser.AddServiceFlags(updateCmd.Flags()) }