Bump docker/cli to 06f34ba50786ec67761745c818e87baecc2ba139

Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
pull/207/head
ulyssessouza 5 years ago
parent f2be09f4e4
commit 9e8c532e61

@ -17,7 +17,7 @@ require (
github.com/containerd/containerd v1.4.0-0.20191014053712-acdcf13d5eaf
github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 // indirect
github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853 // indirect
github.com/docker/cli v1.14.0-0.20190523191156-ab688a9a79a1
github.com/docker/cli v0.0.0-20191010210043-06f34ba50786
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 // indirect
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible
github.com/docker/docker v1.14.0-0.20190410063227-3998dffb806f3887f804b813069f59bc14a7f3c1

@ -80,8 +80,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853 h1:tTngnoO/B
github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
github.com/docker/cli v0.0.0-20190321234815-f40f9c240ab0 h1:E7NTtHfZYV+iu35yZ49AbrxqhMHpiOl3FstDYm38vQ0=
github.com/docker/cli v0.0.0-20190321234815-f40f9c240ab0/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v1.14.0-0.20190523191156-ab688a9a79a1 h1:Va5DmtF6dHEy+IjKQEkOkTVKmGSPysDDSf8Md0w0RXg=
github.com/docker/cli v1.14.0-0.20190523191156-ab688a9a79a1/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v0.0.0-20191010210043-06f34ba50786 h1:pxYpNKywpPwY4ZchdnguI7AiAu9rlv6S05iV4y+6srQ=
github.com/docker/cli v0.0.0-20191010210043-06f34ba50786/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 h1:90ytrX1dbzL7Uf/hHiuWwvywC+gikHv4hkAy4CwRTbs=
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496/go.mod h1:iT2pYfi580XlpaV4KmK0T6+4/9+XoKmk/fhoDod1emE=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible h1:dvc1KSkIYTVjZgHf/CTC2diTYC8PzhaA5sFISRfNVrE=

@ -11,6 +11,7 @@ Abin Shahab <ashahab@altiscale.com>
Ace Tang <aceapril@126.com>
Addam Hardy <addam.hardy@gmail.com>
Adolfo Ochagavía <aochagavia92@gmail.com>
Adrian Plata <adrian.plata@docker.com>
Adrien Duermael <adrien@duermael.com>
Adrien Folie <folie.adrien@gmail.com>
Ahmet Alp Balkan <ahmetb@microsoft.com>
@ -136,6 +137,7 @@ Dafydd Crosby <dtcrsby@gmail.com>
dalanlan <dalanlan925@gmail.com>
Damien Nadé <github@livna.org>
Dan Cotora <dan@bluevision.ro>
Daniel Cassidy <mail@danielcassidy.me.uk>
Daniel Dao <dqminh@cloudflare.com>
Daniel Farrell <dfarrell@redhat.com>
Daniel Gasienica <daniel@gasienica.ch>
@ -215,6 +217,7 @@ Felix Rabe <felix@rabe.io>
Filip Jareš <filipjares@gmail.com>
Flavio Crisciani <flavio.crisciani@docker.com>
Florian Klein <florian.klein@free.fr>
Forest Johnson <fjohnson@peoplenetonline.com>
Foysal Iqbal <foysal.iqbal.fb@gmail.com>
François Scala <francois.scala@swiss-as.com>
Fred Lifton <fred.lifton@docker.com>
@ -231,6 +234,7 @@ George MacRorie <gmacr31@gmail.com>
George Xie <georgexsh@gmail.com>
Gianluca Borello <g.borello@gmail.com>
Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
Goksu Toprak <goksu.toprak@docker.com>
Gou Rao <gou@portworx.com>
Grant Reaber <grant.reaber@gmail.com>
Greg Pflaum <gpflaum@users.noreply.github.com>
@ -351,6 +355,7 @@ Kara Alexandra <kalexandra@us.ibm.com>
Kareem Khazem <karkhaz@karkhaz.com>
Karthik Nayak <Karthik.188@gmail.com>
Kat Samperi <kat.samperi@gmail.com>
Kathryn Spiers <kathryn@spiers.me>
Katie McLaughlin <katie@glasnt.com>
Ke Xu <leonhartx.k@gmail.com>
Kei Ohmura <ohmura.kei@gmail.com>
@ -372,7 +377,6 @@ Krasi Georgiev <krasi@vip-consult.solutions>
Kris-Mikael Krister <krismikael@protonmail.com>
Kun Zhang <zkazure@gmail.com>
Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
Kyle Spiers <kyle@spiers.me>
Lachlan Cooper <lachlancooper@gmail.com>
Lai Jiangshan <jiangshanlai@gmail.com>
Lars Kellogg-Stedman <lars@redhat.com>
@ -537,6 +541,7 @@ Qiang Huang <h.huangqiang@huawei.com>
Qinglan Peng <qinglanpeng@zju.edu.cn>
qudongfang <qudongfang@gmail.com>
Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
Ravi Shekhar Jethani <rsjethani@gmail.com>
Ray Tsang <rayt@google.com>
Reficul <xuzhenglun@gmail.com>
Remy Suen <remy.suen@gmail.com>
@ -553,6 +558,7 @@ Robin Naundorf <r.naundorf@fh-muenster.de>
Robin Speekenbrink <robin@kingsquare.nl>
Rodolfo Ortiz <rodolfo.ortiz@definityfirst.com>
Rogelio Canedo <rcanedo@mappy.priv>
Rohan Verma <hello@rohanverma.net>
Roland Kammerer <roland.kammerer@linbit.com>
Roman Dudin <katrmr@gmail.com>
Rory Hunter <roryhunter2@gmail.com>
@ -701,6 +707,7 @@ Yuan Sun <sunyuan3@huawei.com>
Yue Zhang <zy675793960@yeah.net>
Yunxiang Huang <hyxqshk@vip.qq.com>
Zachary Romero <zacromero3@gmail.com>
Zander Mackie <zmackie@gmail.com>
zebrilee <zebrilee@gmail.com>
Zhang Kun <zkazure@gmail.com>
Zhang Wei <zhangwei555@huawei.com>

@ -3,7 +3,7 @@ Copyright 2012-2017 Docker, Inc.
This product includes software developed at Docker, Inc. (https://www.docker.com).
This product contains software (https://github.com/kr/pty) developed
This product contains software (https://github.com/creack/pty) developed
by Keith Rarick, licensed under the MIT License.
The following is courtesy of our legal counsel:

@ -14,7 +14,6 @@ import (
"github.com/docker/cli/cli/config/configfile"
dcontext "github.com/docker/cli/cli/context"
"github.com/docker/cli/cli/context/docker"
kubecontext "github.com/docker/cli/cli/context/kubernetes"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/cli/debug"
cliflags "github.com/docker/cli/cli/flags"
@ -210,11 +209,11 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
cli.configFile = cliconfig.LoadDefaultConfigFile(cli.err)
baseContextSore := store.New(cliconfig.ContextStoreDir(), cli.contextStoreConfig)
baseContextStore := store.New(cliconfig.ContextStoreDir(), cli.contextStoreConfig)
cli.contextStore = &ContextStoreWithDefault{
Store: baseContextSore,
Store: baseContextStore,
Resolver: func() (*DefaultContext, error) {
return resolveDefaultContext(opts.Common, cli.ConfigFile(), cli.Err())
return ResolveDefaultContext(opts.Common, cli.ConfigFile(), cli.contextStoreConfig, cli.Err())
},
}
cli.currentContext, err = resolveContextName(opts.Common, cli.configFile, cli.contextStore)
@ -259,10 +258,11 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
// NewAPIClientFromFlags creates a new APIClient from command line flags
func NewAPIClientFromFlags(opts *cliflags.CommonOptions, configFile *configfile.ConfigFile) (client.APIClient, error) {
storeConfig := DefaultContextStoreConfig()
store := &ContextStoreWithDefault{
Store: store.New(cliconfig.ContextStoreDir(), defaultContextStoreConfig()),
Store: store.New(cliconfig.ContextStoreDir(), storeConfig),
Resolver: func() (*DefaultContext, error) {
return resolveDefaultContext(opts, configFile, ioutil.Discard)
return ResolveDefaultContext(opts, configFile, storeConfig, ioutil.Discard)
},
}
contextName, err := resolveContextName(opts, configFile, store)
@ -453,7 +453,7 @@ func NewDockerCli(ops ...DockerCliOption) (*DockerCli, error) {
WithContentTrustFromEnv(),
WithContainerizedClient(containerizedengine.NewClient),
}
cli.contextStoreConfig = defaultContextStoreConfig()
cli.contextStoreConfig = DefaultContextStoreConfig()
ops = append(defaultOps, ops...)
if err := cli.Apply(ops...); err != nil {
return nil, err
@ -526,10 +526,22 @@ func resolveContextName(opts *cliflags.CommonOptions, config *configfile.ConfigF
return DefaultContextName, nil
}
func defaultContextStoreConfig() store.Config {
var defaultStoreEndpoints = []store.NamedTypeGetter{
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
}
// RegisterDefaultStoreEndpoints registers a new named endpoint
// metadata type with the default context store config, so that
// endpoint will be supported by stores using the config returned by
// DefaultContextStoreConfig.
func RegisterDefaultStoreEndpoints(ep ...store.NamedTypeGetter) {
defaultStoreEndpoints = append(defaultStoreEndpoints, ep...)
}
// DefaultContextStoreConfig returns a new store.Config with the default set of endpoints configured.
func DefaultContextStoreConfig() store.Config {
return store.NewConfig(
func() interface{} { return &DockerContext{} },
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
store.EndpointTypeGetter(kubecontext.KubernetesEndpoint, func() interface{} { return &kubecontext.EndpointMeta{} }),
defaultStoreEndpoints...,
)
}

@ -7,7 +7,6 @@ import (
"strconv"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/kubernetes"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/cli/streams"
clitypes "github.com/docker/cli/types"
@ -97,7 +96,7 @@ func WithContainerizedClient(containerizedFn func(string) (clitypes.Containerize
func WithContextEndpointType(endpointName string, endpointType store.TypeGetter) DockerCliOption {
return func(cli *DockerCli) error {
switch endpointName {
case docker.DockerEndpoint, kubernetes.KubernetesEndpoint:
case docker.DockerEndpoint:
return fmt.Errorf("cannot change %q endpoint type", endpointName)
}
cli.contextStoreConfig.SetEndpoint(endpointName, endpointType)

@ -3,15 +3,11 @@ package command
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/kubernetes"
"github.com/docker/cli/cli/context/store"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/docker/pkg/homedir"
"github.com/pkg/errors"
)
@ -20,7 +16,7 @@ const (
DefaultContextName = "default"
)
// DefaultContext contains the default context data for all enpoints
// DefaultContext contains the default context data for all endpoints
type DefaultContext struct {
Meta store.Metadata
TLS store.ContextTLSData
@ -35,8 +31,21 @@ type ContextStoreWithDefault struct {
Resolver DefaultContextResolver
}
// resolveDefaultContext creates a Metadata for the current CLI invocation parameters
func resolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.ConfigFile, stderr io.Writer) (*DefaultContext, error) {
// EndpointDefaultResolver is implemented by any EndpointMeta object
// which wants to be able to populate the store with whatever their default is.
type EndpointDefaultResolver interface {
// ResolveDefault returns values suitable for storing in store.Metadata.Endpoints
// and store.ContextTLSData.Endpoints.
//
// An error is only returned for something fatal, not simply
// the lack of a default (e.g. because the config file which
// would contain it is missing). If there is no default then
// returns nil, nil, nil.
ResolveDefault(Orchestrator) (interface{}, *store.EndpointTLSData, error)
}
// ResolveDefaultContext creates a Metadata for the current CLI invocation parameters
func ResolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.ConfigFile, storeconfig store.Config, stderr io.Writer) (*DefaultContext, error) {
stackOrchestrator, err := GetStackOrchestrator("", "", config.StackOrchestrator, stderr)
if err != nil {
return nil, err
@ -62,20 +71,28 @@ func resolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.Conf
contextTLSData.Endpoints[docker.DockerEndpoint] = *dockerEP.TLSData.ToStoreTLSData()
}
// Default context uses env-based kubeconfig for Kubernetes endpoint configuration
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig == "" {
kubeconfig = filepath.Join(homedir.Get(), ".kube/config")
}
kubeEP, err := kubernetes.FromKubeConfig(kubeconfig, "", "")
if (stackOrchestrator == OrchestratorKubernetes || stackOrchestrator == OrchestratorAll) && err != nil {
return nil, errors.Wrapf(err, "default orchestrator is %s but kubernetes endpoint could not be found", stackOrchestrator)
}
if err == nil {
contextMetadata.Endpoints[kubernetes.KubernetesEndpoint] = kubeEP.EndpointMeta
if kubeEP.TLSData != nil {
contextTLSData.Endpoints[kubernetes.KubernetesEndpoint] = *kubeEP.TLSData.ToStoreTLSData()
if err := storeconfig.ForeachEndpointType(func(n string, get store.TypeGetter) error {
if n == docker.DockerEndpoint { // handled above
return nil
}
ep := get()
if i, ok := ep.(EndpointDefaultResolver); ok {
meta, tls, err := i.ResolveDefault(stackOrchestrator)
if err != nil {
return err
}
if meta == nil {
return nil
}
contextMetadata.Endpoints[n] = meta
if tls != nil {
contextTLSData.Endpoints[n] = *tls
}
}
// Nothing to be done
return nil
}); err != nil {
return nil, err
}
return &DefaultContext{Meta: contextMetadata, TLS: contextTLSData}, nil

@ -1,4 +1,4 @@
version: "3.8"
version: "3.9"
services:
foo:

@ -16,6 +16,8 @@ var interpolateTypeCastMapping = map[interp.Path]interp.Cast{
servicePath("deploy", "replicas"): toInt,
servicePath("deploy", "update_config", "parallelism"): toInt,
servicePath("deploy", "update_config", "max_failure_ratio"): toFloat,
servicePath("deploy", "rollback_config", "parallelism"): toInt,
servicePath("deploy", "rollback_config", "max_failure_ratio"): toFloat,
servicePath("deploy", "restart_policy", "max_attempts"): toInt,
servicePath("ports", interp.PathMatchList, "target"): toInt,
servicePath("ports", interp.PathMatchList, "published"): toInt,

@ -32,6 +32,14 @@ type Options struct {
SkipInterpolation bool
// Interpolation options
Interpolate *interp.Options
// Discard 'env_file' entries after resolving to 'environment' section
discardEnvFiles bool
}
// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to
// the `environment` section
func WithDiscardEnvFiles(opts *Options) {
opts.discardEnvFiles = true
}
// ParseYAML reads the bytes from a file, parses the bytes into a mapping
@ -105,6 +113,11 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
return nil, err
}
cfg.Filename = file.Filename
if opts.discardEnvFiles {
for i := range cfg.Services {
cfg.Services[i].EnvFile = nil
}
}
configs = append(configs, cfg)
}
@ -479,12 +492,13 @@ func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string,
}
filePath := expandUser(volume.Source, lookupEnv)
// Check for a Unix absolute path first, to handle a Windows client
// with a Unix daemon. This handles a Windows client connecting to a
// Unix daemon. Note that this is not required for Docker for Windows
// when specifying a local Windows path, because Docker for Windows
// translates the Windows path into a valid path within the VM.
if !path.IsAbs(filePath) {
// Check if source is an absolute path (either Unix or Windows), to
// handle a Windows client with a Unix daemon or vice-versa.
//
// Note that this is not required for Docker for Windows when specifying
// a local Windows path, because Docker for Windows translates the Windows
// path into a valid path within the VM.
if !path.IsAbs(filePath) && !isAbs(filePath) {
filePath = absPath(workingDir, filePath)
}
volume.Source = filePath

@ -0,0 +1,66 @@
package loader
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// https://github.com/golang/go/blob/master/LICENSE
// This file contains utilities to check for Windows absolute paths on Linux.
// The code in this file was largely copied from the Golang filepath package
// https://github.com/golang/go/blob/1d0e94b1e13d5e8a323a63cd1cc1ef95290c9c36/src/path/filepath/path_windows.go#L12-L65
func isSlash(c uint8) bool {
return c == '\\' || c == '/'
}
// isAbs reports whether the path is a Windows absolute path.
func isAbs(path string) (b bool) {
l := volumeNameLen(path)
if l == 0 {
return false
}
path = path[l:]
if path == "" {
return false
}
return isSlash(path[0])
}
// volumeNameLen returns length of the leading volume name on Windows.
// It returns 0 elsewhere.
// nolint: gocyclo
func volumeNameLen(path string) int {
if len(path) < 2 {
return 0
}
// with drive letter
c := path[0]
if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
return 2
}
// is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
!isSlash(path[2]) && path[2] != '.' {
// first, leading `\\` and next shouldn't be `\`. its server name.
for n := 3; n < l-1; n++ {
// second, next '\' shouldn't be repeated.
if isSlash(path[n]) {
n++
// third, following something characters. its share name.
if !isSlash(path[n]) {
if path[n] == '.' {
break
}
for ; n < l; n++ {
if isSlash(path[n]) {
break
}
}
return n
}
break
}
}
}
return 0
}

@ -552,6 +552,50 @@ ean7MQBPP+U4w19V/z+t/hsAAP//Fd/bF0ZHAAA=
`,
},
"/data/config_schema_v3.9.json": {
local: "data/config_schema_v3.9.json",
size: 18246,
modtime: 1518458244,
compressed: `
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
vNT9GICnn3Kc4a+q/59W/w0AAP//CCwovkZHAAA=
`,
},
"/": {
isDir: true,
local: "",

@ -18,15 +18,19 @@ const (
type portsFormatChecker struct{}
func (checker portsFormatChecker) IsFormat(input string) bool {
func (checker portsFormatChecker) IsFormat(input interface{}) bool {
// TODO: implement this
return true
}
type durationFormatChecker struct{}
func (checker durationFormatChecker) IsFormat(input string) bool {
_, err := time.ParseDuration(input)
func (checker durationFormatChecker) IsFormat(input interface{}) bool {
value, ok := input.(string)
if !ok {
return false
}
_, err := time.ParseDuration(value)
return err == nil
}

@ -10,7 +10,6 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
"github.com/docker/cli/cli/config/types"
"github.com/docker/docker/pkg/homedir"
"github.com/pkg/errors"
)
@ -28,7 +27,10 @@ var (
func init() {
if configDir == "" {
configDir = filepath.Join(homedir.Get(), configFileDir)
homedir, err := os.UserHomeDir()
if err == nil {
configDir = filepath.Join(homedir, configFileDir)
}
}
}
@ -106,7 +108,11 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
}
// Can't find latest config file so check for the old one
confFile := filepath.Join(homedir.Get(), oldConfigfile)
homedir, err := os.UserHomeDir()
if err != nil {
return configFile, errors.Wrap(err, oldConfigfile)
}
confFile := filepath.Join(homedir, oldConfigfile)
if _, err := os.Stat(confFile); err != nil {
return configFile, nil //missing file is not an error
}

@ -104,8 +104,8 @@ func (c *Endpoint) ClientOpts() ([]client.Opt, error) {
return nil, err
}
result = append(result,
client.WithHost(c.Host),
withHTTPClient(tlsConfig),
client.WithHost(c.Host),
)
} else {

@ -1,9 +1,15 @@
package kubernetes
import (
"os"
"path/filepath"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context"
"github.com/docker/cli/cli/context/store"
api "github.com/docker/compose-on-kubernetes/api"
"github.com/docker/docker/pkg/homedir"
"github.com/pkg/errors"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)
@ -17,6 +23,8 @@ type EndpointMeta struct {
Exec *clientcmdapi.ExecConfig `json:",omitempty"`
}
var _ command.EndpointDefaultResolver = &EndpointMeta{}
// Endpoint is a typed wrapper around a context-store generic endpoint describing
// a Kubernetes endpoint, with TLS data
type Endpoint struct {
@ -24,6 +32,12 @@ type Endpoint struct {
TLSData *context.TLSData
}
func init() {
command.RegisterDefaultStoreEndpoints(
store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
)
}
// WithTLSData loads TLS materials for the endpoint
func (c *EndpointMeta) WithTLSData(s store.Reader, contextName string) (Endpoint, error) {
tlsData, err := context.LoadTLSData(s, contextName, KubernetesEndpoint)
@ -61,6 +75,32 @@ func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
return clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
}
// ResolveDefault returns endpoint metadata for the default Kubernetes
// endpoint, which is derived from the env-based kubeconfig.
func (c *EndpointMeta) ResolveDefault(stackOrchestrator command.Orchestrator) (interface{}, *store.EndpointTLSData, error) {
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig == "" {
kubeconfig = filepath.Join(homedir.Get(), ".kube/config")
}
kubeEP, err := FromKubeConfig(kubeconfig, "", "")
if err != nil {
if stackOrchestrator == command.OrchestratorKubernetes || stackOrchestrator == command.OrchestratorAll {
return nil, nil, errors.Wrapf(err, "default orchestrator is %s but unable to resolve kubernetes endpoint", stackOrchestrator)
}
// We deliberately quash the error here, returning nil
// for the first argument is sufficient to indicate we weren't able to
// provide a default
return nil, nil, nil
}
var tls *store.EndpointTLSData
if kubeEP.TLSData != nil {
tls = kubeEP.TLSData.ToStoreTLSData()
}
return kubeEP.EndpointMeta, tls, nil
}
// EndpointFromContext extracts kubernetes endpoint info from current context
func EndpointFromContext(metadata store.Metadata) *EndpointMeta {
ep, ok := metadata.Endpoints[KubernetesEndpoint]

@ -0,0 +1,29 @@
package store
import (
"errors"
"io"
)
// LimitedReader is a fork of io.LimitedReader to override Read.
type LimitedReader struct {
R io.Reader
N int64 // max bytes remaining
}
// Read is a fork of io.LimitedReader.Read that returns an error when limit exceeded.
func (l *LimitedReader) Read(p []byte) (n int, err error) {
if l.N < 0 {
return 0, errors.New("read exceeds the defined limit")
}
if l.N == 0 {
return 0, io.EOF
}
// have to cap N + 1 otherwise we won't hit limit err
if int64(len(p)) > l.N+1 {
p = p[0 : l.N+1]
}
n, err = l.R.Read(p)
l.N -= int64(n)
return n, err
}

@ -2,12 +2,16 @@ package store
import (
"archive/tar"
"archive/zip"
"bufio"
"bytes"
_ "crypto/sha256" // ensure ids can be computed
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"path"
"path/filepath"
"strings"
@ -259,12 +263,44 @@ func Export(name string, s Reader) io.ReadCloser {
return reader
}
const (
maxAllowedFileSizeToImport int64 = 10 << 20
zipType string = "application/zip"
)
func getImportContentType(r *bufio.Reader) (string, error) {
head, err := r.Peek(512)
if err != nil && err != io.EOF {
return "", err
}
return http.DetectContentType(head), nil
}
// Import imports an exported context into a store
func Import(name string, s Writer, reader io.Reader) error {
tr := tar.NewReader(reader)
// Buffered reader will not advance the buffer, needed to determine content type
r := bufio.NewReader(reader)
importContentType, err := getImportContentType(r)
if err != nil {
return err
}
switch importContentType {
case zipType:
return importZip(name, s, r)
default:
// Assume it's a TAR (TAR does not have a "magic number")
return importTar(name, s, r)
}
}
func importTar(name string, s Writer, reader io.Reader) error {
tr := tar.NewReader(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
tlsData := ContextTLSData{
Endpoints: map[string]EndpointTLSData{},
}
var importedMetaFile bool
for {
hdr, err := tr.Next()
if err == io.EOF {
@ -282,37 +318,119 @@ func Import(name string, s Writer, reader io.Reader) error {
if err != nil {
return err
}
var meta Metadata
if err := json.Unmarshal(data, &meta); err != nil {
meta, err := parseMetadata(data, name)
if err != nil {
return err
}
meta.Name = name
if err := s.CreateOrUpdate(meta); err != nil {
return err
}
importedMetaFile = true
} else if strings.HasPrefix(hdr.Name, "tls/") {
relative := strings.TrimPrefix(hdr.Name, "tls/")
parts := strings.SplitN(relative, "/", 2)
if len(parts) != 2 {
return errors.New("archive format is invalid")
}
endpointName := parts[0]
fileName := parts[1]
data, err := ioutil.ReadAll(tr)
if err != nil {
return err
}
if _, ok := tlsData.Endpoints[endpointName]; !ok {
tlsData.Endpoints[endpointName] = EndpointTLSData{
Files: map[string][]byte{},
}
if err := importEndpointTLS(&tlsData, hdr.Name, data); err != nil {
return err
}
tlsData.Endpoints[endpointName].Files[fileName] = data
}
}
if !importedMetaFile {
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
}
return s.ResetTLSMaterial(name, &tlsData)
}
func importZip(name string, s Writer, reader io.Reader) error {
body, err := ioutil.ReadAll(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
if err != nil {
return err
}
zr, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
if err != nil {
return err
}
tlsData := ContextTLSData{
Endpoints: map[string]EndpointTLSData{},
}
var importedMetaFile bool
for _, zf := range zr.File {
fi := zf.FileInfo()
if fi.IsDir() {
// skip this entry, only taking files into account
continue
}
if zf.Name == metaFile {
f, err := zf.Open()
if err != nil {
return err
}
data, err := ioutil.ReadAll(&LimitedReader{R: f, N: maxAllowedFileSizeToImport})
defer f.Close()
if err != nil {
return err
}
meta, err := parseMetadata(data, name)
if err != nil {
return err
}
if err := s.CreateOrUpdate(meta); err != nil {
return err
}
importedMetaFile = true
} else if strings.HasPrefix(zf.Name, "tls/") {
f, err := zf.Open()
if err != nil {
return err
}
data, err := ioutil.ReadAll(f)
defer f.Close()
if err != nil {
return err
}
err = importEndpointTLS(&tlsData, zf.Name, data)
if err != nil {
return err
}
}
}
if !importedMetaFile {
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
}
return s.ResetTLSMaterial(name, &tlsData)
}
func parseMetadata(data []byte, name string) (Metadata, error) {
var meta Metadata
if err := json.Unmarshal(data, &meta); err != nil {
return meta, err
}
meta.Name = name
return meta, nil
}
func importEndpointTLS(tlsData *ContextTLSData, path string, data []byte) error {
parts := strings.SplitN(strings.TrimPrefix(path, "tls/"), "/", 2)
if len(parts) != 2 {
// TLS endpoints require archived file directory with 2 layers
// i.e. tls/{endpointName}/{fileName}
return errors.New("archive format is invalid")
}
epName := parts[0]
fileName := parts[1]
if _, ok := tlsData.Endpoints[epName]; !ok {
tlsData.Endpoints[epName] = EndpointTLSData{
Files: map[string][]byte{},
}
}
tlsData.Endpoints[epName].Files[fileName] = data
return nil
}
type setContextName interface {
setContext(name string)
}

@ -30,6 +30,16 @@ func (c Config) SetEndpoint(name string, getter TypeGetter) {
c.endpointTypes[name] = getter
}
// ForeachEndpointType calls cb on every endpoint type registered with the Config
func (c Config) ForeachEndpointType(cb func(string, TypeGetter) error) error {
for n, ep := range c.endpointTypes {
if err := cb(n, ep); err != nil {
return err
}
}
return nil
}
// NewConfig creates a config object
func NewConfig(contextType TypeGetter, endpoints ...NamedTypeGetter) Config {
res := Config{

@ -100,7 +100,7 @@ github.com/containerd/ttrpc
github.com/containerd/typeurl
# github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew
# github.com/docker/cli v1.14.0-0.20190523191156-ab688a9a79a1
# github.com/docker/cli v0.0.0-20191010210043-06f34ba50786
github.com/docker/cli/cli/compose/loader
github.com/docker/cli/cli/compose/types
github.com/docker/cli/cli/config/types
@ -171,10 +171,10 @@ github.com/docker/docker/api/types/swarm
github.com/docker/docker/api/types/time
github.com/docker/docker/api/types/volume
github.com/docker/docker/errdefs
github.com/docker/docker/pkg/homedir
github.com/docker/docker/pkg/system
github.com/docker/docker/pkg/term
github.com/docker/docker/registry
github.com/docker/docker/pkg/homedir
github.com/docker/docker/api/types/blkiodev
github.com/docker/docker/api/types/strslice
github.com/docker/docker/api/types/swarm/runtime

Loading…
Cancel
Save