mirror of https://github.com/docker/docs.git
Merge pull request #2250 from jeanlaurent/2204-broken-env-unset
Fix for docker-machine env unset
This commit is contained in:
commit
34cd4fd898
139
commands/env.go
139
commands/env.go
|
@ -17,7 +17,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errImproperEnvArgs = errors.New("Error: Expected either one machine name, or -u flag to unset the variables in the arguments")
|
errImproperEnvArgs = errors.New("Error: Expected one machine name")
|
||||||
|
errImproperUnsetEnvArgs = errors.New("Error: Expected no machine name when the -u flag is present")
|
||||||
)
|
)
|
||||||
|
|
||||||
type ShellConfig struct {
|
type ShellConfig struct {
|
||||||
|
@ -38,7 +39,14 @@ func cmdEnv(c CommandLine) error {
|
||||||
// being run (it is intended to be run in a subshell)
|
// being run (it is intended to be run in a subshell)
|
||||||
log.SetOutWriter(os.Stderr)
|
log.SetOutWriter(os.Stderr)
|
||||||
|
|
||||||
if len(c.Args()) != 1 && !c.Bool("unset") {
|
if c.Bool("unset") {
|
||||||
|
return unset(c)
|
||||||
|
}
|
||||||
|
return set(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(c CommandLine) error {
|
||||||
|
if len(c.Args()) != 1 {
|
||||||
return errImproperEnvArgs
|
return errImproperEnvArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,24 +60,16 @@ func cmdEnv(c CommandLine) error {
|
||||||
return fmt.Errorf("Error running connection boilerplate: %s", err)
|
return fmt.Errorf("Error running connection boilerplate: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userShell := c.String("shell")
|
userShell, err := getShell(c)
|
||||||
if userShell == "" {
|
if err != nil {
|
||||||
shell, err := detectShell()
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
userShell = shell
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t := template.New("envConfig")
|
|
||||||
|
|
||||||
usageHint := generateUsageHint(userShell, os.Args)
|
|
||||||
|
|
||||||
shellCfg := &ShellConfig{
|
shellCfg := &ShellConfig{
|
||||||
DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), host.Name),
|
DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), host.Name),
|
||||||
DockerHost: dockerHost,
|
DockerHost: dockerHost,
|
||||||
DockerTLSVerify: "1",
|
DockerTLSVerify: "1",
|
||||||
UsageHint: usageHint,
|
UsageHint: generateUsageHint(userShell, os.Args),
|
||||||
MachineName: host.Name,
|
MachineName: host.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,22 +79,14 @@ func cmdEnv(c CommandLine) error {
|
||||||
return fmt.Errorf("Error getting host IP: %s", err)
|
return fmt.Errorf("Error getting host IP: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// first check for an existing lower case no_proxy var
|
noProxyVar, noProxyValue := findNoProxyFromEnv()
|
||||||
noProxyVar := "no_proxy"
|
|
||||||
noProxyValue := os.Getenv("no_proxy")
|
|
||||||
|
|
||||||
// otherwise default to allcaps HTTP_PROXY
|
|
||||||
if noProxyValue == "" {
|
|
||||||
noProxyVar = "NO_PROXY"
|
|
||||||
noProxyValue = os.Getenv("NO_PROXY")
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the docker host to the no_proxy list idempotently
|
// add the docker host to the no_proxy list idempotently
|
||||||
switch {
|
switch {
|
||||||
case noProxyValue == "":
|
case noProxyValue == "":
|
||||||
noProxyValue = ip
|
noProxyValue = ip
|
||||||
case strings.Contains(noProxyValue, ip):
|
case strings.Contains(noProxyValue, ip):
|
||||||
//ip already in no_proxy list, nothing to do
|
//ip already in no_proxy list, nothing to do
|
||||||
default:
|
default:
|
||||||
noProxyValue = fmt.Sprintf("%s,%s", noProxyValue, ip)
|
noProxyValue = fmt.Sprintf("%s,%s", noProxyValue, ip)
|
||||||
}
|
}
|
||||||
|
@ -103,39 +95,6 @@ func cmdEnv(c CommandLine) error {
|
||||||
shellCfg.NoProxyValue = noProxyValue
|
shellCfg.NoProxyValue = noProxyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// unset vars
|
|
||||||
if c.Bool("unset") {
|
|
||||||
switch userShell {
|
|
||||||
case "fish":
|
|
||||||
shellCfg.Prefix = "set -e "
|
|
||||||
shellCfg.Delimiter = ""
|
|
||||||
shellCfg.Suffix = ";\n"
|
|
||||||
case "powershell":
|
|
||||||
shellCfg.Prefix = "Remove-Item Env:\\\\"
|
|
||||||
shellCfg.Delimiter = ""
|
|
||||||
shellCfg.Suffix = "\n"
|
|
||||||
case "cmd":
|
|
||||||
// since there is no way to unset vars in cmd just reset to empty
|
|
||||||
shellCfg.DockerCertPath = ""
|
|
||||||
shellCfg.DockerHost = ""
|
|
||||||
shellCfg.DockerTLSVerify = ""
|
|
||||||
shellCfg.Prefix = "set "
|
|
||||||
shellCfg.Delimiter = "="
|
|
||||||
shellCfg.Suffix = "\n"
|
|
||||||
default:
|
|
||||||
shellCfg.Prefix = "unset "
|
|
||||||
shellCfg.Delimiter = " "
|
|
||||||
shellCfg.Suffix = "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpl, err := t.Parse(envTmpl)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpl.Execute(os.Stdout, shellCfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch userShell {
|
switch userShell {
|
||||||
case "fish":
|
case "fish":
|
||||||
shellCfg.Prefix = "set -x "
|
shellCfg.Prefix = "set -x "
|
||||||
|
@ -155,6 +114,51 @@ func cmdEnv(c CommandLine) error {
|
||||||
shellCfg.Delimiter = "=\""
|
shellCfg.Delimiter = "=\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return executeTemplateStdout(shellCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unset(c CommandLine) error {
|
||||||
|
if len(c.Args()) != 0 {
|
||||||
|
return errImproperUnsetEnvArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
userShell, err := getShell(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shellCfg := &ShellConfig{
|
||||||
|
UsageHint: generateUsageHint(userShell, os.Args),
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Bool("no-proxy") {
|
||||||
|
shellCfg.NoProxyVar, shellCfg.NoProxyValue = findNoProxyFromEnv()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch userShell {
|
||||||
|
case "fish":
|
||||||
|
shellCfg.Prefix = "set -e "
|
||||||
|
shellCfg.Suffix = ";\n"
|
||||||
|
shellCfg.Delimiter = ""
|
||||||
|
case "powershell":
|
||||||
|
shellCfg.Prefix = `Remove-Item Env:\\`
|
||||||
|
shellCfg.Suffix = "\n"
|
||||||
|
shellCfg.Delimiter = ""
|
||||||
|
case "cmd":
|
||||||
|
shellCfg.Prefix = "SET "
|
||||||
|
shellCfg.Suffix = "\n"
|
||||||
|
shellCfg.Delimiter = "="
|
||||||
|
default:
|
||||||
|
shellCfg.Prefix = "unset "
|
||||||
|
shellCfg.Suffix = "\n"
|
||||||
|
shellCfg.Delimiter = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return executeTemplateStdout(shellCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeTemplateStdout(shellCfg *ShellConfig) error {
|
||||||
|
t := template.New("envConfig")
|
||||||
tmpl, err := t.Parse(envTmpl)
|
tmpl, err := t.Parse(envTmpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -163,6 +167,27 @@ func cmdEnv(c CommandLine) error {
|
||||||
return tmpl.Execute(os.Stdout, shellCfg)
|
return tmpl.Execute(os.Stdout, shellCfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getShell(c CommandLine) (string, error) {
|
||||||
|
userShell := c.String("shell")
|
||||||
|
if userShell != "" {
|
||||||
|
return userShell, nil
|
||||||
|
}
|
||||||
|
return detectShell()
|
||||||
|
}
|
||||||
|
|
||||||
|
func findNoProxyFromEnv() (string, string) {
|
||||||
|
// first check for an existing lower case no_proxy var
|
||||||
|
noProxyVar := "no_proxy"
|
||||||
|
noProxyValue := os.Getenv("no_proxy")
|
||||||
|
|
||||||
|
// otherwise default to allcaps HTTP_PROXY
|
||||||
|
if noProxyValue == "" {
|
||||||
|
noProxyVar = "NO_PROXY"
|
||||||
|
noProxyValue = os.Getenv("NO_PROXY")
|
||||||
|
}
|
||||||
|
return noProxyVar, noProxyValue
|
||||||
|
}
|
||||||
|
|
||||||
func generateUsageHint(userShell string, args []string) string {
|
func generateUsageHint(userShell string, args []string) string {
|
||||||
cmd := ""
|
cmd := ""
|
||||||
comment := "#"
|
comment := "#"
|
||||||
|
|
|
@ -18,21 +18,25 @@ func TestHints(t *testing.T) {
|
||||||
{"", "machine env --no-proxy default", "# Run this command to configure your shell: \n# eval \"$(machine env --no-proxy default)\"\n"},
|
{"", "machine env --no-proxy default", "# Run this command to configure your shell: \n# eval \"$(machine env --no-proxy default)\"\n"},
|
||||||
{"", "machine env --swarm default", "# Run this command to configure your shell: \n# eval \"$(machine env --swarm default)\"\n"},
|
{"", "machine env --swarm default", "# Run this command to configure your shell: \n# eval \"$(machine env --swarm default)\"\n"},
|
||||||
{"", "machine env --no-proxy --swarm default", "# Run this command to configure your shell: \n# eval \"$(machine env --no-proxy --swarm default)\"\n"},
|
{"", "machine env --no-proxy --swarm default", "# Run this command to configure your shell: \n# eval \"$(machine env --no-proxy --swarm default)\"\n"},
|
||||||
|
{"", "machine env --unset", "# Run this command to configure your shell: \n# eval \"$(machine env --unset)\"\n"},
|
||||||
|
|
||||||
{"fish", "./machine env --shell=fish default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish default)\n"},
|
{"fish", "./machine env --shell=fish default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish default)\n"},
|
||||||
{"fish", "./machine env --shell=fish --no-proxy default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy default)\n"},
|
{"fish", "./machine env --shell=fish --no-proxy default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy default)\n"},
|
||||||
{"fish", "./machine env --shell=fish --swarm default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --swarm default)\n"},
|
{"fish", "./machine env --shell=fish --swarm default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --swarm default)\n"},
|
||||||
{"fish", "./machine env --shell=fish --no-proxy --swarm default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy --swarm default)\n"},
|
{"fish", "./machine env --shell=fish --no-proxy --swarm default", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --no-proxy --swarm default)\n"},
|
||||||
|
{"fish", "./machine env --shell=fish --unset", "# Run this command to configure your shell: \n# eval (./machine env --shell=fish --unset)\n"},
|
||||||
|
|
||||||
{"powershell", "./machine env --shell=powershell default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell default | Invoke-Expression\n"},
|
{"powershell", "./machine env --shell=powershell default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell default | Invoke-Expression\n"},
|
||||||
{"powershell", "./machine env --shell=powershell --no-proxy default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --no-proxy default | Invoke-Expression\n"},
|
{"powershell", "./machine env --shell=powershell --no-proxy default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --no-proxy default | Invoke-Expression\n"},
|
||||||
{"powershell", "./machine env --shell=powershell --swarm default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --swarm default | Invoke-Expression\n"},
|
{"powershell", "./machine env --shell=powershell --swarm default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --swarm default | Invoke-Expression\n"},
|
||||||
{"powershell", "./machine env --shell=powershell --no-proxy --swarm default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --no-proxy --swarm default | Invoke-Expression\n"},
|
{"powershell", "./machine env --shell=powershell --no-proxy --swarm default", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --no-proxy --swarm default | Invoke-Expression\n"},
|
||||||
|
{"powershell", "./machine env --shell=powershell --unset", "# Run this command to configure your shell: \n# ./machine env --shell=powershell --unset | Invoke-Expression\n"},
|
||||||
|
|
||||||
{"cmd", "./machine env --shell=cmd default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd default') DO %i\n"},
|
{"cmd", "./machine env --shell=cmd default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd default') DO %i\n"},
|
||||||
{"cmd", "./machine env --shell=cmd --no-proxy default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy default') DO %i\n"},
|
{"cmd", "./machine env --shell=cmd --no-proxy default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy default') DO %i\n"},
|
||||||
{"cmd", "./machine env --shell=cmd --swarm default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --swarm default') DO %i\n"},
|
{"cmd", "./machine env --shell=cmd --swarm default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --swarm default') DO %i\n"},
|
||||||
{"cmd", "./machine env --shell=cmd --no-proxy --swarm default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy --swarm default') DO %i\n"},
|
{"cmd", "./machine env --shell=cmd --no-proxy --swarm default", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --no-proxy --swarm default') DO %i\n"},
|
||||||
|
{"cmd", "./machine env --shell=cmd --unset", "REM Run this command to configure your shell: \nREM \tFOR /f \"tokens=*\" %i IN ('./machine env --shell=cmd --unset') DO %i\n"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
|
@ -3,8 +3,9 @@ package drivers
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIP(t *testing.T) {
|
func TestIP(t *testing.T) {
|
||||||
|
|
|
@ -7,6 +7,14 @@ load ${BASE_TEST_DIR}/helpers.bash
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: test basic bash / zsh notation" {
|
||||||
|
run machine env $NAME
|
||||||
|
[[ ${lines[0]} == "export DOCKER_TLS_VERIFY=\"1\"" ]]
|
||||||
|
[[ ${lines[1]} == "export DOCKER_HOST=\"$(machine url $NAME)\"" ]]
|
||||||
|
[[ ${lines[2]} == "export DOCKER_CERT_PATH=\"$MACHINE_STORAGE_PATH/machines/$NAME\"" ]]
|
||||||
|
[[ ${lines[3]} == "export DOCKER_MACHINE_NAME=\"$NAME\"" ]]
|
||||||
|
}
|
||||||
|
|
||||||
@test "$DRIVER: test powershell notation" {
|
@test "$DRIVER: test powershell notation" {
|
||||||
run machine env --shell powershell --no-proxy $NAME
|
run machine env --shell powershell --no-proxy $NAME
|
||||||
[[ ${lines[0]} == "\$Env:DOCKER_TLS_VERIFY = \"1\"" ]]
|
[[ ${lines[0]} == "\$Env:DOCKER_TLS_VERIFY = \"1\"" ]]
|
||||||
|
@ -16,7 +24,7 @@ load ${BASE_TEST_DIR}/helpers.bash
|
||||||
[[ ${lines[4]} == "\$Env:NO_PROXY = \"$(machine ip $NAME)\"" ]]
|
[[ ${lines[4]} == "\$Env:NO_PROXY = \"$(machine ip $NAME)\"" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "$DRIVER: test bash / zsh notation" {
|
@test "$DRIVER: test bash / zsh notation with no-proxy" {
|
||||||
run machine env --no-proxy $NAME
|
run machine env --no-proxy $NAME
|
||||||
[[ ${lines[0]} == "export DOCKER_TLS_VERIFY=\"1\"" ]]
|
[[ ${lines[0]} == "export DOCKER_TLS_VERIFY=\"1\"" ]]
|
||||||
[[ ${lines[1]} == "export DOCKER_HOST=\"$(machine url $NAME)\"" ]]
|
[[ ${lines[1]} == "export DOCKER_HOST=\"$(machine url $NAME)\"" ]]
|
||||||
|
@ -43,8 +51,56 @@ load ${BASE_TEST_DIR}/helpers.bash
|
||||||
[[ ${lines[4]} == "set -x NO_PROXY \"$(machine ip $NAME)\";" ]]
|
[[ ${lines[4]} == "set -x NO_PROXY \"$(machine ip $NAME)\";" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "$DRIVER: no proxy with NO_PROXY already set" {
|
@test "$DRIVER: test no proxy with NO_PROXY already set" {
|
||||||
export NO_PROXY=localhost
|
export NO_PROXY=localhost
|
||||||
run machine env --no-proxy $NAME
|
run machine env --no-proxy $NAME
|
||||||
[[ ${lines[4]} == "export NO_PROXY=\"localhost,$(machine ip $NAME)\"" ]]
|
[[ ${lines[4]} == "export NO_PROXY=\"localhost,$(machine ip $NAME)\"" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: test unset with an args should fail" {
|
||||||
|
run machine env -u $NAME
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ ${lines} == "Error: Expected no machine name when the -u flag is present" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@test "$DRIVER: test bash/zsh unset" {
|
||||||
|
run machine env -u
|
||||||
|
[[ ${lines[0]} == "unset DOCKER_TLS_VERIFY" ]]
|
||||||
|
[[ ${lines[1]} == "unset DOCKER_HOST" ]]
|
||||||
|
[[ ${lines[2]} == "unset DOCKER_CERT_PATH" ]]
|
||||||
|
[[ ${lines[3]} == "unset DOCKER_MACHINE_NAME" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: test unset killing no proxy" {
|
||||||
|
run machine env --no-proxy -u
|
||||||
|
[[ ${lines[0]} == "unset DOCKER_TLS_VERIFY" ]]
|
||||||
|
[[ ${lines[1]} == "unset DOCKER_HOST" ]]
|
||||||
|
[[ ${lines[2]} == "unset DOCKER_CERT_PATH" ]]
|
||||||
|
[[ ${lines[3]} == "unset DOCKER_MACHINE_NAME" ]]
|
||||||
|
[[ ${lines[4]} == "unset NO_PROXY" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: unset powershell" {
|
||||||
|
run machine env --shell powershell -u
|
||||||
|
[[ ${lines[0]} == 'Remove-Item Env:\\DOCKER_TLS_VERIFY' ]]
|
||||||
|
[[ ${lines[1]} == 'Remove-Item Env:\\DOCKER_HOST' ]]
|
||||||
|
[[ ${lines[2]} == 'Remove-Item Env:\\DOCKER_CERT_PATH' ]]
|
||||||
|
[[ ${lines[3]} == 'Remove-Item Env:\\DOCKER_MACHINE_NAME' ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: unset with fish shell" {
|
||||||
|
run machine env --shell fish -u
|
||||||
|
[[ ${lines[0]} == "set -e DOCKER_TLS_VERIFY;" ]]
|
||||||
|
[[ ${lines[1]} == "set -e DOCKER_HOST;" ]]
|
||||||
|
[[ ${lines[2]} == "set -e DOCKER_CERT_PATH;" ]]
|
||||||
|
[[ ${lines[3]} == "set -e DOCKER_MACHINE_NAME;" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "$DRIVER: unset with cmd shell" {
|
||||||
|
run machine env --shell cmd -u
|
||||||
|
[[ ${lines[0]} == "SET DOCKER_TLS_VERIFY=" ]]
|
||||||
|
[[ ${lines[1]} == "SET DOCKER_HOST=" ]]
|
||||||
|
[[ ${lines[2]} == "SET DOCKER_CERT_PATH=" ]]
|
||||||
|
[[ ${lines[3]} == "SET DOCKER_MACHINE_NAME=" ]]
|
||||||
|
}
|
Loading…
Reference in New Issue