From b4a8a4a6f97c0289339d9a375b19641f2d1e7723 Mon Sep 17 00:00:00 2001 From: Silvin Lubecki Date: Thu, 23 May 2019 14:33:22 +0200 Subject: [PATCH] Bump docker/cli Bump docker/docker Fix last changes on context stores made on docker/cli (the main store interface has been split to multiple smaller interfaces). Signed-off-by: Silvin Lubecki --- Gopkg.lock | 27 +- internal/commands/cnab.go | 2 +- internal/commands/dockerdesktop.go | 13 +- .../Microsoft/hcsshim/osversion/osversion.go | 51 ++ .../hcsshim/osversion/windowsbuilds.go | 10 + vendor/github.com/docker/cli/AUTHORS | 9 +- .../docker/cli/cli-plugins/manager/manager.go | 1 + .../docker/cli/cli-plugins/plugin/plugin.go | 13 +- .../github.com/docker/cli/cli/command/cli.go | 10 +- .../docker/cli/cli/command/context.go | 2 +- .../cli/cli/command/defaultcontextstore.go | 68 +-- .../docker/cli/cli/command/service/opts.go | 2 +- .../docker/cli/cli/command/utils.go | 31 ++ .../docker/cli/cli/config/configfile/file.go | 2 + .../cli/connhelper/commandconn/commandconn.go | 2 + ...ommandconn_linux.go => pdeathsig_linux.go} | 4 +- ...ndconn_nolinux.go => pdeathsig_nolinux.go} | 0 .../connhelper/commandconn/session_unix.go | 13 + .../connhelper/commandconn/session_windows.go | 8 + .../docker/cli/cli/context/docker/load.go | 8 +- .../docker/cli/cli/context/kubernetes/load.go | 8 +- .../cli/cli/context/store/metadatastore.go | 18 +- .../docker/cli/cli/context/store/store.go | 94 ++-- .../docker/cli/cli/context/tlsdata.go | 6 +- vendor/github.com/docker/docker/AUTHORS | 17 +- vendor/github.com/docker/docker/api/common.go | 2 +- .../api/types/container/container_changes.go | 2 +- .../api/types/container/container_create.go | 2 +- .../api/types/container/container_top.go | 2 +- .../api/types/container/container_update.go | 2 +- .../api/types/container/container_wait.go | 2 +- .../docker/api/types/container/host_config.go | 31 +- .../docker/api/types/image/image_history.go | 2 +- .../docker/api/types/volume/volume_create.go | 2 +- .../docker/api/types/volume/volume_list.go | 2 +- .../github.com/docker/docker/client/client.go | 46 +- .../github.com/docker/docker/client/hijack.go | 2 +- .../docker/docker/client/options.go | 48 +- .../github.com/docker/docker/client/ping.go | 2 + .../docker/docker/client/request.go | 2 +- .../docker/docker/pkg/mount/mount.go | 4 +- .../docker/pkg/mount/sharedsubtree_linux.go | 24 +- .../docker/docker/pkg/system/init_windows.go | 5 +- .../flynn-archive/go-shlex/shlex.go | 457 ------------------ .../go-shlex => google/shlex}/COPYING | 0 vendor/github.com/google/shlex/shlex.go | 416 ++++++++++++++++ 46 files changed, 844 insertions(+), 630 deletions(-) create mode 100644 vendor/github.com/Microsoft/hcsshim/osversion/osversion.go create mode 100644 vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go rename vendor/github.com/docker/cli/cli/connhelper/commandconn/{commandconn_linux.go => pdeathsig_linux.go} (55%) rename vendor/github.com/docker/cli/cli/connhelper/commandconn/{commandconn_nolinux.go => pdeathsig_nolinux.go} (100%) create mode 100644 vendor/github.com/docker/cli/cli/connhelper/commandconn/session_unix.go create mode 100644 vendor/github.com/docker/cli/cli/connhelper/commandconn/session_windows.go delete mode 100644 vendor/github.com/flynn-archive/go-shlex/shlex.go rename vendor/github.com/{flynn-archive/go-shlex => google/shlex}/COPYING (100%) create mode 100644 vendor/github.com/google/shlex/shlex.go diff --git a/Gopkg.lock b/Gopkg.lock index c69910a4..a281fd7c 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -29,7 +29,7 @@ version = "v0.4.12" [[projects]] - digest = "1:a8e16b4caf3575365c9aa3380d9418f31dd0b810596faebfe3a15c37fabeee4a" + digest = "1:3b7289c340e1043e1b826ba201d4d9ed1eb3ec32a5e8600208ec030afa74f458" name = "github.com/Microsoft/hcsshim" packages = [ ".", @@ -47,6 +47,7 @@ "internal/schema2", "internal/timeout", "internal/wclayer", + "osversion", ] pruneopts = "NUT" revision = "f92b8fb9c92e17da496af5a69e3ee13fbe9916e1" @@ -209,7 +210,7 @@ [[projects]] branch = "19.03" - digest = "1:45401220d930972198a7880d87df89485e53ac44b2a5826d9c2fe57344f650a6" + digest = "1:2f437f78f32178b2951314dd82649fda98e8f114e4d2c42588dd40fc2184a434" name = "github.com/docker/cli" packages = [ "cli", @@ -264,7 +265,7 @@ "types", ] pruneopts = "UT" - revision = "2432af701a7973ea582196b4b9488831156f3458" + revision = "8aebc318062963ba861b65cc2a43425dfdd80fe7" [[projects]] branch = "master" @@ -323,7 +324,7 @@ [[projects]] branch = "master" - digest = "1:37c8169fc0ff166b4ca825154d709545282fffee5572a6a63e1fdfa709c3f0fe" + digest = "1:83ede099909456cf1f5d6de21e5108b1ea593d5d33859799bfa7d8e575281a3c" name = "github.com/docker/docker" packages = [ "api", @@ -365,7 +366,7 @@ "registry/resumable", ] pruneopts = "NUT" - revision = "df3b6383d1ee2f067afce98cefd7c300ddcb02d6" + revision = "8a208a10de6a13ba2d9f65b9955d3594d9b14615" [[projects]] digest = "1:8866486038791fe65ea1abf660041423954b1f3fb99ea6a0ad8424422e943458" @@ -435,14 +436,6 @@ pruneopts = "NUT" revision = "18e7e58ea1a5ec016625a636d0d52500eea123bc" -[[projects]] - branch = "master" - digest = "1:1ccd7321e62f680a988bba496f0f5a9c80410b8104d55b0f6b8ecf84ad328476" - name = "github.com/flynn-archive/go-shlex" - packages = ["."] - pruneopts = "NUT" - revision = "3f9db97f856818214da2e1057f8ad84803971cff" - [[projects]] digest = "1:c6f5a29fce208cb102ad1e356d3a3a361be54604549063943613058a377dd0d0" name = "github.com/gogo/googleapis" @@ -500,6 +493,14 @@ revision = "f140a6486e521aad38f5917de355cbf147cc0496" version = "v1.0.0" +[[projects]] + branch = "master" + digest = "1:c54b2df9eb45e238bca9d7f0e1a4acc90a2e6284e8d31c0df3ec72886ec53406" + name = "github.com/google/shlex" + packages = ["."] + pruneopts = "NUT" + revision = "c34317bd91bf98fab745d77b03933cf8769299fe" + [[projects]] digest = "1:06a7dadb7b760767341ffb6c8d377238d68a1226f2b21b5d497d2e3f6ecf6b4e" name = "github.com/googleapis/gnostic" diff --git a/internal/commands/cnab.go b/internal/commands/cnab.go index 91022b11..e4b2da00 100644 --- a/internal/commands/cnab.go +++ b/internal/commands/cnab.go @@ -296,7 +296,7 @@ func requiredBindMount(targetContextName string, targetOrchestrator string, s st // in case of docker desktop, we want to rewrite the context in cases where it targets the local swarm or Kubernetes s = &dockerDesktopAwareStore{Store: s} - ctxMeta, err := s.GetContextMetadata(targetContextName) + ctxMeta, err := s.GetMetadata(targetContextName) if err != nil { return bindMount{}, err } diff --git a/internal/commands/dockerdesktop.go b/internal/commands/dockerdesktop.go index c64d08bb..74d3ffd0 100644 --- a/internal/commands/dockerdesktop.go +++ b/internal/commands/dockerdesktop.go @@ -74,6 +74,7 @@ func (r *dockerDesktopKubernetesEndpointRewriter) rewrite(ep *kubernetes.Endpoin ep.Host = fmt.Sprintf("https://%s:6443", ip) } +// nolint:interfacer func makeLinuxkitIPProvider(contextName string, s store.Store) dockerDesktopLinuxKitIPProvider { return func() (string, error) { clientCfg, err := kubernetes.ConfigFromContext(contextName, s) @@ -104,7 +105,7 @@ func makeLinuxkitIPProvider(contextName string, s store.Store) dockerDesktopLinu } } -func rewriteContextIfDockerDesktop(meta *store.ContextMetadata, s store.Store) { +func rewriteContextIfDockerDesktop(meta *store.Metadata, s store.Store) { // errors are treated as "don't rewrite" rewriter := dockerDesktopDockerEndpointRewriter{ defaultHostProvider: defaultDockerDesktopHostProvider, @@ -131,8 +132,8 @@ type dockerDesktopAwareStore struct { store.Store } -func (s dockerDesktopAwareStore) ListContexts() ([]store.ContextMetadata, error) { - contexts, err := s.Store.ListContexts() +func (s dockerDesktopAwareStore) List() ([]store.Metadata, error) { + contexts, err := s.Store.List() if err != nil { return nil, err } @@ -143,10 +144,10 @@ func (s dockerDesktopAwareStore) ListContexts() ([]store.ContextMetadata, error) return contexts, nil } -func (s dockerDesktopAwareStore) GetContextMetadata(name string) (store.ContextMetadata, error) { - context, err := s.Store.GetContextMetadata(name) +func (s dockerDesktopAwareStore) GetMetadata(name string) (store.Metadata, error) { + context, err := s.Store.GetMetadata(name) if err != nil { - return store.ContextMetadata{}, err + return store.Metadata{}, err } rewriteContextIfDockerDesktop(&context, s.Store) return context, nil diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/osversion.go b/vendor/github.com/Microsoft/hcsshim/osversion/osversion.go new file mode 100644 index 00000000..916950c0 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/osversion/osversion.go @@ -0,0 +1,51 @@ +package osversion + +import ( + "fmt" + + "golang.org/x/sys/windows" +) + +// OSVersion is a wrapper for Windows version information +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx +type OSVersion struct { + Version uint32 + MajorVersion uint8 + MinorVersion uint8 + Build uint16 +} + +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx +type osVersionInfoEx struct { + OSVersionInfoSize uint32 + MajorVersion uint32 + MinorVersion uint32 + BuildNumber uint32 + PlatformID uint32 + CSDVersion [128]uint16 + ServicePackMajor uint16 + ServicePackMinor uint16 + SuiteMask uint16 + ProductType byte + Reserve byte +} + +// Get gets the operating system version on Windows. +// The calling application must be manifested to get the correct version information. +func Get() OSVersion { + var err error + osv := OSVersion{} + osv.Version, err = windows.GetVersion() + if err != nil { + // GetVersion never fails. + panic(err) + } + osv.MajorVersion = uint8(osv.Version & 0xFF) + osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) + osv.Build = uint16(osv.Version >> 16) + return osv +} + +func (osv OSVersion) ToString() string { + return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build) +} diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go new file mode 100644 index 00000000..2d9567f6 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go @@ -0,0 +1,10 @@ +package osversion + +const ( + + // RS2 was a client-only release in case you're asking why it's not in the list. + RS1 = 14393 + RS3 = 16299 + RS4 = 17134 + RS5 = 17763 +) diff --git a/vendor/github.com/docker/cli/AUTHORS b/vendor/github.com/docker/cli/AUTHORS index b1e1c964..04edcf79 100644 --- a/vendor/github.com/docker/cli/AUTHORS +++ b/vendor/github.com/docker/cli/AUTHORS @@ -58,6 +58,7 @@ Anton Polonskiy Antonio Murdaca Antonis Kalipetis Anusha Ragunathan +Ao Li Arash Deshmeh Arnaud Porterie Ashwini Oruganti @@ -158,6 +159,7 @@ David Cramer David Dooling David Gageot David Lechner +David Scott David Sheets David Williamson David Xia @@ -300,6 +302,7 @@ Jim Galasyn Jimmy Leger Jimmy Song jimmyxian +Jintao Zhang Joao Fernandes Joe Doliner Joe Gordon @@ -471,9 +474,11 @@ Mrunal Patel muicoder Muthukumar R Máximo Cuadros +Mårten Cassel Nace Oroz Nahum Shalman Nalin Dahyabhai +Nao YONASHIRO Nassim 'Nass' Eddequiouaq Natalie Parker Nate Brennand @@ -595,7 +600,7 @@ Spencer Brown squeegels <1674195+squeegels@users.noreply.github.com> Srini Brahmaroutu Stefan S. -Stefan Scherer +Stefan Scherer Stefan Weil Stephane Jeandeaux Stephen Day @@ -605,7 +610,9 @@ Steve Richards Steven Burgess Subhajit Ghosh Sun Jianbo +Sune Keller Sungwon Han +Sunny Gogoi Sven Dowideit Sylvain Baubeau Sébastien HOUZÉ diff --git a/vendor/github.com/docker/cli/cli-plugins/manager/manager.go b/vendor/github.com/docker/cli/cli-plugins/manager/manager.go index 78ff64bb..e7cd2de4 100644 --- a/vendor/github.com/docker/cli/cli-plugins/manager/manager.go +++ b/vendor/github.com/docker/cli/cli-plugins/manager/manager.go @@ -164,6 +164,7 @@ func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command return nil, err } if plugin.Err != nil { + // TODO: why are we not returning plugin.Err? return nil, errPluginNotFound(name) } cmd := exec.Command(plugin.Path, args...) diff --git a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go index 62ab11c9..7bd5f50c 100644 --- a/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go +++ b/vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go @@ -114,11 +114,14 @@ func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta fullname := manager.NamePrefix + name cmd := &cobra.Command{ - Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name), - Short: fullname + " is a Docker CLI plugin", - SilenceUsage: true, - SilenceErrors: true, - PersistentPreRunE: PersistentPreRunE, + Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name), + Short: fullname + " is a Docker CLI plugin", + SilenceUsage: true, + SilenceErrors: true, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + // We can't use this as the hook directly since it is initialised later (in runPlugin) + return PersistentPreRunE(cmd, args) + }, TraverseChildren: true, DisableFlagsInUseLine: true, } diff --git a/vendor/github.com/docker/cli/cli/command/cli.go b/vendor/github.com/docker/cli/cli/command/cli.go index 36ac41c5..0f369f90 100644 --- a/vendor/github.com/docker/cli/cli/command/cli.go +++ b/vendor/github.com/docker/cli/cli/command/cli.go @@ -290,8 +290,8 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF return client.NewClientWithOpts(clientOpts...) } -func resolveDockerEndpoint(s store.Store, contextName string) (docker.Endpoint, error) { - ctxMeta, err := s.GetContextMetadata(contextName) +func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) { + ctxMeta, err := s.GetMetadata(contextName) if err != nil { return docker.Endpoint{}, err } @@ -399,7 +399,7 @@ func (cli *DockerCli) CurrentContext() string { // StackOrchestrator resolves which stack orchestrator is in use func (cli *DockerCli) StackOrchestrator(flagValue string) (Orchestrator, error) { currentContext := cli.CurrentContext() - ctxRaw, err := cli.ContextStore().GetContextMetadata(currentContext) + ctxRaw, err := cli.ContextStore().GetMetadata(currentContext) if store.IsErrContextDoesNotExist(err) { // case where the currentContext has been removed (CLI behavior is to fallback to using DOCKER_HOST based resolution) return GetStackOrchestrator(flagValue, "", cli.ConfigFile().StackOrchestrator, cli.Err()) @@ -500,7 +500,7 @@ func UserAgent() string { // - if DOCKER_CONTEXT is set, use this value // - if Config file has a globally set "CurrentContext", use this value // - fallbacks to default HOST, uses TLS config from flags/env vars -func resolveContextName(opts *cliflags.CommonOptions, config *configfile.ConfigFile, contextstore store.Store) (string, error) { +func resolveContextName(opts *cliflags.CommonOptions, config *configfile.ConfigFile, contextstore store.Reader) (string, error) { if opts.Context != "" && len(opts.Hosts) > 0 { return "", errors.New("Conflicting options: either specify --host or --context, not both") } @@ -517,7 +517,7 @@ func resolveContextName(opts *cliflags.CommonOptions, config *configfile.ConfigF return ctxName, nil } if config != nil && config.CurrentContext != "" { - _, err := contextstore.GetContextMetadata(config.CurrentContext) + _, err := contextstore.GetMetadata(config.CurrentContext) if store.IsErrContextDoesNotExist(err) { return "", errors.Errorf("Current context %q is not found on the file system, please check your config file at %s", config.CurrentContext, config.Filename) } diff --git a/vendor/github.com/docker/cli/cli/command/context.go b/vendor/github.com/docker/cli/cli/command/context.go index 4f9e8e85..0de75dc9 100644 --- a/vendor/github.com/docker/cli/cli/command/context.go +++ b/vendor/github.com/docker/cli/cli/command/context.go @@ -13,7 +13,7 @@ type DockerContext struct { } // GetDockerContext extracts metadata from stored context metadata -func GetDockerContext(storeMetadata store.ContextMetadata) (DockerContext, error) { +func GetDockerContext(storeMetadata store.Metadata) (DockerContext, error) { if storeMetadata.Metadata == nil { // can happen if we save endpoints before assigning a context metadata // it is totally valid, and we should return a default initialized value diff --git a/vendor/github.com/docker/cli/cli/command/defaultcontextstore.go b/vendor/github.com/docker/cli/cli/command/defaultcontextstore.go index 10f8dc16..9da76df7 100644 --- a/vendor/github.com/docker/cli/cli/command/defaultcontextstore.go +++ b/vendor/github.com/docker/cli/cli/command/defaultcontextstore.go @@ -22,7 +22,7 @@ const ( // DefaultContext contains the default context data for all enpoints type DefaultContext struct { - Meta store.ContextMetadata + Meta store.Metadata TLS store.ContextTLSData } @@ -35,7 +35,7 @@ type ContextStoreWithDefault struct { Resolver DefaultContextResolver } -// resolveDefaultContext creates a ContextMetadata for the current CLI invocation parameters +// resolveDefaultContext creates a Metadata for the current CLI invocation parameters func resolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.ConfigFile, stderr io.Writer) (*DefaultContext, error) { stackOrchestrator, err := GetStackOrchestrator("", "", config.StackOrchestrator, stderr) if err != nil { @@ -44,7 +44,7 @@ func resolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.Conf contextTLSData := store.ContextTLSData{ Endpoints: make(map[string]store.EndpointTLSData), } - contextMetadata := store.ContextMetadata{ + contextMetadata := store.Metadata{ Endpoints: make(map[string]interface{}), Metadata: DockerContext{ Description: "", @@ -81,9 +81,9 @@ func resolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.Conf return &DefaultContext{Meta: contextMetadata, TLS: contextTLSData}, nil } -// ListContexts implements store.Store's ListContexts -func (s *ContextStoreWithDefault) ListContexts() ([]store.ContextMetadata, error) { - contextList, err := s.Store.ListContexts() +// List implements store.Store's List +func (s *ContextStoreWithDefault) List() ([]store.Metadata, error) { + contextList, err := s.Store.List() if err != nil { return nil, err } @@ -94,52 +94,52 @@ func (s *ContextStoreWithDefault) ListContexts() ([]store.ContextMetadata, error return append(contextList, defaultContext.Meta), nil } -// CreateOrUpdateContext is not allowed for the default context and fails -func (s *ContextStoreWithDefault) CreateOrUpdateContext(meta store.ContextMetadata) error { +// CreateOrUpdate is not allowed for the default context and fails +func (s *ContextStoreWithDefault) CreateOrUpdate(meta store.Metadata) error { if meta.Name == DefaultContextName { return errors.New("default context cannot be created nor updated") } - return s.Store.CreateOrUpdateContext(meta) + return s.Store.CreateOrUpdate(meta) } -// RemoveContext is not allowed for the default context and fails -func (s *ContextStoreWithDefault) RemoveContext(name string) error { +// Remove is not allowed for the default context and fails +func (s *ContextStoreWithDefault) Remove(name string) error { if name == DefaultContextName { return errors.New("default context cannot be removed") } - return s.Store.RemoveContext(name) + return s.Store.Remove(name) } -// GetContextMetadata implements store.Store's GetContextMetadata -func (s *ContextStoreWithDefault) GetContextMetadata(name string) (store.ContextMetadata, error) { +// GetMetadata implements store.Store's GetMetadata +func (s *ContextStoreWithDefault) GetMetadata(name string) (store.Metadata, error) { if name == DefaultContextName { defaultContext, err := s.Resolver() if err != nil { - return store.ContextMetadata{}, err + return store.Metadata{}, err } return defaultContext.Meta, nil } - return s.Store.GetContextMetadata(name) + return s.Store.GetMetadata(name) } -// ResetContextTLSMaterial is not implemented for default context and fails -func (s *ContextStoreWithDefault) ResetContextTLSMaterial(name string, data *store.ContextTLSData) error { +// ResetTLSMaterial is not implemented for default context and fails +func (s *ContextStoreWithDefault) ResetTLSMaterial(name string, data *store.ContextTLSData) error { if name == DefaultContextName { - return errors.New("The default context store does not support ResetContextTLSMaterial") + return errors.New("The default context store does not support ResetTLSMaterial") } - return s.Store.ResetContextTLSMaterial(name, data) + return s.Store.ResetTLSMaterial(name, data) } -// ResetContextEndpointTLSMaterial is not implemented for default context and fails -func (s *ContextStoreWithDefault) ResetContextEndpointTLSMaterial(contextName string, endpointName string, data *store.EndpointTLSData) error { +// ResetEndpointTLSMaterial is not implemented for default context and fails +func (s *ContextStoreWithDefault) ResetEndpointTLSMaterial(contextName string, endpointName string, data *store.EndpointTLSData) error { if contextName == DefaultContextName { - return errors.New("The default context store does not support ResetContextEndpointTLSMaterial") + return errors.New("The default context store does not support ResetEndpointTLSMaterial") } - return s.Store.ResetContextEndpointTLSMaterial(contextName, endpointName, data) + return s.Store.ResetEndpointTLSMaterial(contextName, endpointName, data) } -// ListContextTLSFiles implements store.Store's ListContextTLSFiles -func (s *ContextStoreWithDefault) ListContextTLSFiles(name string) (map[string]store.EndpointFiles, error) { +// ListTLSFiles implements store.Store's ListTLSFiles +func (s *ContextStoreWithDefault) ListTLSFiles(name string) (map[string]store.EndpointFiles, error) { if name == DefaultContextName { defaultContext, err := s.Resolver() if err != nil { @@ -155,11 +155,11 @@ func (s *ContextStoreWithDefault) ListContextTLSFiles(name string) (map[string]s } return tlsfiles, nil } - return s.Store.ListContextTLSFiles(name) + return s.Store.ListTLSFiles(name) } -// GetContextTLSData implements store.Store's GetContextTLSData -func (s *ContextStoreWithDefault) GetContextTLSData(contextName, endpointName, fileName string) ([]byte, error) { +// GetTLSData implements store.Store's GetTLSData +func (s *ContextStoreWithDefault) GetTLSData(contextName, endpointName, fileName string) ([]byte, error) { if contextName == DefaultContextName { defaultContext, err := s.Resolver() if err != nil { @@ -171,7 +171,7 @@ func (s *ContextStoreWithDefault) GetContextTLSData(contextName, endpointName, f return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil } - return s.Store.GetContextTLSData(contextName, endpointName, fileName) + return s.Store.GetTLSData(contextName, endpointName, fileName) } type noDefaultTLSDataError struct { @@ -189,10 +189,10 @@ func (e *noDefaultTLSDataError) NotFound() {} // IsTLSDataDoesNotExist satisfies github.com/docker/cli/cli/context/store.tlsDataDoesNotExist func (e *noDefaultTLSDataError) IsTLSDataDoesNotExist() {} -// GetContextStorageInfo implements store.Store's GetContextStorageInfo -func (s *ContextStoreWithDefault) GetContextStorageInfo(contextName string) store.ContextStorageInfo { +// GetStorageInfo implements store.Store's GetStorageInfo +func (s *ContextStoreWithDefault) GetStorageInfo(contextName string) store.StorageInfo { if contextName == DefaultContextName { - return store.ContextStorageInfo{MetadataPath: "", TLSPath: ""} + return store.StorageInfo{MetadataPath: "", TLSPath: ""} } - return s.Store.GetContextStorageInfo(contextName) + return s.Store.GetStorageInfo(contextName) } diff --git a/vendor/github.com/docker/cli/cli/command/service/opts.go b/vendor/github.com/docker/cli/cli/command/service/opts.go index d7668733..e0beeba0 100644 --- a/vendor/github.com/docker/cli/cli/command/service/opts.go +++ b/vendor/github.com/docker/cli/cli/command/service/opts.go @@ -16,8 +16,8 @@ import ( "github.com/docker/docker/client" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/api/defaults" - shlex "github.com/flynn-archive/go-shlex" gogotypes "github.com/gogo/protobuf/types" + "github.com/google/shlex" "github.com/pkg/errors" "github.com/spf13/pflag" ) diff --git a/vendor/github.com/docker/cli/cli/command/utils.go b/vendor/github.com/docker/cli/cli/command/utils.go index 0356fa4c..21e702eb 100644 --- a/vendor/github.com/docker/cli/cli/command/utils.go +++ b/vendor/github.com/docker/cli/cli/command/utils.go @@ -161,3 +161,34 @@ func ValidateOutputPathFileMode(fileMode os.FileMode) error { } return nil } + +func stringSliceIndex(s, subs []string) int { + j := 0 + if len(subs) > 0 { + for i, x := range s { + if j < len(subs) && subs[j] == x { + j++ + } else { + j = 0 + } + if len(subs) == j { + return i + 1 - j + } + } + } + return -1 +} + +// StringSliceReplaceAt replaces the sub-slice old, with the sub-slice new, in the string +// slice s, returning a new slice and a boolean indicating if the replacement happened. +// requireIdx is the index at which old needs to be found at (or -1 to disregard that). +func StringSliceReplaceAt(s, old, new []string, requireIndex int) ([]string, bool) { + idx := stringSliceIndex(s, old) + if (requireIndex != -1 && requireIndex != idx) || idx == -1 { + return s, false + } + out := append([]string{}, s[:idx]...) + out = append(out, new...) + out = append(out, s[idx+len(old):]...) + return out, true +} diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index c8d60116..67ae655b 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -50,6 +50,7 @@ type ConfigFile struct { CurrentContext string `json:"currentContext,omitempty"` CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"` Plugins map[string]map[string]string `json:"plugins,omitempty"` + Aliases map[string]string `json:"aliases,omitempty"` } // ProxyConfig contains proxy configuration settings @@ -72,6 +73,7 @@ func New(fn string) *ConfigFile { HTTPHeaders: make(map[string]string), Filename: fn, Plugins: make(map[string]map[string]string), + Aliases: make(map[string]string), } } diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go index 7e03741f..4c5783fb 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go @@ -41,7 +41,9 @@ func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { // we assume that args never contains sensitive information logrus.Debugf("commandconn: starting %s with %v", cmd, args) c.cmd.Env = os.Environ() + c.cmd.SysProcAttr = &syscall.SysProcAttr{} setPdeathsig(c.cmd) + createSession(c.cmd) c.stdin, err = c.cmd.StdinPipe() if err != nil { return nil, err diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn_linux.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/pdeathsig_linux.go similarity index 55% rename from vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn_linux.go rename to vendor/github.com/docker/cli/cli/connhelper/commandconn/pdeathsig_linux.go index 7d8b122e..1cdd788c 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn_linux.go +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/pdeathsig_linux.go @@ -6,7 +6,5 @@ import ( ) func setPdeathsig(cmd *exec.Cmd) { - cmd.SysProcAttr = &syscall.SysProcAttr{ - Pdeathsig: syscall.SIGKILL, - } + cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL } diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn_nolinux.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/pdeathsig_nolinux.go similarity index 100% rename from vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn_nolinux.go rename to vendor/github.com/docker/cli/cli/connhelper/commandconn/pdeathsig_nolinux.go diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_unix.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_unix.go new file mode 100644 index 00000000..6448500d --- /dev/null +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_unix.go @@ -0,0 +1,13 @@ +// +build !windows + +package commandconn + +import ( + "os/exec" +) + +func createSession(cmd *exec.Cmd) { + // for supporting ssh connection helper with ProxyCommand + // https://github.com/docker/cli/issues/1707 + cmd.SysProcAttr.Setsid = true +} diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_windows.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_windows.go new file mode 100644 index 00000000..b9260745 --- /dev/null +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/session_windows.go @@ -0,0 +1,8 @@ +package commandconn + +import ( + "os/exec" +) + +func createSession(cmd *exec.Cmd) { +} diff --git a/vendor/github.com/docker/cli/cli/context/docker/load.go b/vendor/github.com/docker/cli/cli/context/docker/load.go index 5661fa91..126fa2f2 100644 --- a/vendor/github.com/docker/cli/cli/context/docker/load.go +++ b/vendor/github.com/docker/cli/cli/context/docker/load.go @@ -31,7 +31,7 @@ type Endpoint struct { } // WithTLSData loads TLS materials for the endpoint -func WithTLSData(s store.Store, contextName string, m EndpointMeta) (Endpoint, error) { +func WithTLSData(s store.Reader, contextName string, m EndpointMeta) (Endpoint, error) { tlsData, err := context.LoadTLSData(s, contextName, DockerEndpoint) if err != nil { return Endpoint{}, err @@ -91,8 +91,8 @@ func (c *Endpoint) tlsConfig() (*tls.Config, error) { } // ClientOpts returns a slice of Client options to configure an API client with this endpoint -func (c *Endpoint) ClientOpts() ([]func(*client.Client) error, error) { - var result []func(*client.Client) error +func (c *Endpoint) ClientOpts() ([]client.Opt, error) { + var result []client.Opt if c.Host != "" { helper, err := connhelper.GetConnectionHelper(c.Host) if err != nil { @@ -153,7 +153,7 @@ func withHTTPClient(tlsConfig *tls.Config) func(*client.Client) error { } // EndpointFromContext parses a context docker endpoint metadata into a typed EndpointMeta structure -func EndpointFromContext(metadata store.ContextMetadata) (EndpointMeta, error) { +func EndpointFromContext(metadata store.Metadata) (EndpointMeta, error) { ep, ok := metadata.Endpoints[DockerEndpoint] if !ok { return EndpointMeta{}, errors.New("cannot find docker endpoint in context") diff --git a/vendor/github.com/docker/cli/cli/context/kubernetes/load.go b/vendor/github.com/docker/cli/cli/context/kubernetes/load.go index 803fd8c8..97dded9b 100644 --- a/vendor/github.com/docker/cli/cli/context/kubernetes/load.go +++ b/vendor/github.com/docker/cli/cli/context/kubernetes/load.go @@ -25,7 +25,7 @@ type Endpoint struct { } // WithTLSData loads TLS materials for the endpoint -func (c *EndpointMeta) WithTLSData(s store.Store, contextName string) (Endpoint, error) { +func (c *EndpointMeta) WithTLSData(s store.Reader, contextName string) (Endpoint, error) { tlsData, err := context.LoadTLSData(s, contextName, KubernetesEndpoint) if err != nil { return Endpoint{}, err @@ -62,7 +62,7 @@ func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig { } // EndpointFromContext extracts kubernetes endpoint info from current context -func EndpointFromContext(metadata store.ContextMetadata) *EndpointMeta { +func EndpointFromContext(metadata store.Metadata) *EndpointMeta { ep, ok := metadata.Endpoints[KubernetesEndpoint] if !ok { return nil @@ -77,8 +77,8 @@ func EndpointFromContext(metadata store.ContextMetadata) *EndpointMeta { // ConfigFromContext resolves a kubernetes client config for the specified context. // If kubeconfigOverride is specified, use this config file instead of the context defaults.ConfigFromContext // if command.ContextDockerHost is specified as the context name, fallsback to the default user's kubeconfig file -func ConfigFromContext(name string, s store.Store) (clientcmd.ClientConfig, error) { - ctxMeta, err := s.GetContextMetadata(name) +func ConfigFromContext(name string, s store.Reader) (clientcmd.ClientConfig, error) { + ctxMeta, err := s.GetMetadata(name) if err != nil { return nil, err } diff --git a/vendor/github.com/docker/cli/cli/context/store/metadatastore.go b/vendor/github.com/docker/cli/cli/context/store/metadatastore.go index 47aacdc5..df087164 100644 --- a/vendor/github.com/docker/cli/cli/context/store/metadatastore.go +++ b/vendor/github.com/docker/cli/cli/context/store/metadatastore.go @@ -26,7 +26,7 @@ func (s *metadataStore) contextDir(id contextdir) string { return filepath.Join(s.root, string(id)) } -func (s *metadataStore) createOrUpdate(meta ContextMetadata) error { +func (s *metadataStore) createOrUpdate(meta Metadata) error { contextDir := s.contextDir(contextdirOf(meta.Name)) if err := os.MkdirAll(contextDir, 0755); err != nil { return err @@ -56,26 +56,26 @@ func parseTypedOrMap(payload []byte, getter TypeGetter) (interface{}, error) { return reflect.ValueOf(typed).Elem().Interface(), nil } -func (s *metadataStore) get(id contextdir) (ContextMetadata, error) { +func (s *metadataStore) get(id contextdir) (Metadata, error) { contextDir := s.contextDir(id) bytes, err := ioutil.ReadFile(filepath.Join(contextDir, metaFile)) if err != nil { - return ContextMetadata{}, convertContextDoesNotExist(err) + return Metadata{}, convertContextDoesNotExist(err) } var untyped untypedContextMetadata - r := ContextMetadata{ + r := Metadata{ Endpoints: make(map[string]interface{}), } if err := json.Unmarshal(bytes, &untyped); err != nil { - return ContextMetadata{}, err + return Metadata{}, err } r.Name = untyped.Name if r.Metadata, err = parseTypedOrMap(untyped.Metadata, s.config.contextType); err != nil { - return ContextMetadata{}, err + return Metadata{}, err } for k, v := range untyped.Endpoints { if r.Endpoints[k], err = parseTypedOrMap(v, s.config.endpointTypes[k]); err != nil { - return ContextMetadata{}, err + return Metadata{}, err } } return r, err @@ -86,7 +86,7 @@ func (s *metadataStore) remove(id contextdir) error { return os.RemoveAll(contextDir) } -func (s *metadataStore) list() ([]ContextMetadata, error) { +func (s *metadataStore) list() ([]Metadata, error) { ctxDirs, err := listRecursivelyMetadataDirs(s.root) if err != nil { if os.IsNotExist(err) { @@ -94,7 +94,7 @@ func (s *metadataStore) list() ([]ContextMetadata, error) { } return nil, err } - var res []ContextMetadata + var res []Metadata for _, dir := range ctxDirs { c, err := s.get(contextdir(dir)) if err != nil { diff --git a/vendor/github.com/docker/cli/cli/context/store/store.go b/vendor/github.com/docker/cli/cli/context/store/store.go index f3561b3c..9e332e7c 100644 --- a/vendor/github.com/docker/cli/cli/context/store/store.go +++ b/vendor/github.com/docker/cli/cli/context/store/store.go @@ -18,26 +18,58 @@ import ( // Store provides a context store for easily remembering endpoints configuration type Store interface { - ListContexts() ([]ContextMetadata, error) - CreateOrUpdateContext(meta ContextMetadata) error - RemoveContext(name string) error - GetContextMetadata(name string) (ContextMetadata, error) - ResetContextTLSMaterial(name string, data *ContextTLSData) error - ResetContextEndpointTLSMaterial(contextName string, endpointName string, data *EndpointTLSData) error - ListContextTLSFiles(name string) (map[string]EndpointFiles, error) - GetContextTLSData(contextName, endpointName, fileName string) ([]byte, error) - GetContextStorageInfo(contextName string) ContextStorageInfo + Reader + Lister + Writer + StorageInfoProvider } -// ContextMetadata contains metadata about a context and its endpoints -type ContextMetadata struct { +// Reader provides read-only (without list) access to context data +type Reader interface { + GetMetadata(name string) (Metadata, error) + ListTLSFiles(name string) (map[string]EndpointFiles, error) + GetTLSData(contextName, endpointName, fileName string) ([]byte, error) +} + +// Lister provides listing of contexts +type Lister interface { + List() ([]Metadata, error) +} + +// ReaderLister combines Reader and Lister interfaces +type ReaderLister interface { + Reader + Lister +} + +// StorageInfoProvider provides more information about storage details of contexts +type StorageInfoProvider interface { + GetStorageInfo(contextName string) StorageInfo +} + +// Writer provides write access to context data +type Writer interface { + CreateOrUpdate(meta Metadata) error + Remove(name string) error + ResetTLSMaterial(name string, data *ContextTLSData) error + ResetEndpointTLSMaterial(contextName string, endpointName string, data *EndpointTLSData) error +} + +// ReaderWriter combines Reader and Writer interfaces +type ReaderWriter interface { + Reader + Writer +} + +// Metadata contains metadata about a context and its endpoints +type Metadata struct { Name string `json:",omitempty"` Metadata interface{} `json:",omitempty"` Endpoints map[string]interface{} `json:",omitempty"` } -// ContextStorageInfo contains data about where a given context is stored -type ContextStorageInfo struct { +// StorageInfo contains data about where a given context is stored +type StorageInfo struct { MetadataPath string TLSPath string } @@ -74,15 +106,15 @@ type store struct { tls *tlsStore } -func (s *store) ListContexts() ([]ContextMetadata, error) { +func (s *store) List() ([]Metadata, error) { return s.meta.list() } -func (s *store) CreateOrUpdateContext(meta ContextMetadata) error { +func (s *store) CreateOrUpdate(meta Metadata) error { return s.meta.createOrUpdate(meta) } -func (s *store) RemoveContext(name string) error { +func (s *store) Remove(name string) error { id := contextdirOf(name) if err := s.meta.remove(id); err != nil { return patchErrContextName(err, name) @@ -90,13 +122,13 @@ func (s *store) RemoveContext(name string) error { return patchErrContextName(s.tls.removeAllContextData(id), name) } -func (s *store) GetContextMetadata(name string) (ContextMetadata, error) { +func (s *store) GetMetadata(name string) (Metadata, error) { res, err := s.meta.get(contextdirOf(name)) patchErrContextName(err, name) return res, err } -func (s *store) ResetContextTLSMaterial(name string, data *ContextTLSData) error { +func (s *store) ResetTLSMaterial(name string, data *ContextTLSData) error { id := contextdirOf(name) if err := s.tls.removeAllContextData(id); err != nil { return patchErrContextName(err, name) @@ -114,7 +146,7 @@ func (s *store) ResetContextTLSMaterial(name string, data *ContextTLSData) error return nil } -func (s *store) ResetContextEndpointTLSMaterial(contextName string, endpointName string, data *EndpointTLSData) error { +func (s *store) ResetEndpointTLSMaterial(contextName string, endpointName string, data *EndpointTLSData) error { id := contextdirOf(contextName) if err := s.tls.removeAllEndpointData(id, endpointName); err != nil { return patchErrContextName(err, contextName) @@ -130,19 +162,19 @@ func (s *store) ResetContextEndpointTLSMaterial(contextName string, endpointName return nil } -func (s *store) ListContextTLSFiles(name string) (map[string]EndpointFiles, error) { +func (s *store) ListTLSFiles(name string) (map[string]EndpointFiles, error) { res, err := s.tls.listContextData(contextdirOf(name)) return res, patchErrContextName(err, name) } -func (s *store) GetContextTLSData(contextName, endpointName, fileName string) ([]byte, error) { +func (s *store) GetTLSData(contextName, endpointName, fileName string) ([]byte, error) { res, err := s.tls.getData(contextdirOf(contextName), endpointName, fileName) return res, patchErrContextName(err, contextName) } -func (s *store) GetContextStorageInfo(contextName string) ContextStorageInfo { +func (s *store) GetStorageInfo(contextName string) StorageInfo { dir := contextdirOf(contextName) - return ContextStorageInfo{ + return StorageInfo{ MetadataPath: s.meta.contextDir(dir), TLSPath: s.tls.contextDir(dir), } @@ -151,13 +183,13 @@ func (s *store) GetContextStorageInfo(contextName string) ContextStorageInfo { // Export exports an existing namespace into an opaque data stream // This stream is actually a tarball containing context metadata and TLS materials, but it does // not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import) -func Export(name string, s Store) io.ReadCloser { +func Export(name string, s Reader) io.ReadCloser { reader, writer := io.Pipe() go func() { tw := tar.NewWriter(writer) defer tw.Close() defer writer.Close() - meta, err := s.GetContextMetadata(name) + meta, err := s.GetMetadata(name) if err != nil { writer.CloseWithError(err) return @@ -179,7 +211,7 @@ func Export(name string, s Store) io.ReadCloser { writer.CloseWithError(err) return } - tlsFiles, err := s.ListContextTLSFiles(name) + tlsFiles, err := s.ListTLSFiles(name) if err != nil { writer.CloseWithError(err) return @@ -204,7 +236,7 @@ func Export(name string, s Store) io.ReadCloser { return } for _, fileName := range endpointFiles { - data, err := s.GetContextTLSData(name, endpointName, fileName) + data, err := s.GetTLSData(name, endpointName, fileName) if err != nil { writer.CloseWithError(err) return @@ -228,7 +260,7 @@ func Export(name string, s Store) io.ReadCloser { } // Import imports an exported context into a store -func Import(name string, s Store, reader io.Reader) error { +func Import(name string, s Writer, reader io.Reader) error { tr := tar.NewReader(reader) tlsData := ContextTLSData{ Endpoints: map[string]EndpointTLSData{}, @@ -250,12 +282,12 @@ func Import(name string, s Store, reader io.Reader) error { if err != nil { return err } - var meta ContextMetadata + var meta Metadata if err := json.Unmarshal(data, &meta); err != nil { return err } meta.Name = name - if err := s.CreateOrUpdateContext(meta); err != nil { + if err := s.CreateOrUpdate(meta); err != nil { return err } } else if strings.HasPrefix(hdr.Name, "tls/") { @@ -278,7 +310,7 @@ func Import(name string, s Store, reader io.Reader) error { tlsData.Endpoints[endpointName].Files[fileName] = data } } - return s.ResetContextTLSMaterial(name, &tlsData) + return s.ResetTLSMaterial(name, &tlsData) } type setContextName interface { diff --git a/vendor/github.com/docker/cli/cli/context/tlsdata.go b/vendor/github.com/docker/cli/cli/context/tlsdata.go index 6bd05fbb..124d98ba 100644 --- a/vendor/github.com/docker/cli/cli/context/tlsdata.go +++ b/vendor/github.com/docker/cli/cli/context/tlsdata.go @@ -42,15 +42,15 @@ func (data *TLSData) ToStoreTLSData() *store.EndpointTLSData { } // LoadTLSData loads TLS data from the store -func LoadTLSData(s store.Store, contextName, endpointName string) (*TLSData, error) { - tlsFiles, err := s.ListContextTLSFiles(contextName) +func LoadTLSData(s store.Reader, contextName, endpointName string) (*TLSData, error) { + tlsFiles, err := s.ListTLSFiles(contextName) if err != nil { return nil, errors.Wrapf(err, "failed to retrieve context tls files for context %q", contextName) } if epTLSFiles, ok := tlsFiles[endpointName]; ok { var tlsData TLSData for _, f := range epTLSFiles { - data, err := s.GetContextTLSData(contextName, endpointName, f) + data, err := s.GetTLSData(contextName, endpointName, f) if err != nil { return nil, errors.Wrapf(err, "failed to retrieve context tls data for file %q of context %q", f, contextName) } diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index 851e8101..d5b6cbbe 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -4,6 +4,7 @@ Aanand Prasad Aaron Davidson Aaron Feng +Aaron Hnatiw Aaron Huslage Aaron L. Xu Aaron Lehmann @@ -44,7 +45,7 @@ Ajey Charantimath ajneu Akash Gupta Akihiro Matsushima -Akihiro Suda +Akihiro Suda Akim Demaille Akira Koyasu Akshay Karle @@ -81,6 +82,7 @@ Alexandre Garnier Alexandre González Alexandre Jomin Alexandru Sfirlogea +Alexei Margasov Alexey Guskov Alexey Kotlyarov Alexey Shamrin @@ -153,6 +155,7 @@ Andy Wilson Anes Hasicic Anil Belur Anil Madhavapeddy +Ankit Jain Ankush Agarwal Anonmily Anran Qiao @@ -184,6 +187,7 @@ Asad Saeeduddin Asbjørn Enge averagehuman Avi Das +Avi Kivity Avi Miller Avi Vaid ayoshitake @@ -507,6 +511,7 @@ Dmitri Shuralyov Dmitry Demeshchuk Dmitry Gusev Dmitry Kononenko +Dmitry Sharshakov Dmitry Shyshkin Dmitry Smirnov Dmitry V. Krivenok @@ -656,6 +661,7 @@ Frederik Loeffert Frederik Nordahl Jul Sabroe Freek Kalter Frieder Bluemle +Fu JinLin Félix Baylac-Jacqué Félix Cantournet Gabe Rosenhouse @@ -688,6 +694,7 @@ Ghislain Bourgeois Giampaolo Mancini Gianluca Borello Gildas Cuisinier +Giovan Isa Musthofa gissehel Giuseppe Mazzotta Gleb Fotengauer-Malinovskiy @@ -898,6 +905,7 @@ Jimmy Cuadra Jimmy Puckett Jimmy Song Jinsoo Park +Jintao Zhang Jiri Appl Jiri Popelka Jiuyue Ma @@ -1079,6 +1087,7 @@ Kunal Kushwaha Kunal Tyagi Kyle Conroy Kyle Linden +Kyle Wuolle kyu Lachlan Coote Lai Jiangshan @@ -1146,6 +1155,7 @@ Luca-Bogdan Grigorescu Lucas Chan Lucas Chi Lucas Molas +Lucas Silvestre Luciano Mores Luis Martínez de Bartolomé Izquierdo Luiz Svoboda @@ -1255,6 +1265,7 @@ Maxim Kulkin Maxim Treskin Maxime Petazzoni Maximiliano Maccanti +Maxwell Meaglith Ma meejah Megan Kostick @@ -1519,6 +1530,7 @@ Quentin Brossard Quentin Perez Quentin Tayssier r0n22 +Radostin Stoyanov Rafal Jeczalik Rafe Colton Raghavendra K T @@ -1743,7 +1755,7 @@ Stefan Berger Stefan J. Wernli Stefan Praszalowicz Stefan S. -Stefan Scherer +Stefan Scherer Stefan Staudenmeyer Stefan Weil Stephan Spindler @@ -1976,6 +1988,7 @@ xamyzhao Xian Chaobo Xianglin Gao Xianlu Bird +Xiao YongBiao XiaoBing Jiang Xiaodong Zhang Xiaoxi He diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go index aa146cda..1565e2af 100644 --- a/vendor/github.com/docker/docker/api/common.go +++ b/vendor/github.com/docker/docker/api/common.go @@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api" // Common constants for daemon and client. const ( // DefaultVersion of Current REST API - DefaultVersion = "1.40" + DefaultVersion = "1.41" // NoBaseImageSpecifier is the symbol used by the FROM // command to specify that no base image is to be used. diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go index c909d6ca..222d1410 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_changes.go +++ b/vendor/github.com/docker/docker/api/types/container/container_changes.go @@ -1,4 +1,4 @@ -package container +package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/container/container_create.go b/vendor/github.com/docker/docker/api/types/container/container_create.go index 49efa0f2..1ec9c372 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_create.go +++ b/vendor/github.com/docker/docker/api/types/container/container_create.go @@ -1,4 +1,4 @@ -package container +package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/container/container_top.go b/vendor/github.com/docker/docker/api/types/container/container_top.go index ba41edcf..f8a60668 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_top.go +++ b/vendor/github.com/docker/docker/api/types/container/container_top.go @@ -1,4 +1,4 @@ -package container +package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/container/container_update.go b/vendor/github.com/docker/docker/api/types/container/container_update.go index 7630ae54..33addedf 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_update.go +++ b/vendor/github.com/docker/docker/api/types/container/container_update.go @@ -1,4 +1,4 @@ -package container +package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go index 9e3910a6..94b6a20e 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_wait.go +++ b/vendor/github.com/docker/docker/api/types/container/container_wait.go @@ -1,4 +1,4 @@ -package container +package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE 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 c7101077..654c8810 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 @@ -10,6 +10,29 @@ import ( "github.com/docker/go-units" ) +// CgroupnsMode represents the cgroup namespace mode of the container +type CgroupnsMode string + +// IsPrivate indicates whether the container uses its own private cgroup namespace +func (c CgroupnsMode) IsPrivate() bool { + return c == "private" +} + +// IsHost indicates whether the container shares the host's cgroup namespace +func (c CgroupnsMode) IsHost() bool { + return c == "host" +} + +// IsEmpty indicates whether the container cgroup namespace mode is unset +func (c CgroupnsMode) IsEmpty() bool { + return c == "" +} + +// Valid indicates whether the cgroup namespace mode is valid +func (c CgroupnsMode) Valid() bool { + return c.IsEmpty() || c.IsPrivate() || c.IsHost() +} + // Isolation represents the isolation technology of a container. The supported // values are platform specific type Isolation string @@ -338,7 +361,6 @@ type Resources struct { 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) MemoryReservation int64 // Memory soft limit (in bytes) @@ -382,9 +404,10 @@ type HostConfig struct { CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container 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 + CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for 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 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/image/image_history.go b/vendor/github.com/docker/docker/api/types/image/image_history.go index d6b354bc..b5a7a0c4 100644 --- a/vendor/github.com/docker/docker/api/types/image/image_history.go +++ b/vendor/github.com/docker/docker/api/types/image/image_history.go @@ -1,4 +1,4 @@ -package image +package image // import "github.com/docker/docker/api/types/image" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_create.go b/vendor/github.com/docker/docker/api/types/volume/volume_create.go index f12e4861..0c3772d3 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_create.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_create.go @@ -1,4 +1,4 @@ -package volume +package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_list.go b/vendor/github.com/docker/docker/api/types/volume/volume_list.go index 020198f7..45c3c1c9 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_list.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_list.go @@ -1,4 +1,4 @@ -package volume +package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- // DO NOT EDIT THIS FILE diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index 0b7b4d95..b63d4d6d 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -81,6 +81,15 @@ type Client struct { customHTTPHeaders map[string]string // manualOverride is set to true when the version was set by users. manualOverride bool + + // negotiateVersion indicates if the client should automatically negotiate + // the API version to use when making requests. API version negotiation is + // performed on the first request, after which negotiated is set to "true" + // so that subsequent requests do not re-negotiate. + negotiateVersion bool + + // negotiated indicates that API version negotiation took place + negotiated bool } // CheckRedirect specifies the policy for dealing with redirect responses: @@ -107,7 +116,7 @@ func CheckRedirect(req *http.Request, via []*http.Request) error { // 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. -func NewClientWithOpts(ops ...func(*Client) error) (*Client, error) { +func NewClientWithOpts(ops ...Opt) (*Client, error) { client, err := defaultHTTPClient(DefaultDockerHost) if err != nil { return nil, err @@ -169,8 +178,11 @@ func (cli *Client) Close() error { // getAPIPath returns the versioned request path to call the api. // It appends the query parameters to the path if they are not empty. -func (cli *Client) getAPIPath(p string, query url.Values) string { +func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string { var apiPath string + if cli.negotiateVersion && !cli.negotiated { + cli.NegotiateAPIVersion(ctx) + } if cli.version != "" { v := strings.TrimPrefix(cli.version, "v") apiPath = path.Join(cli.basePath, "/v"+v, p) @@ -186,19 +198,31 @@ func (cli *Client) ClientVersion() string { } // NegotiateAPIVersion queries the API and updates the version to match the -// API version. Any errors are silently ignored. +// API version. Any errors are silently ignored. If a manual override is in place, +// either through the `DOCKER_API_VERSION` environment variable, or if the client +// was initialized with a fixed version (`opts.WithVersion(xx)`), no negotiation +// will be performed. func (cli *Client) NegotiateAPIVersion(ctx context.Context) { - ping, _ := cli.Ping(ctx) - cli.NegotiateAPIVersionPing(ping) + if !cli.manualOverride { + ping, _ := cli.Ping(ctx) + cli.negotiateAPIVersionPing(ping) + } } // NegotiateAPIVersionPing updates the client version to match the Ping.APIVersion -// if the ping version is less than the default version. +// if the ping version is less than the default version. If a manual override is +// in place, either through the `DOCKER_API_VERSION` environment variable, or if +// the client was initialized with a fixed version (`opts.WithVersion(xx)`), no +// negotiation is performed. func (cli *Client) NegotiateAPIVersionPing(p types.Ping) { - if cli.manualOverride { - return + if !cli.manualOverride { + cli.negotiateAPIVersionPing(p) } +} +// negotiateAPIVersionPing queries the API and updates the version to match the +// API version. Any errors are silently ignored. +func (cli *Client) negotiateAPIVersionPing(p types.Ping) { // try the latest version before versioning headers existed if p.APIVersion == "" { p.APIVersion = "1.24" @@ -213,6 +237,12 @@ func (cli *Client) NegotiateAPIVersionPing(p types.Ping) { if versions.LessThan(p.APIVersion, cli.version) { cli.version = p.APIVersion } + + // Store the results, so that automatic API version negotiation (if enabled) + // won't be performed on the next request. + if cli.negotiateVersion { + cli.negotiated = true + } } // DaemonHost returns the host address used by the client diff --git a/vendor/github.com/docker/docker/client/hijack.go b/vendor/github.com/docker/docker/client/hijack.go index 86099827..e9c9a752 100644 --- a/vendor/github.com/docker/docker/client/hijack.go +++ b/vendor/github.com/docker/docker/client/hijack.go @@ -23,7 +23,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu return types.HijackedResponse{}, err } - apiPath := cli.getAPIPath(path, query) + apiPath := cli.getAPIPath(ctx, path, query) req, err := http.NewRequest("POST", apiPath, bodyEncoded) if err != nil { return types.HijackedResponse{}, err diff --git a/vendor/github.com/docker/docker/client/options.go b/vendor/github.com/docker/docker/client/options.go index 089be0d5..6f77f095 100644 --- a/vendor/github.com/docker/docker/client/options.go +++ b/vendor/github.com/docker/docker/client/options.go @@ -6,12 +6,16 @@ import ( "net/http" "os" "path/filepath" + "time" "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" "github.com/pkg/errors" ) +// Opt is a configuration option to initialize a client +type Opt func(*Client) error + // FromEnv configures the client with values from environment variables. // // Supported environment variables: @@ -55,13 +59,13 @@ func FromEnv(c *Client) error { // 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 { +func WithDialer(dialer *net.Dialer) Opt { 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 { +func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) Opt { return func(c *Client) error { if transport, ok := c.client.Transport.(*http.Transport); ok { transport.DialContext = dialContext @@ -72,7 +76,7 @@ func WithDialContext(dialContext func(ctx context.Context, network, addr string) } // WithHost overrides the client host with the specified one. -func WithHost(host string) func(*Client) error { +func WithHost(host string) Opt { return func(c *Client) error { hostURL, err := ParseHostURL(host) if err != nil { @@ -90,7 +94,7 @@ func WithHost(host string) func(*Client) error { } // WithHTTPClient overrides the client http client with the specified one -func WithHTTPClient(client *http.Client) func(*Client) error { +func WithHTTPClient(client *http.Client) Opt { return func(c *Client) error { if client != nil { c.client = client @@ -99,8 +103,16 @@ func WithHTTPClient(client *http.Client) func(*Client) error { } } +// WithTimeout configures the time limit for requests made by the HTTP client +func WithTimeout(timeout time.Duration) Opt { + return func(c *Client) error { + c.client.Timeout = timeout + return nil + } +} + // WithHTTPHeaders overrides the client default http headers -func WithHTTPHeaders(headers map[string]string) func(*Client) error { +func WithHTTPHeaders(headers map[string]string) Opt { return func(c *Client) error { c.customHTTPHeaders = headers return nil @@ -108,7 +120,7 @@ func WithHTTPHeaders(headers map[string]string) func(*Client) error { } // WithScheme overrides the client scheme with the specified one -func WithScheme(scheme string) func(*Client) error { +func WithScheme(scheme string) Opt { return func(c *Client) error { c.scheme = scheme return nil @@ -116,7 +128,7 @@ func WithScheme(scheme string) func(*Client) error { } // WithTLSClientConfig applies a tls config to the client transport. -func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error { +func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt { return func(c *Client) error { opts := tlsconfig.Options{ CAFile: cacertPath, @@ -136,11 +148,25 @@ func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) err } } -// WithVersion overrides the client version with the specified one -func WithVersion(version string) func(*Client) error { +// WithVersion overrides the client version with the specified one. If an empty +// version is specified, the value will be ignored to allow version negotiation. +func WithVersion(version string) Opt { return func(c *Client) error { - c.version = version - c.manualOverride = true + if version != "" { + c.version = version + c.manualOverride = true + } + return nil + } +} + +// WithAPIVersionNegotiation enables automatic API version negotiation for the client. +// With this option enabled, the client automatically negotiates the API version +// to use when making requests. API version negotiation is performed on the first +// request; subsequent requests will not re-negotiate. +func WithAPIVersionNegotiation() Opt { + return func(c *Client) error { + c.negotiateVersion = true return nil } } diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index 4553e0fb..90f39ec1 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -31,6 +31,8 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { // Server handled the request, so parse the response return parsePingResponse(cli, serverResp) } + } else if IsErrConnectionFailed(err) { + return ping, err } req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil) diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index 0afe26d5..3078335e 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -115,7 +115,7 @@ func (cli *Client) buildRequest(method, path string, body io.Reader, headers hea } func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers headers) (serverResponse, error) { - req, err := cli.buildRequest(method, cli.getAPIPath(path, query), body, headers) + req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers) if err != nil { return serverResponse{}, err } diff --git a/vendor/github.com/docker/docker/pkg/mount/mount.go b/vendor/github.com/docker/docker/pkg/mount/mount.go index 4afd63c4..be0631c6 100644 --- a/vendor/github.com/docker/docker/pkg/mount/mount.go +++ b/vendor/github.com/docker/docker/pkg/mount/mount.go @@ -102,13 +102,13 @@ func Mounted(mountpoint string) (bool, error) { // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See // flags.go for supported option flags. func Mount(device, target, mType, options string) error { - flag, _ := parseOptions(options) + flag, data := parseOptions(options) if flag&REMOUNT != REMOUNT { if mounted, err := Mounted(target); err != nil || mounted { return err } } - return ForceMount(device, target, mType, options) + return mount(device, target, mType, uintptr(flag), data) } // ForceMount will mount a filesystem according to the specified configuration, diff --git a/vendor/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go b/vendor/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go index 8a100f0b..db388287 100644 --- a/vendor/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go +++ b/vendor/github.com/docker/docker/pkg/mount/sharedsubtree_linux.go @@ -3,49 +3,49 @@ package mount // import "github.com/docker/docker/pkg/mount" // MakeShared ensures a mounted filesystem has the SHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "shared") + return ensureMountedAs(mountPoint, SHARED) } // MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. // See the supported options in flags.go for further reference. func MakeRShared(mountPoint string) error { - return ensureMountedAs(mountPoint, "rshared") + return ensureMountedAs(mountPoint, RSHARED) } // MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. // See the supported options in flags.go for further reference. func MakePrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "private") + return ensureMountedAs(mountPoint, PRIVATE) } // MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option // enabled. See the supported options in flags.go for further reference. func MakeRPrivate(mountPoint string) error { - return ensureMountedAs(mountPoint, "rprivate") + return ensureMountedAs(mountPoint, RPRIVATE) } // MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "slave") + return ensureMountedAs(mountPoint, SLAVE) } // MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. // See the supported options in flags.go for further reference. func MakeRSlave(mountPoint string) error { - return ensureMountedAs(mountPoint, "rslave") + return ensureMountedAs(mountPoint, RSLAVE) } // MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option // enabled. See the supported options in flags.go for further reference. func MakeUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "unbindable") + return ensureMountedAs(mountPoint, UNBINDABLE) } // MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount // option enabled. See the supported options in flags.go for further reference. func MakeRUnbindable(mountPoint string) error { - return ensureMountedAs(mountPoint, "runbindable") + return ensureMountedAs(mountPoint, RUNBINDABLE) } // MakeMount ensures that the file or directory given is a mount point, @@ -59,13 +59,13 @@ func MakeMount(mnt string) error { return nil } - return Mount(mnt, mnt, "none", "bind") + return mount(mnt, mnt, "none", uintptr(BIND), "") } -func ensureMountedAs(mountPoint, options string) error { - if err := MakeMount(mountPoint); err != nil { +func ensureMountedAs(mnt string, flags int) error { + if err := MakeMount(mnt); err != nil { return err } - return ForceMount("", mountPoint, "none", options) + return mount("", mnt, "none", uintptr(flags), "") } diff --git a/vendor/github.com/docker/docker/pkg/system/init_windows.go b/vendor/github.com/docker/docker/pkg/system/init_windows.go index 7f675012..f303aa90 100644 --- a/vendor/github.com/docker/docker/pkg/system/init_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/init_windows.go @@ -3,6 +3,7 @@ package system // import "github.com/docker/docker/pkg/system" import ( "os" + "github.com/Microsoft/hcsshim/osversion" "github.com/sirupsen/logrus" ) @@ -15,10 +16,10 @@ var ( containerdRuntimeSupported = false ) -// InitLCOW sets whether LCOW is supported or not +// InitLCOW sets whether LCOW is supported or not. Requires RS5+ func InitLCOW(experimental bool) { v := GetOSVersion() - if experimental && v.Build >= 16299 { + if experimental && v.Build >= osversion.RS5 { lcowSupported = true } } diff --git a/vendor/github.com/flynn-archive/go-shlex/shlex.go b/vendor/github.com/flynn-archive/go-shlex/shlex.go deleted file mode 100644 index 7aeace80..00000000 --- a/vendor/github.com/flynn-archive/go-shlex/shlex.go +++ /dev/null @@ -1,457 +0,0 @@ -/* -Copyright 2012 Google Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package shlex - -/* -Package shlex implements a simple lexer which splits input in to tokens using -shell-style rules for quoting and commenting. -*/ -import ( - "bufio" - "errors" - "fmt" - "io" - "strings" -) - -/* -A TokenType is a top-level token; a word, space, comment, unknown. -*/ -type TokenType int - -/* -A RuneTokenType is the type of a UTF-8 character; a character, quote, space, escape. -*/ -type RuneTokenType int - -type lexerState int - -type Token struct { - tokenType TokenType - value string -} - -/* -Two tokens are equal if both their types and values are equal. A nil token can -never equal another token. -*/ -func (a *Token) Equal(b *Token) bool { - if a == nil || b == nil { - return false - } - if a.tokenType != b.tokenType { - return false - } - return a.value == b.value -} - -const ( - RUNE_CHAR string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-,/@$*()+=><:;&^%~|!?[]{}" - RUNE_SPACE string = " \t\r\n" - RUNE_ESCAPING_QUOTE string = "\"" - RUNE_NONESCAPING_QUOTE string = "'" - RUNE_ESCAPE = "\\" - RUNE_COMMENT = "#" - - RUNETOKEN_UNKNOWN RuneTokenType = 0 - RUNETOKEN_CHAR RuneTokenType = 1 - RUNETOKEN_SPACE RuneTokenType = 2 - RUNETOKEN_ESCAPING_QUOTE RuneTokenType = 3 - RUNETOKEN_NONESCAPING_QUOTE RuneTokenType = 4 - RUNETOKEN_ESCAPE RuneTokenType = 5 - RUNETOKEN_COMMENT RuneTokenType = 6 - RUNETOKEN_EOF RuneTokenType = 7 - - TOKEN_UNKNOWN TokenType = 0 - TOKEN_WORD TokenType = 1 - TOKEN_SPACE TokenType = 2 - TOKEN_COMMENT TokenType = 3 - - STATE_START lexerState = 0 - STATE_INWORD lexerState = 1 - STATE_ESCAPING lexerState = 2 - STATE_ESCAPING_QUOTED lexerState = 3 - STATE_QUOTED_ESCAPING lexerState = 4 - STATE_QUOTED lexerState = 5 - STATE_COMMENT lexerState = 6 - - INITIAL_TOKEN_CAPACITY int = 100 -) - -/* -A type for classifying characters. This allows for different sorts of -classifiers - those accepting extended non-ascii chars, or strict posix -compatibility, for example. -*/ -type TokenClassifier struct { - typeMap map[int32]RuneTokenType -} - -func addRuneClass(typeMap *map[int32]RuneTokenType, runes string, tokenType RuneTokenType) { - for _, rune := range runes { - (*typeMap)[int32(rune)] = tokenType - } -} - -/* -Create a new classifier for basic ASCII characters. -*/ -func NewDefaultClassifier() *TokenClassifier { - typeMap := map[int32]RuneTokenType{} - addRuneClass(&typeMap, RUNE_CHAR, RUNETOKEN_CHAR) - addRuneClass(&typeMap, RUNE_SPACE, RUNETOKEN_SPACE) - addRuneClass(&typeMap, RUNE_ESCAPING_QUOTE, RUNETOKEN_ESCAPING_QUOTE) - addRuneClass(&typeMap, RUNE_NONESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE) - addRuneClass(&typeMap, RUNE_ESCAPE, RUNETOKEN_ESCAPE) - addRuneClass(&typeMap, RUNE_COMMENT, RUNETOKEN_COMMENT) - return &TokenClassifier{ - typeMap: typeMap} -} - -func (classifier *TokenClassifier) ClassifyRune(rune int32) RuneTokenType { - return classifier.typeMap[rune] -} - -/* -A type for turning an input stream in to a sequence of strings. Whitespace and -comments are skipped. -*/ -type Lexer struct { - tokenizer *Tokenizer -} - -/* -Create a new lexer. -*/ -func NewLexer(r io.Reader) (*Lexer, error) { - - tokenizer, err := NewTokenizer(r) - if err != nil { - return nil, err - } - lexer := &Lexer{tokenizer: tokenizer} - return lexer, nil -} - -/* -Return the next word, and an error value. If there are no more words, the error -will be io.EOF. -*/ -func (l *Lexer) NextWord() (string, error) { - var token *Token - var err error - for { - token, err = l.tokenizer.NextToken() - if err != nil { - return "", err - } - switch token.tokenType { - case TOKEN_WORD: - { - return token.value, nil - } - case TOKEN_COMMENT: - { - // skip comments - } - default: - { - panic(fmt.Sprintf("Unknown token type: %v", token.tokenType)) - } - } - } - return "", io.EOF -} - -/* -A type for turning an input stream in to a sequence of typed tokens. -*/ -type Tokenizer struct { - input *bufio.Reader - classifier *TokenClassifier -} - -/* -Create a new tokenizer. -*/ -func NewTokenizer(r io.Reader) (*Tokenizer, error) { - input := bufio.NewReader(r) - classifier := NewDefaultClassifier() - tokenizer := &Tokenizer{ - input: input, - classifier: classifier} - return tokenizer, nil -} - -/* -Scan the stream for the next token. - -This uses an internal state machine. It will panic if it encounters a character -which it does not know how to handle. -*/ -func (t *Tokenizer) scanStream() (*Token, error) { - state := STATE_START - var tokenType TokenType - value := make([]int32, 0, INITIAL_TOKEN_CAPACITY) - var ( - nextRune int32 - nextRuneType RuneTokenType - err error - ) -SCAN: - for { - nextRune, _, err = t.input.ReadRune() - nextRuneType = t.classifier.ClassifyRune(nextRune) - if err != nil { - if err == io.EOF { - nextRuneType = RUNETOKEN_EOF - err = nil - } else { - return nil, err - } - } - switch state { - case STATE_START: // no runes read yet - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - return nil, io.EOF - } - case RUNETOKEN_CHAR: - { - tokenType = TOKEN_WORD - value = append(value, nextRune) - state = STATE_INWORD - } - case RUNETOKEN_SPACE: - { - } - case RUNETOKEN_ESCAPING_QUOTE: - { - tokenType = TOKEN_WORD - state = STATE_QUOTED_ESCAPING - } - case RUNETOKEN_NONESCAPING_QUOTE: - { - tokenType = TOKEN_WORD - state = STATE_QUOTED - } - case RUNETOKEN_ESCAPE: - { - tokenType = TOKEN_WORD - state = STATE_ESCAPING - } - case RUNETOKEN_COMMENT: - { - tokenType = TOKEN_COMMENT - state = STATE_COMMENT - } - default: - { - return nil, errors.New(fmt.Sprintf("Unknown rune: %v", nextRune)) - } - } - } - case STATE_INWORD: // in a regular word - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_COMMENT: - { - value = append(value, nextRune) - } - case RUNETOKEN_SPACE: - { - t.input.UnreadRune() - break SCAN - } - case RUNETOKEN_ESCAPING_QUOTE: - { - state = STATE_QUOTED_ESCAPING - } - case RUNETOKEN_NONESCAPING_QUOTE: - { - state = STATE_QUOTED - } - case RUNETOKEN_ESCAPE: - { - state = STATE_ESCAPING - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - case STATE_ESCAPING: // the next rune after an escape character - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - err = errors.New("EOF found after escape character") - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT: - { - state = STATE_INWORD - value = append(value, nextRune) - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - case STATE_ESCAPING_QUOTED: // the next rune after an escape character, in double quotes - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - err = errors.New("EOF found after escape character") - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT: - { - state = STATE_QUOTED_ESCAPING - value = append(value, nextRune) - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - case STATE_QUOTED_ESCAPING: // in escaping double quotes - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - err = errors.New("EOF found when expecting closing quote.") - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_SPACE, RUNETOKEN_NONESCAPING_QUOTE, RUNETOKEN_COMMENT: - { - value = append(value, nextRune) - } - case RUNETOKEN_ESCAPING_QUOTE: - { - state = STATE_INWORD - } - case RUNETOKEN_ESCAPE: - { - state = STATE_ESCAPING_QUOTED - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - case STATE_QUOTED: // in non-escaping single quotes - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - err = errors.New("EOF found when expecting closing quote.") - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_SPACE, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT: - { - value = append(value, nextRune) - } - case RUNETOKEN_NONESCAPING_QUOTE: - { - state = STATE_INWORD - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - case STATE_COMMENT: - { - switch nextRuneType { - case RUNETOKEN_EOF: - { - break SCAN - } - case RUNETOKEN_CHAR, RUNETOKEN_UNKNOWN, RUNETOKEN_ESCAPING_QUOTE, RUNETOKEN_ESCAPE, RUNETOKEN_COMMENT, RUNETOKEN_NONESCAPING_QUOTE: - { - value = append(value, nextRune) - } - case RUNETOKEN_SPACE: - { - if nextRune == '\n' { - state = STATE_START - break SCAN - } else { - value = append(value, nextRune) - } - } - default: - { - return nil, errors.New(fmt.Sprintf("Uknown rune: %v", nextRune)) - } - } - } - default: - { - panic(fmt.Sprintf("Unexpected state: %v", state)) - } - } - } - token := &Token{ - tokenType: tokenType, - value: string(value)} - return token, err -} - -/* -Return the next token in the stream, and an error value. If there are no more -tokens available, the error value will be io.EOF. -*/ -func (t *Tokenizer) NextToken() (*Token, error) { - return t.scanStream() -} - -/* -Split a string in to a slice of strings, based upon shell-style rules for -quoting, escaping, and spaces. -*/ -func Split(s string) ([]string, error) { - l, err := NewLexer(strings.NewReader(s)) - if err != nil { - return nil, err - } - subStrings := []string{} - for { - word, err := l.NextWord() - if err != nil { - if err == io.EOF { - return subStrings, nil - } - return subStrings, err - } - subStrings = append(subStrings, word) - } - return subStrings, nil -} diff --git a/vendor/github.com/flynn-archive/go-shlex/COPYING b/vendor/github.com/google/shlex/COPYING similarity index 100% rename from vendor/github.com/flynn-archive/go-shlex/COPYING rename to vendor/github.com/google/shlex/COPYING diff --git a/vendor/github.com/google/shlex/shlex.go b/vendor/github.com/google/shlex/shlex.go new file mode 100644 index 00000000..d98308bc --- /dev/null +++ b/vendor/github.com/google/shlex/shlex.go @@ -0,0 +1,416 @@ +/* +Copyright 2012 Google Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package shlex implements a simple lexer which splits input in to tokens using +shell-style rules for quoting and commenting. + +The basic use case uses the default ASCII lexer to split a string into sub-strings: + + shlex.Split("one \"two three\" four") -> []string{"one", "two three", "four"} + +To process a stream of strings: + + l := NewLexer(os.Stdin) + for ; token, err := l.Next(); err != nil { + // process token + } + +To access the raw token stream (which includes tokens for comments): + + t := NewTokenizer(os.Stdin) + for ; token, err := t.Next(); err != nil { + // process token + } + +*/ +package shlex + +import ( + "bufio" + "fmt" + "io" + "strings" +) + +// TokenType is a top-level token classification: A word, space, comment, unknown. +type TokenType int + +// runeTokenClass is the type of a UTF-8 character classification: A quote, space, escape. +type runeTokenClass int + +// the internal state used by the lexer state machine +type lexerState int + +// Token is a (type, value) pair representing a lexographical token. +type Token struct { + tokenType TokenType + value string +} + +// Equal reports whether tokens a, and b, are equal. +// Two tokens are equal if both their types and values are equal. A nil token can +// never be equal to another token. +func (a *Token) Equal(b *Token) bool { + if a == nil || b == nil { + return false + } + if a.tokenType != b.tokenType { + return false + } + return a.value == b.value +} + +// Named classes of UTF-8 runes +const ( + spaceRunes = " \t\r\n" + escapingQuoteRunes = `"` + nonEscapingQuoteRunes = "'" + escapeRunes = `\` + commentRunes = "#" +) + +// Classes of rune token +const ( + unknownRuneClass runeTokenClass = iota + spaceRuneClass + escapingQuoteRuneClass + nonEscapingQuoteRuneClass + escapeRuneClass + commentRuneClass + eofRuneClass +) + +// Classes of lexographic token +const ( + UnknownToken TokenType = iota + WordToken + SpaceToken + CommentToken +) + +// Lexer state machine states +const ( + startState lexerState = iota // no runes have been seen + inWordState // processing regular runes in a word + escapingState // we have just consumed an escape rune; the next rune is literal + escapingQuotedState // we have just consumed an escape rune within a quoted string + quotingEscapingState // we are within a quoted string that supports escaping ("...") + quotingState // we are within a string that does not support escaping ('...') + commentState // we are within a comment (everything following an unquoted or unescaped # +) + +// tokenClassifier is used for classifying rune characters. +type tokenClassifier map[rune]runeTokenClass + +func (typeMap tokenClassifier) addRuneClass(runes string, tokenType runeTokenClass) { + for _, runeChar := range runes { + typeMap[runeChar] = tokenType + } +} + +// newDefaultClassifier creates a new classifier for ASCII characters. +func newDefaultClassifier() tokenClassifier { + t := tokenClassifier{} + t.addRuneClass(spaceRunes, spaceRuneClass) + t.addRuneClass(escapingQuoteRunes, escapingQuoteRuneClass) + t.addRuneClass(nonEscapingQuoteRunes, nonEscapingQuoteRuneClass) + t.addRuneClass(escapeRunes, escapeRuneClass) + t.addRuneClass(commentRunes, commentRuneClass) + return t +} + +// ClassifyRune classifiees a rune +func (t tokenClassifier) ClassifyRune(runeVal rune) runeTokenClass { + return t[runeVal] +} + +// Lexer turns an input stream into a sequence of tokens. Whitespace and comments are skipped. +type Lexer Tokenizer + +// NewLexer creates a new lexer from an input stream. +func NewLexer(r io.Reader) *Lexer { + + return (*Lexer)(NewTokenizer(r)) +} + +// Next returns the next word, or an error. If there are no more words, +// the error will be io.EOF. +func (l *Lexer) Next() (string, error) { + for { + token, err := (*Tokenizer)(l).Next() + if err != nil { + return "", err + } + switch token.tokenType { + case WordToken: + return token.value, nil + case CommentToken: + // skip comments + default: + return "", fmt.Errorf("Unknown token type: %v", token.tokenType) + } + } +} + +// Tokenizer turns an input stream into a sequence of typed tokens +type Tokenizer struct { + input bufio.Reader + classifier tokenClassifier +} + +// NewTokenizer creates a new tokenizer from an input stream. +func NewTokenizer(r io.Reader) *Tokenizer { + input := bufio.NewReader(r) + classifier := newDefaultClassifier() + return &Tokenizer{ + input: *input, + classifier: classifier} +} + +// scanStream scans the stream for the next token using the internal state machine. +// It will panic if it encounters a rune which it does not know how to handle. +func (t *Tokenizer) scanStream() (*Token, error) { + state := startState + var tokenType TokenType + var value []rune + var nextRune rune + var nextRuneType runeTokenClass + var err error + + for { + nextRune, _, err = t.input.ReadRune() + nextRuneType = t.classifier.ClassifyRune(nextRune) + + if err == io.EOF { + nextRuneType = eofRuneClass + err = nil + } else if err != nil { + return nil, err + } + + switch state { + case startState: // no runes read yet + { + switch nextRuneType { + case eofRuneClass: + { + return nil, io.EOF + } + case spaceRuneClass: + { + } + case escapingQuoteRuneClass: + { + tokenType = WordToken + state = quotingEscapingState + } + case nonEscapingQuoteRuneClass: + { + tokenType = WordToken + state = quotingState + } + case escapeRuneClass: + { + tokenType = WordToken + state = escapingState + } + case commentRuneClass: + { + tokenType = CommentToken + state = commentState + } + default: + { + tokenType = WordToken + value = append(value, nextRune) + state = inWordState + } + } + } + case inWordState: // in a regular word + { + switch nextRuneType { + case eofRuneClass: + { + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + case spaceRuneClass: + { + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + case escapingQuoteRuneClass: + { + state = quotingEscapingState + } + case nonEscapingQuoteRuneClass: + { + state = quotingState + } + case escapeRuneClass: + { + state = escapingState + } + default: + { + value = append(value, nextRune) + } + } + } + case escapingState: // the rune after an escape character + { + switch nextRuneType { + case eofRuneClass: + { + err = fmt.Errorf("EOF found after escape character") + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + default: + { + state = inWordState + value = append(value, nextRune) + } + } + } + case escapingQuotedState: // the next rune after an escape character, in double quotes + { + switch nextRuneType { + case eofRuneClass: + { + err = fmt.Errorf("EOF found after escape character") + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + default: + { + state = quotingEscapingState + value = append(value, nextRune) + } + } + } + case quotingEscapingState: // in escaping double quotes + { + switch nextRuneType { + case eofRuneClass: + { + err = fmt.Errorf("EOF found when expecting closing quote") + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + case escapingQuoteRuneClass: + { + state = inWordState + } + case escapeRuneClass: + { + state = escapingQuotedState + } + default: + { + value = append(value, nextRune) + } + } + } + case quotingState: // in non-escaping single quotes + { + switch nextRuneType { + case eofRuneClass: + { + err = fmt.Errorf("EOF found when expecting closing quote") + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + case nonEscapingQuoteRuneClass: + { + state = inWordState + } + default: + { + value = append(value, nextRune) + } + } + } + case commentState: // in a comment + { + switch nextRuneType { + case eofRuneClass: + { + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } + case spaceRuneClass: + { + if nextRune == '\n' { + state = startState + token := &Token{ + tokenType: tokenType, + value: string(value)} + return token, err + } else { + value = append(value, nextRune) + } + } + default: + { + value = append(value, nextRune) + } + } + } + default: + { + return nil, fmt.Errorf("Unexpected state: %v", state) + } + } + } +} + +// Next returns the next token in the stream. +func (t *Tokenizer) Next() (*Token, error) { + return t.scanStream() +} + +// Split partitions a string into a slice of strings. +func Split(s string) ([]string, error) { + l := NewLexer(strings.NewReader(s)) + subStrings := make([]string, 0) + for { + word, err := l.Next() + if err != nil { + if err == io.EOF { + return subStrings, nil + } + return subStrings, err + } + subStrings = append(subStrings, word) + } +}