From 9c70693e40f85d667a11d06656a1a718e7312d6a Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 07:04:51 -0800 Subject: [PATCH 1/6] Revert whitespace change in docker-env output --- cmd/minikube/cmd/env.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/cmd/minikube/cmd/env.go b/cmd/minikube/cmd/env.go index 546a6a5cc5..9d6324724c 100644 --- a/cmd/minikube/cmd/env.go +++ b/cmd/minikube/cmd/env.go @@ -129,27 +129,22 @@ type NoProxyGetter interface { type EnvNoProxyGetter struct{} func generateUsageHint(profile string, userShell string) string { - const usgPlz = "Please run command bellow to point your shell to minikube's docker-daemon :" + const usgPlz = "To point your shell to minikube's docker-daemon:" var usgCmd = fmt.Sprintf("minikube -p %s docker-env", profile) var usageHintMap = map[string]string{ - "bash": fmt.Sprintf(` -# %s + "bash": fmt.Sprintf(`# %s # eval $(%s) `, usgPlz, usgCmd), - "fish": fmt.Sprintf(` -# %s + "fish": fmt.Sprintf(`# %s # eval (%s) `, usgPlz, usgCmd), - "powershell": fmt.Sprintf(` -# %s + "powershell": fmt.Sprintf(`# %s # & %s | Invoke-Expression `, usgPlz, usgCmd), - "cmd": fmt.Sprintf(` -REM %s + "cmd": fmt.Sprintf(`REM %s REM @FOR /f "tokens=*" %%i IN ('%s') DO @%%i `, usgPlz, usgCmd), - "emacs": fmt.Sprintf(` -;; %s + "emacs": fmt.Sprintf(`;; %s ;; (with-temp-buffer (shell-command "%s" (current-buffer)) (eval-buffer)) `, usgPlz, usgCmd), } From 32bc0ff76aed38fbf35090c55e9cfd8d67ad0eec Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 15:32:00 -0800 Subject: [PATCH 2/6] Refactor docker-env for testability --- cmd/minikube/cmd/env.go | 354 ++++++++++---------- cmd/minikube/cmd/env_test.go | 470 +++++++++++---------------- go.mod | 1 + go.sum | 1 + pkg/minikube/cluster/cluster_test.go | 68 ---- pkg/minikube/cluster/docker_env.go | 67 ---- 6 files changed, 374 insertions(+), 587 deletions(-) delete mode 100644 pkg/minikube/cluster/docker_env.go diff --git a/cmd/minikube/cmd/env.go b/cmd/minikube/cmd/env.go index 9d6324724c..fe764cc84f 100644 --- a/cmd/minikube/cmd/env.go +++ b/cmd/minikube/cmd/env.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors All rights reserved. +Copyright 2020 The Kubernetes Authors 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. @@ -21,28 +21,35 @@ package cmd import ( "fmt" + "io" + "net" "os" + "strconv" "strings" "text/template" - "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/drivers" - "github.com/docker/machine/libmachine/host" - "github.com/docker/machine/libmachine/log" "github.com/docker/machine/libmachine/shell" "github.com/docker/machine/libmachine/state" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + "k8s.io/minikube/pkg/drivers/kic" + "k8s.io/minikube/pkg/drivers/kic/oci" "k8s.io/minikube/pkg/minikube/cluster" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/exit" + "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/machine" + "k8s.io/minikube/pkg/minikube/out" ) -var envTmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}", constants.DockerTLSVerifyEnv, constants.DockerHostEnv, constants.DockerCertPathEnv, constants.MinikubeActiveDockerdEnv) +var ( + forceShell string + envTmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}", constants.DockerTLSVerifyEnv, constants.DockerHostEnv, constants.DockerCertPathEnv, constants.MinikubeActiveDockerdEnv) +) const ( fishSetPfx = "set -gx " @@ -105,21 +112,9 @@ type ShellConfig struct { } var ( - noProxy bool - forceShell string - unset bool - defaultShellDetector ShellDetector defaultNoProxyGetter NoProxyGetter ) -// ShellDetector detects shell -type ShellDetector interface { - GetShell(string) (string, error) -} - -// LibmachineShellDetector detects shell, using libmachine -type LibmachineShellDetector struct{} - // NoProxyGetter gets the no_proxy variable type NoProxyGetter interface { GetNoProxyVar() (string, string) @@ -128,169 +123,134 @@ type NoProxyGetter interface { // EnvNoProxyGetter gets the no_proxy variable, using environment type EnvNoProxyGetter struct{} -func generateUsageHint(profile string, userShell string) string { - const usgPlz = "To point your shell to minikube's docker-daemon:" +func generateUsageHint(profile, sh string) string { + const usgPlz = "Please run command bellow to point your shell to minikube's docker-daemon :" var usgCmd = fmt.Sprintf("minikube -p %s docker-env", profile) var usageHintMap = map[string]string{ - "bash": fmt.Sprintf(`# %s + "bash": fmt.Sprintf(` +# %s # eval $(%s) `, usgPlz, usgCmd), - "fish": fmt.Sprintf(`# %s + "fish": fmt.Sprintf(` +# %s # eval (%s) `, usgPlz, usgCmd), - "powershell": fmt.Sprintf(`# %s + "powershell": fmt.Sprintf(` +# %s # & %s | Invoke-Expression `, usgPlz, usgCmd), - "cmd": fmt.Sprintf(`REM %s + "cmd": fmt.Sprintf(` +REM %s REM @FOR /f "tokens=*" %%i IN ('%s') DO @%%i `, usgPlz, usgCmd), - "emacs": fmt.Sprintf(`;; %s + "emacs": fmt.Sprintf(` +;; %s ;; (with-temp-buffer (shell-command "%s" (current-buffer)) (eval-buffer)) `, usgPlz, usgCmd), } - hint, ok := usageHintMap[userShell] + hint, ok := usageHintMap[sh] if !ok { return usageHintMap["bash"] } return hint } -func shellCfgSet(api libmachine.API) (*ShellConfig, error) { - - envMap, err := cluster.GetNodeDockerEnv(api) - if err != nil { - return nil, err - } - - userShell, err := defaultShellDetector.GetShell(forceShell) - if err != nil { - return nil, err - } - - shellCfg := &ShellConfig{ +// shellCfgSet generates context variables for "docker-env" +func shellCfgSet(ec EnvConfig, envMap map[string]string) *ShellConfig { + s := &ShellConfig{ DockerCertPath: envMap[constants.DockerCertPathEnv], DockerHost: envMap[constants.DockerHostEnv], DockerTLSVerify: envMap[constants.DockerTLSVerifyEnv], MinikubeDockerdProfile: envMap[constants.MinikubeActiveDockerdEnv], - UsageHint: generateUsageHint(viper.GetString(config.MachineProfile), userShell), + UsageHint: generateUsageHint(ec.profile, ec.shell), } - if noProxy { - host, err := api.Load(viper.GetString(config.MachineProfile)) - if err != nil { - return nil, errors.Wrap(err, "Error getting IP") - } - - ip, err := host.Driver.GetIP() - if err != nil { - return nil, errors.Wrap(err, "Error getting host IP") - } - + if ec.noProxy { noProxyVar, noProxyValue := defaultNoProxyGetter.GetNoProxyVar() // add the docker host to the no_proxy list idempotently switch { case noProxyValue == "": - noProxyValue = ip - case strings.Contains(noProxyValue, ip): + noProxyValue = ec.hostIP + case strings.Contains(noProxyValue, ec.hostIP): // ip already in no_proxy list, nothing to do default: - noProxyValue = fmt.Sprintf("%s,%s", noProxyValue, ip) + noProxyValue = fmt.Sprintf("%s,%s", noProxyValue, ec.hostIP) } - shellCfg.NoProxyVar = noProxyVar - shellCfg.NoProxyValue = noProxyValue + s.NoProxyVar = noProxyVar + s.NoProxyValue = noProxyValue } - switch userShell { + switch ec.shell { case "fish": - shellCfg.Prefix = fishSetPfx - shellCfg.Suffix = fishSetSfx - shellCfg.Delimiter = fishSetDelim + s.Prefix = fishSetPfx + s.Suffix = fishSetSfx + s.Delimiter = fishSetDelim case "powershell": - shellCfg.Prefix = psSetPfx - shellCfg.Suffix = psSetSfx - shellCfg.Delimiter = psSetDelim + s.Prefix = psSetPfx + s.Suffix = psSetSfx + s.Delimiter = psSetDelim case "cmd": - shellCfg.Prefix = cmdSetPfx - shellCfg.Suffix = cmdSetSfx - shellCfg.Delimiter = cmdSetDelim + s.Prefix = cmdSetPfx + s.Suffix = cmdSetSfx + s.Delimiter = cmdSetDelim case "emacs": - shellCfg.Prefix = emacsSetPfx - shellCfg.Suffix = emacsSetSfx - shellCfg.Delimiter = emacsSetDelim + s.Prefix = emacsSetPfx + s.Suffix = emacsSetSfx + s.Delimiter = emacsSetDelim case "none": - shellCfg.Prefix = nonePfx - shellCfg.Suffix = noneSfx - shellCfg.Delimiter = noneDelim - shellCfg.UsageHint = "" + s.Prefix = nonePfx + s.Suffix = noneSfx + s.Delimiter = noneDelim + s.UsageHint = "" default: - shellCfg.Prefix = bashSetPfx - shellCfg.Suffix = bashSetSfx - shellCfg.Delimiter = bashSetDelim + s.Prefix = bashSetPfx + s.Suffix = bashSetSfx + s.Delimiter = bashSetDelim } - - return shellCfg, nil + return s } -func shellCfgUnset() (*ShellConfig, error) { - - userShell, err := defaultShellDetector.GetShell(forceShell) - if err != nil { - return nil, err +// shellCfgUnset generates context variables for "docker-env -u" +func shellCfgUnset(ec EnvConfig) *ShellConfig { + s := &ShellConfig{ + UsageHint: generateUsageHint(ec.profile, ec.shell), } - shellCfg := &ShellConfig{ - UsageHint: generateUsageHint(viper.GetString(config.MachineProfile), userShell), + if ec.noProxy { + s.NoProxyVar, s.NoProxyValue = defaultNoProxyGetter.GetNoProxyVar() } - if noProxy { - shellCfg.NoProxyVar, shellCfg.NoProxyValue = defaultNoProxyGetter.GetNoProxyVar() - } - - switch userShell { + switch ec.shell { case "fish": - shellCfg.Prefix = fishUnsetPfx - shellCfg.Suffix = fishUnsetSfx - shellCfg.Delimiter = fishUnsetDelim + s.Prefix = fishUnsetPfx + s.Suffix = fishUnsetSfx + s.Delimiter = fishUnsetDelim case "powershell": - shellCfg.Prefix = psUnsetPfx - shellCfg.Suffix = psUnsetSfx - shellCfg.Delimiter = psUnsetDelim + s.Prefix = psUnsetPfx + s.Suffix = psUnsetSfx + s.Delimiter = psUnsetDelim case "cmd": - shellCfg.Prefix = cmdUnsetPfx - shellCfg.Suffix = cmdUnsetSfx - shellCfg.Delimiter = cmdUnsetDelim + s.Prefix = cmdUnsetPfx + s.Suffix = cmdUnsetSfx + s.Delimiter = cmdUnsetDelim case "emacs": - shellCfg.Prefix = emacsUnsetPfx - shellCfg.Suffix = emacsUnsetSfx - shellCfg.Delimiter = emacsUnsetDelim + s.Prefix = emacsUnsetPfx + s.Suffix = emacsUnsetSfx + s.Delimiter = emacsUnsetDelim case "none": - shellCfg.Prefix = nonePfx - shellCfg.Suffix = noneSfx - shellCfg.Delimiter = noneDelim - shellCfg.UsageHint = "" + s.Prefix = nonePfx + s.Suffix = noneSfx + s.Delimiter = noneDelim + s.UsageHint = "" default: - shellCfg.Prefix = bashUnsetPfx - shellCfg.Suffix = bashUnsetSfx - shellCfg.Delimiter = bashUnsetDelim + s.Prefix = bashUnsetPfx + s.Suffix = bashUnsetSfx + s.Delimiter = bashUnsetDelim } - - return shellCfg, nil -} - -func executeTemplateStdout(shellCfg *ShellConfig) error { - tmpl := template.Must(template.New("envConfig").Parse(envTmpl)) - return tmpl.Execute(os.Stdout, shellCfg) -} - -// GetShell detects the shell -func (LibmachineShellDetector) GetShell(userShell string) (string, error) { - if userShell != "" { - return userShell, nil - } - return shell.Detect() + return s } // GetNoProxyVar gets the no_proxy var @@ -307,30 +267,18 @@ func (EnvNoProxyGetter) GetNoProxyVar() (string, string) { return noProxyVar, noProxyValue } -// same as drivers.RunSSHCommandFromDriver, but allows errors -func runSSHCommandFromDriver(d drivers.Driver, command string) (string, error) { +// isDockerActive checks if Docker is active +func isDockerActive(d drivers.Driver) (bool, error) { client, err := drivers.GetSSHClientFromDriver(d) if err != nil { - return "", err + return false, err + } + output, err := client.Output("sudo systemctl is-active docker") + if err != nil { + return false, err } - - log.Debugf("About to run SSH command:\n%s", command) - output, err := client.Output(command) - log.Debugf("SSH cmd err, output: %v: %s", err, output) - return output, err -} - -// same as host.RunSSHCommand, but allows errors -func runSSHCommand(h *host.Host, command string) (string, error) { - return runSSHCommandFromDriver(h.Driver, command) -} - -// GetDockerActive checks if Docker is active -func GetDockerActive(host *host.Host) (bool, error) { - statusCmd := `sudo systemctl is-active docker` - status, err := runSSHCommand(host, statusCmd) // systemd returns error code on inactive - s := strings.TrimSpace(status) + s := strings.TrimSpace(output) return err == nil && s == "active", nil } @@ -345,7 +293,9 @@ var dockerEnvCmd = &cobra.Command{ exit.WithError("Error getting client", err) } defer api.Close() - cc, err := config.Load(viper.GetString(config.MachineProfile)) + + profile := viper.GetString(config.MachineProfile) + cc, err := config.Load(profile) if err != nil { exit.WithError("Error getting config", err) } @@ -356,45 +306,113 @@ var dockerEnvCmd = &cobra.Command{ if host.Driver.DriverName() == driver.None { exit.UsageT(`'none' driver does not support 'minikube docker-env' command`) } + hostSt, err := cluster.GetHostStatus(api, cc.Name) if err != nil { exit.WithError("Error getting host status", err) } if hostSt != state.Running.String() { - exit.WithCodeT(exit.Unavailable, `The docker host is currently not running`) + exit.WithCodeT(exit.Unavailable, `'{{.profile}}' is not running`, out.V{"profile": profile}) } - docker, err := GetDockerActive(host) + ok, err := isDockerActive(host.Driver) if err != nil { exit.WithError("Error getting service status", err) } - if !docker { - exit.WithCodeT(exit.Unavailable, `The docker service is currently not active`) + + if !ok { + exit.WithCodeT(exit.Unavailable, `The docker service within '{{.profile}}' is not active`, out.V{"profile": profile}) } - var shellCfg *ShellConfig - - if unset { - shellCfg, err = shellCfgUnset() - if err != nil { - exit.WithError("Error unsetting shell variables", err) - } - } else { - shellCfg, err = shellCfgSet(api) - if err != nil { - exit.WithError("Error setting shell variables", err) - } + hostIP, err := host.Driver.GetIP() + if err != nil { + exit.WithError("Error getting host IP", err) } - if err := executeTemplateStdout(shellCfg); err != nil { - exit.WithError("Error executing template", err) + ec := EnvConfig{ + profile: profile, + driver: host.DriverName, + hostIP: hostIP, + certsDir: localpath.MakeMiniPath("certs"), + noProxy: viper.GetBool("no-proxy"), + } + + sh := viper.GetString("shell") + fmt.Printf("user shell=%s\n", sh) + if sh == "" { + sh, err = shell.Detect() + if err != nil { + exit.WithError("Error detecting shell", err) + } + } + ec.shell = sh + fmt.Printf("shell=%s, ec: %+v\n", viper.GetString("shell"), ec) + + if viper.GetBool("unset") { + if err := generateUnsetScript(ec, os.Stdout); err != nil { + exit.WithError("Error generating unset output", err) + } + return + } + + if err := generateSetScript(ec, os.Stdout); err != nil { + exit.WithError("Error generating set output", err) } }, } -func init() { - defaultShellDetector = &LibmachineShellDetector{} - defaultNoProxyGetter = &EnvNoProxyGetter{} - dockerEnvCmd.Flags().BoolVar(&noProxy, "no-proxy", false, "Add machine IP to NO_PROXY environment variable") - dockerEnvCmd.Flags().StringVar(&forceShell, "shell", "", "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect") - dockerEnvCmd.Flags().BoolVarP(&unset, "unset", "u", false, "Unset variables instead of setting them") +// EnvConfig encapsulates all external inputs into shell generation +type EnvConfig struct { + profile string + shell string + driver string + hostIP string + certsDir string + noProxy bool +} + +// generateSetScript writes out a shell-compatible 'docker-env' script +func generateSetScript(ec EnvConfig, w io.Writer) error { + tmpl := template.Must(template.New("envConfig").Parse(envTmpl)) + envVars, err := dockerEnvVars(ec) + if err != nil { + return err + } + return tmpl.Execute(w, shellCfgSet(ec, envVars)) +} + +// generateSetScript writes out a shell-compatible 'docker-env unset' script +func generateUnsetScript(ec EnvConfig, w io.Writer) error { + tmpl := template.Must(template.New("envConfig").Parse(envTmpl)) + return tmpl.Execute(w, shellCfgUnset(ec)) +} + +// dockerURL returns a the docker endpoint URL for an ip/port pair. +func dockerURL(ip string, port int) string { + return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(port))) +} + +// dockerEnvVars gets the necessary docker env variables to allow the use of docker through minikube's vm +func dockerEnvVars(ec EnvConfig) (map[string]string, error) { + env := map[string]string{ + constants.DockerTLSVerifyEnv: "1", + constants.DockerHostEnv: dockerURL(ec.hostIP, constants.DockerDaemonPort), + constants.DockerCertPathEnv: ec.certsDir, + constants.MinikubeActiveDockerdEnv: ec.profile, + } + + if driver.IsKIC(ec.driver) { // for kic we need to find out what port docker allocated during creation + port, err := oci.HostPortBinding(ec.driver, ec.profile, constants.DockerDaemonPort) + if err != nil { + return nil, errors.Wrapf(err, "get hostbind port for %d", constants.DockerDaemonPort) + } + env[constants.DockerCertPathEnv] = dockerURL(kic.DefaultBindIPV4, port) + } + return env, nil +} + +func init() { + defaultNoProxyGetter = &EnvNoProxyGetter{} + dockerEnvCmd.Flags().Bool("no-proxy", false, "Add machine IP to NO_PROXY environment variable") + dockerEnvCmd.Flags().StringVar(&forceShell, "shell", "auto", "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect") + dockerEnvCmd.Flags().BoolP("unset", "u", false, "Unset variables instead of setting them") } diff --git a/cmd/minikube/cmd/env_test.go b/cmd/minikube/cmd/env_test.go index f304471e6f..cd9e102ab1 100644 --- a/cmd/minikube/cmd/env_test.go +++ b/cmd/minikube/cmd/env_test.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors All rights reserved. +Copyright 2020 The Kubernetes Authors 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. @@ -17,25 +17,12 @@ limitations under the License. package cmd import ( - "reflect" + "bytes" "testing" - "github.com/docker/machine/libmachine/host" - "github.com/spf13/viper" - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/constants" - "k8s.io/minikube/pkg/minikube/localpath" - "k8s.io/minikube/pkg/minikube/tests" + "github.com/google/go-cmp/cmp" ) -type FakeShellDetector struct { - Shell string -} - -func (f FakeShellDetector) GetShell(_ string) (string, error) { - return f.Shell, nil -} - type FakeNoProxyGetter struct { NoProxyVar string NoProxyValue string @@ -45,297 +32,212 @@ func (f FakeNoProxyGetter) GetNoProxyVar() (string, string) { return f.NoProxyVar, f.NoProxyValue } -var defaultAPI = &tests.MockAPI{ - FakeStore: tests.FakeStore{ - Hosts: map[string]*host.Host{ - constants.DefaultMachineName: { - Name: constants.DefaultMachineName, - Driver: &tests.MockDriver{}, - }, - }, - }, -} - -// Most of the shell cfg isn't configurable -func newShellCfg(shell, prefix, suffix, delim string) *ShellConfig { - return &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", shell), - Prefix: prefix, - Suffix: suffix, - Delimiter: delim, - MinikubeDockerdProfile: "minikube", - } -} - -func TestShellCfgSet(t *testing.T) { +func TestGenerateScripts(t *testing.T) { var tests = []struct { - description string - api *tests.MockAPI - shell string - noProxyVar string - noProxyValue string - expectedShellCfg *ShellConfig - shouldErr bool - noProxyFlag bool + config EnvConfig + noProxyGetter *FakeNoProxyGetter + wantSet string + wantUnset string }{ { - description: "no host specified", - api: &tests.MockAPI{ - FakeStore: tests.FakeStore{ - Hosts: make(map[string]*host.Host), - }, - }, - shell: "bash", - expectedShellCfg: nil, - shouldErr: true, + EnvConfig{profile: "bash", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs"}, + nil, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://127.0.0.1:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="bash" + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash docker-env) +`, + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash docker-env)`, }, { - description: "default", - api: defaultAPI, - shell: "bash", - expectedShellCfg: newShellCfg("", bashSetPfx, bashSetSfx, bashSetDelim), - shouldErr: false, + EnvConfig{profile: "fish", shell: "fish", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs"}, + nil, + `set -gx DOCKER_TLS_VERIFY "1"; +set -gx DOCKER_HOST "tcp://127.0.0.1:2376"; +set -gx DOCKER_CERT_PATH "/certs"; +set -gx MINIKUBE_ACTIVE_DOCKERD "fish"; + +# To point your shell to minikube's docker-daemon, +# eval (minikube -p fish docker-env) +`, + `set -e DOCKER_TLS_VERIFY; +set -e DOCKER_HOST; +set -e DOCKER_CERT_PATH; +set -e MINIKUBE_ACTIVE_DOCKERD; + +# To point your shell to minikube's docker-daemon, +# eval (minikube -p fish docker-env)`, }, { - description: "bash", - api: defaultAPI, - shell: "bash", - expectedShellCfg: newShellCfg("bash", bashSetPfx, bashSetSfx, bashSetDelim), - shouldErr: false, + EnvConfig{profile: "powershell", shell: "powershell", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, + nil, + `$Env:DOCKER_TLS_VERIFY = "1" +$Env:DOCKER_HOST = "tcp://192.168.0.1:2376" +$Env:DOCKER_CERT_PATH = "/certs" +$Env:MINIKUBE_ACTIVE_DOCKERD = "powershell" + +# To point your shell to minikube's docker-daemon, +# & minikube -p powershell docker-env | Invoke-Expression +`, + `Remove-Item Env:\\DOCKER_TLS_VERIFY +Remove-Item Env:\\DOCKER_HOST +Remove-Item Env:\\DOCKER_CERT_PATH +Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD + +# To point your shell to minikube's docker-daemon, +# & minikube -p powershell docker-env | Invoke-Expression`, }, { - description: "fish", - api: defaultAPI, - shell: "fish", - expectedShellCfg: newShellCfg("fish", fishSetPfx, fishSetSfx, fishSetDelim), - shouldErr: false, + EnvConfig{profile: "cmd", shell: "cmd", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, + nil, + `SET DOCKER_TLS_VERIFY=1 +SET DOCKER_HOST=tcp://192.168.0.1:2376 +SET DOCKER_CERT_PATH=/certs +SET MINIKUBE_ACTIVE_DOCKERD=cmd + +REM To point your shell to minikube's docker-daemon, +REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i +`, + `SET DOCKER_TLS_VERIFY= +SET DOCKER_HOST= +SET DOCKER_CERT_PATH= +SET MINIKUBE_ACTIVE_DOCKERD= + +REM To point your shell to minikube's docker-daemon, +REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i`, }, { - description: "powershell", - api: defaultAPI, - shell: "powershell", - expectedShellCfg: newShellCfg("powershell", psSetPfx, psSetSfx, psSetDelim), - shouldErr: false, + EnvConfig{profile: "emacs", shell: "emacs", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, + nil, + `(setenv "DOCKER_TLS_VERIFY" "1") +(setenv "DOCKER_HOST" "tcp://192.168.0.1:2376") +(setenv "DOCKER_CERT_PATH" "/certs") +(setenv "MINIKUBE_ACTIVE_DOCKERD" "emacs") + +;; To point your shell to minikube's docker-daemon, +;; (with-temp-buffer (shell-command "minikube -p emacs docker-env" (current-buffer)) (eval-buffer)) +`, + `(setenv "DOCKER_TLS_VERIFY" nil) +(setenv "DOCKER_HOST" nil) +(setenv "DOCKER_CERT_PATH" nil) +(setenv "MINIKUBE_ACTIVE_DOCKERD" nil) + +;; To point your shell to minikube's docker-daemon, +;; (with-temp-buffer (shell-command "minikube -p emacs docker-env" (current-buffer)) (eval-buffer))`, }, { - description: "cmd", - api: defaultAPI, - shell: "cmd", - expectedShellCfg: newShellCfg("cmd", cmdSetPfx, cmdSetSfx, cmdSetDelim), - shouldErr: false, + EnvConfig{profile: "bash-no-proxy", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, + &FakeNoProxyGetter{"NO_PROXY", "127.0.0.1"}, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://127.0.0.1:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy" +export NO_PROXY="127.0.0.1" + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash-no-proxy docker-env) +`, + + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD +unset no_proxy127.0.0.1`, }, { - description: "emacs", - api: defaultAPI, - shell: "emacs", - expectedShellCfg: newShellCfg("emacs", emacsSetPfx, emacsSetSfx, emacsSetDelim), - shouldErr: false, + EnvConfig{profile: "bash-no-proxy-lower", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, + &FakeNoProxyGetter{"no_proxy", "127.0.0.1"}, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://127.0.0.1:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy-lower" +export no_proxy="127.0.0.1" + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash-no-proxy-lower docker-env) +`, + + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD +unset no_proxy127.0.0.1`, }, { - description: "no proxy add uppercase", - api: defaultAPI, - shell: "bash", - noProxyVar: "NO_PROXY", - noProxyValue: "", - noProxyFlag: true, - expectedShellCfg: &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", "bash"), - Prefix: bashSetPfx, - Suffix: bashSetSfx, - Delimiter: bashSetDelim, - NoProxyVar: "NO_PROXY", - NoProxyValue: "127.0.0.1", - MinikubeDockerdProfile: "minikube", - }, + EnvConfig{profile: "bash-no-proxy-idempotent", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, + &FakeNoProxyGetter{"no_proxy", "127.0.0.1"}, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://127.0.0.1:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy-idempotent" +export no_proxy="127.0.0.1" + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash-no-proxy-idempotent docker-env) +`, + + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD +unset no_proxy127.0.0.1 + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p bash-no-proxy-idempotent docker-env)`, }, { - description: "no proxy add lowercase", - api: defaultAPI, - shell: "bash", - noProxyVar: "no_proxy", - noProxyValue: "", - noProxyFlag: true, - expectedShellCfg: &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", "bash"), - Prefix: bashSetPfx, - Suffix: bashSetSfx, - Delimiter: bashSetDelim, - NoProxyVar: "no_proxy", - NoProxyValue: "127.0.0.1", - MinikubeDockerdProfile: "minikube", - }, - }, - { - description: "no proxy idempotent", - api: defaultAPI, - shell: "bash", - noProxyVar: "no_proxy", - noProxyValue: "127.0.0.1", - noProxyFlag: true, - expectedShellCfg: &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", "bash"), - Prefix: bashSetPfx, - Suffix: bashSetSfx, - Delimiter: bashSetDelim, - NoProxyVar: "no_proxy", - NoProxyValue: "127.0.0.1", - MinikubeDockerdProfile: "minikube", - }, - }, - { - description: "no proxy list add", - api: defaultAPI, - shell: "bash", - noProxyVar: "no_proxy", - noProxyValue: "0.0.0.0", - noProxyFlag: true, - expectedShellCfg: &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", "bash"), - Prefix: bashSetPfx, - Suffix: bashSetSfx, - Delimiter: bashSetDelim, - NoProxyVar: "no_proxy", - NoProxyValue: "0.0.0.0,127.0.0.1", - MinikubeDockerdProfile: "minikube", - }, - }, - { - description: "no proxy list already present", - api: defaultAPI, - shell: "bash", - noProxyVar: "no_proxy", - noProxyValue: "0.0.0.0,127.0.0.1", - noProxyFlag: true, - expectedShellCfg: &ShellConfig{ - DockerCertPath: localpath.MakeMiniPath("certs"), - DockerTLSVerify: "1", - DockerHost: "tcp://127.0.0.1:2376", - UsageHint: generateUsageHint("minikube", "bash"), - Prefix: bashSetPfx, - Suffix: bashSetSfx, - Delimiter: bashSetDelim, - NoProxyVar: "no_proxy", - NoProxyValue: "0.0.0.0,127.0.0.1", - MinikubeDockerdProfile: "minikube", - }, + EnvConfig{profile: "sh-no-proxy-add", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, + &FakeNoProxyGetter{"NO_PROXY", "192.168.0.1,10.0.0.4"}, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://127.0.0.1:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="sh-no-proxy-add" +export NO_PROXY="192.168.0.1,10.0.0.4,127.0.0.1" + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p sh-no-proxy-add docker-env)`, + + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD +unset NO_PROXY192.168.0.1,10.0.0.4 + +# To point your shell to minikube's docker-daemon, +# eval $(minikube -p sh-no-proxy-add docker-env)`, }, } + for _, tc := range tests { + t.Run(tc.config.profile, func(t *testing.T) { + defaultNoProxyGetter = tc.noProxyGetter + var b []byte + buf := bytes.NewBuffer(b) + if err := generateSetScript(tc.config, buf); err != nil { + t.Errorf("generateSetScript(%+v) error: %v", tc.config, err) + } + got := buf.String() + if diff := cmp.Diff(tc.wantSet, got); diff != "" { + t.Errorf("generateSetScript(%+v) content mismatch (-want +got):\n%s\n\nraw output:\n%s", tc.config, diff, got) + } - for _, test := range tests { - test := test - t.Run(test.description, func(t *testing.T) { + buf = bytes.NewBuffer(b) + if err := generateUnsetScript(tc.config, buf); err != nil { + t.Errorf("generateUnsetScript(%+v) error: %v", tc.config, err) + } + got = buf.String() + if diff := cmp.Diff(tc.wantUnset, got); diff != "" { + t.Errorf("generateUnsetScript(%+v) content mismatch (-want +got):\n%s\n\nraw output:\n%s", tc.config, diff, got) + } - viper.Set(config.MachineProfile, constants.DefaultMachineName) - defaultShellDetector = &FakeShellDetector{test.shell} - defaultNoProxyGetter = &FakeNoProxyGetter{test.noProxyVar, test.noProxyValue} - noProxy = test.noProxyFlag - test.api.T = t - shellCfg, err := shellCfgSet(test.api) - if !reflect.DeepEqual(shellCfg, test.expectedShellCfg) { - t.Errorf("Shell cfgs differ: expected %+v, \n\n got %+v", test.expectedShellCfg, shellCfg) - } - if err != nil && !test.shouldErr { - t.Errorf("Unexpected error occurred: %s, error: %v", test.description, err) - } - if err == nil && test.shouldErr { - t.Errorf("Test didn't return error but should have: %s", test.description) - } - }) - } -} - -func TestShellCfgUnset(t *testing.T) { - - var tests = []struct { - description string - shell string - expectedShellCfg *ShellConfig - }{ - { - description: "unset default", - shell: "bash", - expectedShellCfg: &ShellConfig{ - Prefix: bashUnsetPfx, - Suffix: bashUnsetSfx, - Delimiter: bashUnsetDelim, - UsageHint: generateUsageHint("minikube", "bash"), - }, - }, - { - description: "unset bash", - shell: "bash", - expectedShellCfg: &ShellConfig{ - Prefix: bashUnsetPfx, - Suffix: bashUnsetSfx, - Delimiter: bashUnsetDelim, - UsageHint: generateUsageHint("minikube", "bash"), - }, - }, - { - description: "unset fish", - shell: "fish", - expectedShellCfg: &ShellConfig{ - Prefix: fishUnsetPfx, - Suffix: fishUnsetSfx, - Delimiter: fishUnsetDelim, - UsageHint: generateUsageHint("minikube", "fish"), - }, - }, - { - description: "unset powershell", - shell: "powershell", - expectedShellCfg: &ShellConfig{ - Prefix: psUnsetPfx, - Suffix: psUnsetSfx, - Delimiter: psUnsetDelim, - UsageHint: generateUsageHint("minikube", "powershell"), - }, - }, - { - description: "unset cmd", - shell: "cmd", - expectedShellCfg: &ShellConfig{ - Prefix: cmdUnsetPfx, - Suffix: cmdUnsetSfx, - Delimiter: cmdUnsetDelim, - UsageHint: generateUsageHint("minikube", "cmd"), - }, - }, - { - description: "unset emacs", - shell: "emacs", - expectedShellCfg: &ShellConfig{ - Prefix: emacsUnsetPfx, - Suffix: emacsUnsetSfx, - Delimiter: emacsUnsetDelim, - UsageHint: generateUsageHint("minikube", "emacs"), - }, - }, - } - - for _, test := range tests { - t.Run(test.description, func(t *testing.T) { - defaultShellDetector = &FakeShellDetector{test.shell} - defaultNoProxyGetter = &FakeNoProxyGetter{} - actual, _ := shellCfgUnset() - if !reflect.DeepEqual(actual, test.expectedShellCfg) { - t.Errorf("Actual shell config did not match expected: \n\n actual: \n%+v \n\n expected: \n%+v \n\n", actual, test.expectedShellCfg) - } }) } } diff --git a/go.mod b/go.mod index 346a954e35..48ba9b8692 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/juju/version v0.0.0-20180108022336-b64dbd566305 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/libvirt/libvirt-go v3.4.0+incompatible + github.com/lithammer/dedent v1.1.0 github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 github.com/mattn/go-isatty v0.0.9 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 diff --git a/go.sum b/go.sum index 40b885f371..8ff8a7db82 100644 --- a/go.sum +++ b/go.sum @@ -428,6 +428,7 @@ github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wn github.com/libvirt/libvirt-go v3.4.0+incompatible h1:Cpyalgj1x8JIeTlL6SDYZBo7j8nY3+5XHqmi8DaunCk= github.com/libvirt/libvirt-go v3.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= diff --git a/pkg/minikube/cluster/cluster_test.go b/pkg/minikube/cluster/cluster_test.go index 4c9490ecb8..14c809360c 100644 --- a/pkg/minikube/cluster/cluster_test.go +++ b/pkg/minikube/cluster/cluster_test.go @@ -18,7 +18,6 @@ package cluster import ( "fmt" - "os" "testing" "time" @@ -338,73 +337,6 @@ func TestGetHostStatus(t *testing.T) { checkState(state.Stopped.String()) } -func TestGetNodeDockerEnv(t *testing.T) { - RegisterMockDriver(t) - tempDir := tests.MakeTempDir() - defer os.RemoveAll(tempDir) - - api := tests.NewMockAPI(t) - h, err := createHost(api, defaultMachineConfig) - if err != nil { - t.Fatalf("Error creating host: %v", err) - } - d := &tests.MockDriver{ - BaseDriver: drivers.BaseDriver{ - IPAddress: "127.0.0.1", - }, - T: t, - } - h.Driver = d - - envMap, err := GetNodeDockerEnv(api) - if err != nil { - t.Fatalf("Unexpected error getting env: %v", err) - } - - dockerEnvKeys := [...]string{ - constants.DockerTLSVerifyEnv, - constants.DockerHostEnv, - constants.DockerCertPathEnv, - constants.MinikubeActiveDockerdEnv, - } - for _, dockerEnvKey := range dockerEnvKeys { - if _, hasKey := envMap[dockerEnvKey]; !hasKey { - t.Fatalf("Expected envMap[\"%s\"] key to be defined", dockerEnvKey) - } - } -} - -func TestGetNodeDockerEnvIPv6(t *testing.T) { - RegisterMockDriver(t) - - tempDir := tests.MakeTempDir() - defer os.RemoveAll(tempDir) - - api := tests.NewMockAPI(t) - h, err := createHost(api, defaultMachineConfig) - if err != nil { - t.Fatalf("Error creating host: %v", err) - } - d := &tests.MockDriver{ - BaseDriver: drivers.BaseDriver{ - IPAddress: "fe80::215:5dff:fe00:a903", - }, - T: t, - } - h.Driver = d - - envMap, err := GetNodeDockerEnv(api) - if err != nil { - t.Fatalf("Unexpected error getting env: %v", err) - } - - expected := "tcp://[fe80::215:5dff:fe00:a903]:2376" - v := envMap["DOCKER_HOST"] - if v != expected { - t.Fatalf("Expected DOCKER_HOST to be defined as %s but was %s", expected, v) - } -} - func TestCreateSSHShell(t *testing.T) { api := tests.NewMockAPI(t) diff --git a/pkg/minikube/cluster/docker_env.go b/pkg/minikube/cluster/docker_env.go deleted file mode 100644 index d3feac7fca..0000000000 --- a/pkg/minikube/cluster/docker_env.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors 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 cluster - -import ( - "fmt" - "net" - - "github.com/docker/machine/libmachine" - "github.com/pkg/errors" - "github.com/spf13/viper" - "k8s.io/minikube/pkg/drivers/kic" - "k8s.io/minikube/pkg/drivers/kic/oci" - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/constants" - "k8s.io/minikube/pkg/minikube/driver" - "k8s.io/minikube/pkg/minikube/localpath" -) - -// GetNodeDockerEnv gets the necessary docker env variables to allow the use of docker through minikube's vm -func GetNodeDockerEnv(api libmachine.API) (map[string]string, error) { - pName := viper.GetString(config.MachineProfile) - host, err := CheckIfHostExistsAndLoad(api, pName) - if err != nil { - return nil, errors.Wrap(err, "Error checking that api exists and loading it") - } - - ip := kic.DefaultBindIPV4 - if !driver.IsKIC(host.Driver.DriverName()) { // kic externally accessible ip is different that node ip - ip, err = host.Driver.GetIP() - if err != nil { - return nil, errors.Wrap(err, "Error getting ip from host") - } - - } - - tcpPrefix := "tcp://" - port := constants.DockerDaemonPort - if driver.IsKIC(host.Driver.DriverName()) { // for kic we need to find out what port docker allocated during creation - port, err = oci.HostPortBinding(host.Driver.DriverName(), pName, constants.DockerDaemonPort) - if err != nil { - return nil, errors.Wrapf(err, "get hostbind port for %d", constants.DockerDaemonPort) - } - } - - envMap := map[string]string{ - constants.DockerTLSVerifyEnv: "1", - constants.DockerHostEnv: tcpPrefix + net.JoinHostPort(ip, fmt.Sprint(port)), - constants.DockerCertPathEnv: localpath.MakeMiniPath("certs"), - constants.MinikubeActiveDockerdEnv: pName, - } - return envMap, nil -} From b478fbaa1aef3596e7c57eb365f3ef0148b829a8 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 15:40:24 -0800 Subject: [PATCH 3/6] Minimize changes --- cmd/minikube/cmd/env.go | 27 ++++++++++++--------------- go.mod | 1 - go.sum | 1 - 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/cmd/minikube/cmd/env.go b/cmd/minikube/cmd/env.go index fe764cc84f..52a2b807d2 100644 --- a/cmd/minikube/cmd/env.go +++ b/cmd/minikube/cmd/env.go @@ -46,10 +46,7 @@ import ( "k8s.io/minikube/pkg/minikube/out" ) -var ( - forceShell string - envTmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}", constants.DockerTLSVerifyEnv, constants.DockerHostEnv, constants.DockerCertPathEnv, constants.MinikubeActiveDockerdEnv) -) +var envTmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}", constants.DockerTLSVerifyEnv, constants.DockerHostEnv, constants.DockerCertPathEnv, constants.MinikubeActiveDockerdEnv) const ( fishSetPfx = "set -gx " @@ -112,6 +109,9 @@ type ShellConfig struct { } var ( + noProxy bool + forceShell string + unset bool defaultNoProxyGetter NoProxyGetter ) @@ -331,23 +331,20 @@ var dockerEnvCmd = &cobra.Command{ ec := EnvConfig{ profile: profile, driver: host.DriverName, + shell: forceShell, hostIP: hostIP, certsDir: localpath.MakeMiniPath("certs"), - noProxy: viper.GetBool("no-proxy"), + noProxy: noProxy, } - sh := viper.GetString("shell") - fmt.Printf("user shell=%s\n", sh) - if sh == "" { - sh, err = shell.Detect() + if ec.shell == "" { + ec.shell, err = shell.Detect() if err != nil { exit.WithError("Error detecting shell", err) } } - ec.shell = sh - fmt.Printf("shell=%s, ec: %+v\n", viper.GetString("shell"), ec) - if viper.GetBool("unset") { + if unset { if err := generateUnsetScript(ec, os.Stdout); err != nil { exit.WithError("Error generating unset output", err) } @@ -412,7 +409,7 @@ func dockerEnvVars(ec EnvConfig) (map[string]string, error) { func init() { defaultNoProxyGetter = &EnvNoProxyGetter{} - dockerEnvCmd.Flags().Bool("no-proxy", false, "Add machine IP to NO_PROXY environment variable") - dockerEnvCmd.Flags().StringVar(&forceShell, "shell", "auto", "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect") - dockerEnvCmd.Flags().BoolP("unset", "u", false, "Unset variables instead of setting them") + dockerEnvCmd.Flags().BoolVar(&noProxy, "no-proxy", false, "Add machine IP to NO_PROXY environment variable") + dockerEnvCmd.Flags().StringVar(&forceShell, "shell", "", "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect") + dockerEnvCmd.Flags().BoolVarP(&unset, "unset", "u", false, "Unset variables instead of setting them") } diff --git a/go.mod b/go.mod index 48ba9b8692..346a954e35 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( github.com/juju/version v0.0.0-20180108022336-b64dbd566305 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/libvirt/libvirt-go v3.4.0+incompatible - github.com/lithammer/dedent v1.1.0 github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 github.com/mattn/go-isatty v0.0.9 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 diff --git a/go.sum b/go.sum index 8ff8a7db82..40b885f371 100644 --- a/go.sum +++ b/go.sum @@ -428,7 +428,6 @@ github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wn github.com/libvirt/libvirt-go v3.4.0+incompatible h1:Cpyalgj1x8JIeTlL6SDYZBo7j8nY3+5XHqmi8DaunCk= github.com/libvirt/libvirt-go v3.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= From 6e19c62896039edd3271b9a18034fa17418d59ff Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 15:54:57 -0800 Subject: [PATCH 4/6] Update tests to include all current output quirks --- cmd/minikube/cmd/env.go | 12 ++--- cmd/minikube/cmd/env_test.go | 88 ++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/cmd/minikube/cmd/env.go b/cmd/minikube/cmd/env.go index 52a2b807d2..a708312eef 100644 --- a/cmd/minikube/cmd/env.go +++ b/cmd/minikube/cmd/env.go @@ -345,13 +345,13 @@ var dockerEnvCmd = &cobra.Command{ } if unset { - if err := generateUnsetScript(ec, os.Stdout); err != nil { + if err := unsetScript(ec, os.Stdout); err != nil { exit.WithError("Error generating unset output", err) } return } - if err := generateSetScript(ec, os.Stdout); err != nil { + if err := setScript(ec, os.Stdout); err != nil { exit.WithError("Error generating set output", err) } }, @@ -367,8 +367,8 @@ type EnvConfig struct { noProxy bool } -// generateSetScript writes out a shell-compatible 'docker-env' script -func generateSetScript(ec EnvConfig, w io.Writer) error { +// setScript writes out a shell-compatible 'docker-env' script +func setScript(ec EnvConfig, w io.Writer) error { tmpl := template.Must(template.New("envConfig").Parse(envTmpl)) envVars, err := dockerEnvVars(ec) if err != nil { @@ -377,8 +377,8 @@ func generateSetScript(ec EnvConfig, w io.Writer) error { return tmpl.Execute(w, shellCfgSet(ec, envVars)) } -// generateSetScript writes out a shell-compatible 'docker-env unset' script -func generateUnsetScript(ec EnvConfig, w io.Writer) error { +// setScript writes out a shell-compatible 'docker-env unset' script +func unsetScript(ec EnvConfig, w io.Writer) error { tmpl := template.Must(template.New("envConfig").Parse(envTmpl)) return tmpl.Execute(w, shellCfgUnset(ec)) } diff --git a/cmd/minikube/cmd/env_test.go b/cmd/minikube/cmd/env_test.go index cd9e102ab1..3f1a7cbab0 100644 --- a/cmd/minikube/cmd/env_test.go +++ b/cmd/minikube/cmd/env_test.go @@ -47,7 +47,7 @@ export DOCKER_HOST="tcp://127.0.0.1:2376" export DOCKER_CERT_PATH="/certs" export MINIKUBE_ACTIVE_DOCKERD="bash" -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # eval $(minikube -p bash docker-env) `, `unset DOCKER_TLS_VERIFY @@ -55,8 +55,9 @@ unset DOCKER_HOST unset DOCKER_CERT_PATH unset MINIKUBE_ACTIVE_DOCKERD -# To point your shell to minikube's docker-daemon, -# eval $(minikube -p bash docker-env)`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p bash docker-env) +`, }, { EnvConfig{profile: "fish", shell: "fish", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs"}, @@ -66,7 +67,7 @@ set -gx DOCKER_HOST "tcp://127.0.0.1:2376"; set -gx DOCKER_CERT_PATH "/certs"; set -gx MINIKUBE_ACTIVE_DOCKERD "fish"; -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # eval (minikube -p fish docker-env) `, `set -e DOCKER_TLS_VERIFY; @@ -74,8 +75,9 @@ set -e DOCKER_HOST; set -e DOCKER_CERT_PATH; set -e MINIKUBE_ACTIVE_DOCKERD; -# To point your shell to minikube's docker-daemon, -# eval (minikube -p fish docker-env)`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval (minikube -p fish docker-env) +`, }, { EnvConfig{profile: "powershell", shell: "powershell", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, @@ -85,16 +87,18 @@ $Env:DOCKER_HOST = "tcp://192.168.0.1:2376" $Env:DOCKER_CERT_PATH = "/certs" $Env:MINIKUBE_ACTIVE_DOCKERD = "powershell" -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # & minikube -p powershell docker-env | Invoke-Expression -`, + `, + `Remove-Item Env:\\DOCKER_TLS_VERIFY Remove-Item Env:\\DOCKER_HOST Remove-Item Env:\\DOCKER_CERT_PATH Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD -# To point your shell to minikube's docker-daemon, -# & minikube -p powershell docker-env | Invoke-Expression`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# & minikube -p powershell docker-env | Invoke-Expression + `, }, { EnvConfig{profile: "cmd", shell: "cmd", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, @@ -104,16 +108,18 @@ SET DOCKER_HOST=tcp://192.168.0.1:2376 SET DOCKER_CERT_PATH=/certs SET MINIKUBE_ACTIVE_DOCKERD=cmd -REM To point your shell to minikube's docker-daemon, +REM Please run command bellow to point your shell to minikube's docker-daemon : REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i -`, + `, + `SET DOCKER_TLS_VERIFY= SET DOCKER_HOST= SET DOCKER_CERT_PATH= SET MINIKUBE_ACTIVE_DOCKERD= -REM To point your shell to minikube's docker-daemon, -REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i`, +REM Please run command bellow to point your shell to minikube's docker-daemon : +REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i + `, }, { EnvConfig{profile: "emacs", shell: "emacs", driver: "hyperv", hostIP: "192.168.0.1", certsDir: "/certs"}, @@ -123,16 +129,17 @@ REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env') DO @%i`, (setenv "DOCKER_CERT_PATH" "/certs") (setenv "MINIKUBE_ACTIVE_DOCKERD" "emacs") -;; To point your shell to minikube's docker-daemon, +;; Please run command bellow to point your shell to minikube's docker-daemon : ;; (with-temp-buffer (shell-command "minikube -p emacs docker-env" (current-buffer)) (eval-buffer)) -`, + `, `(setenv "DOCKER_TLS_VERIFY" nil) (setenv "DOCKER_HOST" nil) (setenv "DOCKER_CERT_PATH" nil) (setenv "MINIKUBE_ACTIVE_DOCKERD" nil) -;; To point your shell to minikube's docker-daemon, -;; (with-temp-buffer (shell-command "minikube -p emacs docker-env" (current-buffer)) (eval-buffer))`, +;; Please run command bellow to point your shell to minikube's docker-daemon : +;; (with-temp-buffer (shell-command "minikube -p emacs docker-env" (current-buffer)) (eval-buffer)) + `, }, { EnvConfig{profile: "bash-no-proxy", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, @@ -143,7 +150,7 @@ export DOCKER_CERT_PATH="/certs" export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy" export NO_PROXY="127.0.0.1" -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # eval $(minikube -p bash-no-proxy docker-env) `, @@ -151,7 +158,11 @@ export NO_PROXY="127.0.0.1" unset DOCKER_HOST unset DOCKER_CERT_PATH unset MINIKUBE_ACTIVE_DOCKERD -unset no_proxy127.0.0.1`, +unset NO_PROXY127.0.0.1 + +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p bash-no-proxy docker-env) +`, }, { EnvConfig{profile: "bash-no-proxy-lower", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, @@ -162,7 +173,7 @@ export DOCKER_CERT_PATH="/certs" export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy-lower" export no_proxy="127.0.0.1" -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # eval $(minikube -p bash-no-proxy-lower docker-env) `, @@ -170,7 +181,11 @@ export no_proxy="127.0.0.1" unset DOCKER_HOST unset DOCKER_CERT_PATH unset MINIKUBE_ACTIVE_DOCKERD -unset no_proxy127.0.0.1`, +unset no_proxy127.0.0.1 + +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p bash-no-proxy-lower docker-env) +`, }, { EnvConfig{profile: "bash-no-proxy-idempotent", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, @@ -181,7 +196,7 @@ export DOCKER_CERT_PATH="/certs" export MINIKUBE_ACTIVE_DOCKERD="bash-no-proxy-idempotent" export no_proxy="127.0.0.1" -# To point your shell to minikube's docker-daemon, +# Please run command bellow to point your shell to minikube's docker-daemon : # eval $(minikube -p bash-no-proxy-idempotent docker-env) `, @@ -191,8 +206,9 @@ unset DOCKER_CERT_PATH unset MINIKUBE_ACTIVE_DOCKERD unset no_proxy127.0.0.1 -# To point your shell to minikube's docker-daemon, -# eval $(minikube -p bash-no-proxy-idempotent docker-env)`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p bash-no-proxy-idempotent docker-env) +`, }, { EnvConfig{profile: "sh-no-proxy-add", shell: "bash", driver: "kvm2", hostIP: "127.0.0.1", certsDir: "/certs", noProxy: true}, @@ -203,8 +219,9 @@ export DOCKER_CERT_PATH="/certs" export MINIKUBE_ACTIVE_DOCKERD="sh-no-proxy-add" export NO_PROXY="192.168.0.1,10.0.0.4,127.0.0.1" -# To point your shell to minikube's docker-daemon, -# eval $(minikube -p sh-no-proxy-add docker-env)`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p sh-no-proxy-add docker-env) +`, `unset DOCKER_TLS_VERIFY unset DOCKER_HOST @@ -212,8 +229,9 @@ unset DOCKER_CERT_PATH unset MINIKUBE_ACTIVE_DOCKERD unset NO_PROXY192.168.0.1,10.0.0.4 -# To point your shell to minikube's docker-daemon, -# eval $(minikube -p sh-no-proxy-add docker-env)`, +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p sh-no-proxy-add docker-env) +`, }, } for _, tc := range tests { @@ -221,21 +239,21 @@ unset NO_PROXY192.168.0.1,10.0.0.4 defaultNoProxyGetter = tc.noProxyGetter var b []byte buf := bytes.NewBuffer(b) - if err := generateSetScript(tc.config, buf); err != nil { - t.Errorf("generateSetScript(%+v) error: %v", tc.config, err) + if err := setScript(tc.config, buf); err != nil { + t.Errorf("setScript(%+v) error: %v", tc.config, err) } got := buf.String() if diff := cmp.Diff(tc.wantSet, got); diff != "" { - t.Errorf("generateSetScript(%+v) content mismatch (-want +got):\n%s\n\nraw output:\n%s", tc.config, diff, got) + t.Errorf("setScript(%+v) mismatch (-want +got):\n%s\n\nraw output:\n%s\nquoted: %q", tc.config, diff, got, got) } buf = bytes.NewBuffer(b) - if err := generateUnsetScript(tc.config, buf); err != nil { - t.Errorf("generateUnsetScript(%+v) error: %v", tc.config, err) + if err := unsetScript(tc.config, buf); err != nil { + t.Errorf("unsetScript(%+v) error: %v", tc.config, err) } got = buf.String() if diff := cmp.Diff(tc.wantUnset, got); diff != "" { - t.Errorf("generateUnsetScript(%+v) content mismatch (-want +got):\n%s\n\nraw output:\n%s", tc.config, diff, got) + t.Errorf("unsetScript(%+v) mismatch (-want +got):\n%s\n\nraw output:\n%s\nquoted: %q", tc.config, diff, got, got) } }) From 0cac457126355ed037ee2f29b8e904eec36a65a0 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 16:05:05 -0800 Subject: [PATCH 5/6] Transition TestGetNodeDockerEnvIPv6 to env_test --- cmd/minikube/cmd/env_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cmd/minikube/cmd/env_test.go b/cmd/minikube/cmd/env_test.go index 3f1a7cbab0..f287b4bdc0 100644 --- a/cmd/minikube/cmd/env_test.go +++ b/cmd/minikube/cmd/env_test.go @@ -57,6 +57,26 @@ unset MINIKUBE_ACTIVE_DOCKERD # Please run command bellow to point your shell to minikube's docker-daemon : # eval $(minikube -p bash docker-env) +`, + }, + { + EnvConfig{profile: "ipv6", shell: "bash", driver: "kvm2", hostIP: "fe80::215:5dff:fe00:a903", certsDir: "/certs"}, + nil, + `export DOCKER_TLS_VERIFY="1" +export DOCKER_HOST="tcp://[fe80::215:5dff:fe00:a903]:2376" +export DOCKER_CERT_PATH="/certs" +export MINIKUBE_ACTIVE_DOCKERD="ipv6" + +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p ipv6 docker-env) +`, + `unset DOCKER_TLS_VERIFY +unset DOCKER_HOST +unset DOCKER_CERT_PATH +unset MINIKUBE_ACTIVE_DOCKERD + +# Please run command bellow to point your shell to minikube's docker-daemon : +# eval $(minikube -p ipv6 docker-env) `, }, { From 63954700d70a857aa742a436423d8839663a7d2b Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 6 Feb 2020 17:32:08 -0800 Subject: [PATCH 6/6] Address review comments --- cmd/minikube/cmd/env.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/env.go b/cmd/minikube/cmd/env.go index a708312eef..290c6041d3 100644 --- a/cmd/minikube/cmd/env.go +++ b/cmd/minikube/cmd/env.go @@ -388,7 +388,7 @@ func dockerURL(ip string, port int) string { return fmt.Sprintf("tcp://%s", net.JoinHostPort(ip, strconv.Itoa(port))) } -// dockerEnvVars gets the necessary docker env variables to allow the use of docker through minikube's vm +// dockerEnvVars gets the necessary docker env variables to allow the use of minikube's docker daemon func dockerEnvVars(ec EnvConfig) (map[string]string, error) { env := map[string]string{ constants.DockerTLSVerifyEnv: "1",