Fix docker-env command

pull/9510/head
Ilya Zuyev 2020-10-20 23:10:08 -07:00
parent d384343c39
commit 85d45be207
8 changed files with 168 additions and 36 deletions

View File

@ -30,6 +30,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/constants"
@ -43,7 +44,31 @@ import (
"k8s.io/minikube/pkg/minikube/sysinit"
)
var dockerEnvTmpl = 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 dockerSetEnvTmpl = fmt.Sprintf(
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}"+
"{{ if .ExistingDockerTLSVerify }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .ExistingDockerTLSVerify }}{{ .Suffix }}"+
"{{ end }}"+
"{{ if .ExistingDockerHost }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .ExistingDockerHost }}{{ .Suffix }}"+
"{{ end }}"+
"{{ if .ExistingDockerCertPath }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .ExistingDockerCertPath }}{{ .Suffix }}"+
"{{ end }}"+
"{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}"+
"{{ if .NoProxyVar }}"+
"{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}"+
"{{ end }}"+
"{{ .UsageHint }}",
constants.DockerTLSVerifyEnv,
constants.DockerHostEnv,
constants.DockerCertPathEnv,
constants.ExistingDockerTLSVerifyEnv,
constants.ExistingDockerHostEnv,
constants.ExistingDockerCertPathEnv,
constants.MinikubeActiveDockerdEnv)
// DockerShellConfig represents the shell config for Docker
type DockerShellConfig struct {
@ -54,6 +79,10 @@ type DockerShellConfig struct {
MinikubeDockerdProfile string
NoProxyVar string
NoProxyValue string
ExistingDockerCertPath string
ExistingDockerHost string
ExistingDockerTLSVerify string
}
var (
@ -81,6 +110,11 @@ func dockerShellCfgSet(ec DockerEnvConfig, envMap map[string]string) *DockerShel
s.DockerCertPath = envMap[constants.DockerCertPathEnv]
s.DockerHost = envMap[constants.DockerHostEnv]
s.DockerTLSVerify = envMap[constants.DockerTLSVerifyEnv]
s.ExistingDockerCertPath = envMap[constants.ExistingDockerCertPathEnv]
s.ExistingDockerHost = envMap[constants.ExistingDockerHostEnv]
s.ExistingDockerTLSVerify = envMap[constants.ExistingDockerTLSVerifyEnv]
s.MinikubeDockerdProfile = envMap[constants.MinikubeActiveDockerdEnv]
if ec.noProxy {
@ -228,7 +262,7 @@ type DockerEnvConfig struct {
// dockerSetScript writes out a shell-compatible 'docker-env' script
func dockerSetScript(ec DockerEnvConfig, w io.Writer) error {
envVars := dockerEnvVars(ec)
return shell.SetScript(ec.EnvConfig, w, dockerEnvTmpl, dockerShellCfgSet(ec, envVars))
return shell.SetScript(ec.EnvConfig, w, dockerSetEnvTmpl, dockerShellCfgSet(ec, envVars))
}
// dockerSetScript writes out a shell-compatible 'docker-env unset' script
@ -246,7 +280,6 @@ func dockerUnsetScript(ec DockerEnvConfig, w io.Writer) error {
vars = append(vars, k)
}
}
return shell.UnsetScript(ec.EnvConfig, w, vars)
}
@ -257,14 +290,21 @@ func dockerURL(ip string, port int) string {
// dockerEnvVars gets the necessary docker env variables to allow the use of minikube's docker daemon
func dockerEnvVars(ec DockerEnvConfig) map[string]string {
env := map[string]string{
rt := map[string]string{
constants.DockerTLSVerifyEnv: "1",
constants.DockerHostEnv: dockerURL(ec.hostIP, ec.port),
constants.DockerCertPathEnv: ec.certsDir,
constants.MinikubeActiveDockerdEnv: ec.profile,
}
return env
if os.Getenv(constants.MinikubeActiveDockerdEnv) == "" {
for _, env := range constants.DockerDaemonEnvs {
if v := oci.InitialEnv(env); v != "" {
key := constants.MinikubeExistingPrefix + env
rt[key] = v
}
}
}
return rt
}
// dockerEnvVarsList gets the necessary docker env variables to allow the use of minikube's docker daemon to be used in a exec.Command

View File

@ -95,10 +95,11 @@ func (d *Driver) Create() error {
}
// control plane specific options
params.PortMappings = append(params.PortMappings, oci.PortMapping{
ListenAddress: oci.DefaultBindIPV4,
ContainerPort: int32(params.APIServerPort),
},
params.PortMappings = append(params.PortMappings,
oci.PortMapping{
ListenAddress: oci.DefaultBindIPV4,
ContainerPort: int32(params.APIServerPort),
},
oci.PortMapping{
ListenAddress: oci.DefaultBindIPV4,
ContainerPort: constants.SSHPort,

View File

@ -0,0 +1,47 @@
/*
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 oci
import (
"os"
"k8s.io/minikube/pkg/minikube/constants"
)
var initialEnvs = make(map[string]string)
func init() {
for _, env := range constants.DockerDaemonEnvs {
if v, set := os.LookupEnv(env); set {
initialEnvs[env] = v
}
exEnv := constants.MinikubeExistingPrefix + env
if v, set := os.LookupEnv(exEnv); set {
initialEnvs[exEnv] = v
}
}
}
// InitialEnv returns the value of the environment variable env before any environment changes made by minikube
func InitialEnv(env string) string {
return initialEnvs[env]
}
// LookupInitialEnv returns the value of the environment variable env before any environment changes made by minikube
func LookupInitialEnv(env string) (string, bool) {
v, set := initialEnvs[env]
return v, set
}

View File

@ -523,11 +523,10 @@ func PointToHostDockerDaemon() error {
if p := os.Getenv(constants.MinikubeActiveDockerdEnv); p != "" {
klog.Infof("shell is pointing to dockerd inside minikube. will unset to use host")
}
for _, e := range constants.DockerDaemonEnvs {
if err := resetEnv(e); err != nil {
return err
for _, e := range constants.DockerDaemonEnvs {
if err := resetEnv(e); err != nil {
return err
}
}
}
@ -542,7 +541,6 @@ func resetEnv(key string) error {
}
return nil
}
if err := os.Setenv(key, v); err != nil {
return errors.Wrapf(err, "resetting %s env", key)
}

View File

@ -25,6 +25,7 @@ func TestPointToHostDockerDaemonEmpty(t *testing.T) {
_ = os.Setenv("DOCKER_HOST", "foo_host")
_ = os.Setenv("DOCKER_CERT_PATH", "foo_cert_path")
_ = os.Setenv("DOCKER_TLS_VERIFY", "foo_tls_verify")
_ = os.Setenv("MINIKUBE_ACTIVE_DOCKERD", "minikube")
_ = os.Unsetenv("MINIKUBE_EXISTING_DOCKER_HOST")
_ = os.Unsetenv("MINIKUBE_EXISTING_DOCKER_CERT_PATH")

View File

@ -75,8 +75,16 @@ const (
MinikubeForceSystemdEnv = "MINIKUBE_FORCE_SYSTEMD"
// TestDiskUsedEnv is used in integration tests for insufficient storage with 'minikube status'
TestDiskUsedEnv = "MINIKUBE_TEST_STORAGE_CAPACITY"
// MinikubeExistingPrefix is used to save the original environment when executing docker-env
MinikubeExistingPrefix = "MINIKUBE_EXISTING_"
// ExistingDockerHostEnv is used to save original docker environment
ExistingDockerHostEnv = MinikubeExistingPrefix + "DOCKER_HOST"
// ExistingDockerCertPathEnv is used to save original docker environment
ExistingDockerCertPathEnv = MinikubeExistingPrefix + "DOCKER_CERT_PATH"
// ExistingDockerTLSVerifyEnv is used to save original docker environment
ExistingDockerTLSVerifyEnv = MinikubeExistingPrefix + "DOCKER_TLS_VERIFY"
)
var (
@ -92,6 +100,9 @@ var (
// DockerDaemonEnvs is list of docker-daemon related environment variables.
DockerDaemonEnvs = [3]string{DockerHostEnv, DockerTLSVerifyEnv, DockerCertPathEnv}
// ExistingDockerDaemonEnvs is list of docker-daemon related environment variables.
ExistingDockerDaemonEnvs = [3]string{ExistingDockerHostEnv, ExistingDockerTLSVerifyEnv, ExistingDockerCertPathEnv}
// PodmanRemoteEnvs is list of podman-remote related environment variables.
PodmanRemoteEnvs = [1]string{PodmanVarlinkBridgeEnv}

View File

@ -24,12 +24,21 @@ import (
"io"
"os"
"runtime"
"strings"
"text/template"
"github.com/docker/machine/libmachine/shell"
"k8s.io/minikube/pkg/minikube/constants"
)
var unsetEnvTmpl = "{{ $root := .}}" +
"{{ range .Unset }}" +
"{{ $root.UnsetPrefix }}{{ . }}{{ $root.UnsetDelimiter }}{{ $root.UnsetSuffix }}" +
"{{ end }}" +
"{{ range .Set }}" +
"{{ $root.SetPrefix }}{{ .Env }}{{ $root.SetDelimiter }}{{ .Value }}{{ $root.SetSuffix }}" +
"{{ end }}"
// Config represents the shell config
type Config struct {
Prefix string
@ -107,7 +116,7 @@ REM @FOR /f "tokens=*" %%i IN ('%s') DO @%%i
suffix: "\"\n",
delimiter: "=\"",
unsetPrefix: "unset ",
unsetSuffix: "\n",
unsetSuffix: ";\n",
unsetDelimiter: "",
usageHint: func(s ...interface{}) string {
return fmt.Sprintf(`
@ -181,24 +190,46 @@ func SetScript(ec EnvConfig, w io.Writer, envTmpl string, data interface{}) erro
return tmpl.Execute(w, data)
}
type unsetConfigItem struct {
Env, Value string
}
type unsetConfig struct {
Set []unsetConfigItem
Unset []string
SetPrefix string
SetDelimiter string
SetSuffix string
UnsetPrefix string
UnsetDelimiter string
UnsetSuffix string
}
// UnsetScript writes out a shell-compatible unset script
func UnsetScript(ec EnvConfig, w io.Writer, vars []string) error {
var sb strings.Builder
shellCfg := ec.getShell()
pfx, sfx, delim := shellCfg.unsetPrefix, shellCfg.unsetSuffix, shellCfg.unsetDelimiter
switch ec.Shell {
case "cmd", "emacs", "fish":
break
case "powershell":
vars = []string{strings.Join(vars, " Env:\\\\")}
default:
vars = []string{strings.Join(vars, " ")}
cfg := unsetConfig{
SetPrefix: shellCfg.prefix,
SetDelimiter: shellCfg.delimiter,
SetSuffix: shellCfg.suffix,
UnsetPrefix: shellCfg.unsetPrefix,
UnsetDelimiter: shellCfg.unsetDelimiter,
UnsetSuffix: shellCfg.unsetSuffix,
}
for _, v := range vars {
if _, err := sb.WriteString(fmt.Sprintf("%s%s%s%s", pfx, v, delim, sfx)); err != nil {
return err
var tempUnset []string
for _, env := range vars {
exEnv := constants.MinikubeExistingPrefix + env
if v := os.Getenv(exEnv); v == "" {
cfg.Unset = append(cfg.Unset, env)
} else {
cfg.Set = append(cfg.Set, unsetConfigItem{
Env: env,
Value: v,
})
tempUnset = append(tempUnset, exEnv)
}
}
_, err := w.Write([]byte(sb.String()))
return err
cfg.Unset = append(cfg.Unset, tempUnset...)
tmpl := template.Must(template.New("unsetEnv").Parse(unsetEnvTmpl))
return tmpl.Execute(w, &cfg)
}

View File

@ -87,16 +87,19 @@ func TestUnsetScript(t *testing.T) {
ec EnvConfig
expected string
}{
{[]string{"baz", "bar"}, EnvConfig{""}, `unset baz bar`},
{[]string{"baz", "bar"}, EnvConfig{"bash"}, `unset baz bar`},
{[]string{"baz", "bar"}, EnvConfig{"powershell"}, `Remove-Item Env:\\baz Env:\\bar`},
{[]string{"baz", "bar"}, EnvConfig{""}, `unset baz;
unset bar;`},
{[]string{"baz", "bar"}, EnvConfig{"bash"}, `unset baz;
unset bar;`},
{[]string{"baz", "bar"}, EnvConfig{"powershell"}, `Remove-Item Env:\\baz
Remove-Item Env:\\bar`},
{[]string{"baz", "bar"}, EnvConfig{"cmd"}, `SET baz=
SET bar=`},
{[]string{"baz", "bar"}, EnvConfig{"fish"}, `set -e baz;
set -e bar;`},
{[]string{"baz", "bar"}, EnvConfig{"emacs"}, `(setenv "baz" nil)
(setenv "bar" nil)`},
{[]string{"baz", "bar"}, EnvConfig{"none"}, `baz bar`},
{[]string{"baz", "bar"}, EnvConfig{"none"}, "baz\nbar"},
}
for _, tc := range testCases {
tc := tc