Merge pull request #10145 from duglin/Issue10141
Docker run -e FOO should erase FOO if FOO isn't set in client env
This commit is contained in:
commit
edaf23b7a7
4 changed files with 106 additions and 7 deletions
|
@ -1736,9 +1736,12 @@ ports in Docker.
|
||||||
|
|
||||||
This sets environmental variables in the container. For illustration all three
|
This sets environmental variables in the container. For illustration all three
|
||||||
flags are shown here. Where `-e`, `--env` take an environment variable and
|
flags are shown here. Where `-e`, `--env` take an environment variable and
|
||||||
value, or if no "=" is provided, then that variable's current value is passed
|
value, or if no `=` is provided, then that variable's current value is passed
|
||||||
through (i.e. `$MYVAR1` from the host is set to `$MYVAR1` in the container). All
|
through (i.e. `$MYVAR1` from the host is set to `$MYVAR1` in the container).
|
||||||
three flags, `-e`, `--env` and `--env-file` can be repeated.
|
When no `=` is provided and that variable is not defined in the client's
|
||||||
|
environment then that variable will be removed from the container's list of
|
||||||
|
environment variables.
|
||||||
|
All three flags, `-e`, `--env` and `--env-file` can be repeated.
|
||||||
|
|
||||||
Regardless of the order of these three flags, the `--env-file` are processed
|
Regardless of the order of these three flags, the `--env-file` are processed
|
||||||
first, and then `-e`, `--env` flags. This way, the `-e` or `--env` will
|
first, and then `-e`, `--env` flags. This way, the `-e` or `--env` will
|
||||||
|
|
|
@ -792,10 +792,7 @@ func TestRunEnvironment(t *testing.T) {
|
||||||
t.Fatal(err, out)
|
t.Fatal(err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
actualEnv := strings.Split(out, "\n")
|
actualEnv := strings.Split(strings.TrimSpace(out), "\n")
|
||||||
if actualEnv[len(actualEnv)-1] == "" {
|
|
||||||
actualEnv = actualEnv[:len(actualEnv)-1]
|
|
||||||
}
|
|
||||||
sort.Strings(actualEnv)
|
sort.Strings(actualEnv)
|
||||||
|
|
||||||
goodEnv := []string{
|
goodEnv := []string{
|
||||||
|
@ -823,6 +820,72 @@ func TestRunEnvironment(t *testing.T) {
|
||||||
logDone("run - verify environment")
|
logDone("run - verify environment")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunEnvironmentErase(t *testing.T) {
|
||||||
|
// Test to make sure that when we use -e on env vars that are
|
||||||
|
// not set in our local env that they're removed (if present) in
|
||||||
|
// the container
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env")
|
||||||
|
cmd.Env = []string{}
|
||||||
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualEnv := strings.Split(strings.TrimSpace(out), "\n")
|
||||||
|
sort.Strings(actualEnv)
|
||||||
|
|
||||||
|
goodEnv := []string{
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root",
|
||||||
|
}
|
||||||
|
sort.Strings(goodEnv)
|
||||||
|
if len(goodEnv) != len(actualEnv) {
|
||||||
|
t.Fatalf("Wrong environment: should be %d variables, not: %q\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
||||||
|
}
|
||||||
|
for i := range goodEnv {
|
||||||
|
if actualEnv[i] != goodEnv[i] {
|
||||||
|
t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAllContainers()
|
||||||
|
|
||||||
|
logDone("run - verify environment erase")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunEnvironmentOverride(t *testing.T) {
|
||||||
|
// Test to make sure that when we use -e on env vars that are
|
||||||
|
// already in the env that we're overriding them
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env")
|
||||||
|
cmd.Env = []string{"HOSTNAME=bar"}
|
||||||
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualEnv := strings.Split(strings.TrimSpace(out), "\n")
|
||||||
|
sort.Strings(actualEnv)
|
||||||
|
|
||||||
|
goodEnv := []string{
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOME=/root2",
|
||||||
|
"HOSTNAME=bar",
|
||||||
|
}
|
||||||
|
sort.Strings(goodEnv)
|
||||||
|
if len(goodEnv) != len(actualEnv) {
|
||||||
|
t.Fatalf("Wrong environment: should be %d variables, not: %q\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
||||||
|
}
|
||||||
|
for i := range goodEnv {
|
||||||
|
if actualEnv[i] != goodEnv[i] {
|
||||||
|
t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAllContainers()
|
||||||
|
|
||||||
|
logDone("run - verify environment override")
|
||||||
|
}
|
||||||
|
|
||||||
func TestRunContainerNetwork(t *testing.T) {
|
func TestRunContainerNetwork(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "busybox", "ping", "-c", "1", "127.0.0.1")
|
cmd := exec.Command(dockerBinary, "run", "busybox", "ping", "-c", "1", "127.0.0.1")
|
||||||
if _, err := runCommand(cmd); err != nil {
|
if _, err := runCommand(cmd); err != nil {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -168,6 +169,9 @@ func ValidateEnv(val string) (string, error) {
|
||||||
if len(arr) > 1 {
|
if len(arr) > 1 {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
if !utils.DoesEnvExist(val) {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
|
return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,7 +401,17 @@ func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
|
||||||
parts := strings.SplitN(e, "=", 2)
|
parts := strings.SplitN(e, "=", 2)
|
||||||
cache[parts[0]] = i
|
cache[parts[0]] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, value := range overrides {
|
for _, value := range overrides {
|
||||||
|
// Values w/o = means they want this env to be removed/unset.
|
||||||
|
if !strings.Contains(value, "=") {
|
||||||
|
if i, exists := cache[value]; exists {
|
||||||
|
defaults[i] = "" // Used to indicate it should be removed
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just do a normal set/update
|
||||||
parts := strings.SplitN(value, "=", 2)
|
parts := strings.SplitN(value, "=", 2)
|
||||||
if i, exists := cache[parts[0]]; exists {
|
if i, exists := cache[parts[0]]; exists {
|
||||||
defaults[i] = value
|
defaults[i] = value
|
||||||
|
@ -409,9 +419,28 @@ func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
|
||||||
defaults = append(defaults, value)
|
defaults = append(defaults, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now remove all entries that we want to "unset"
|
||||||
|
for i := 0; i < len(defaults); i++ {
|
||||||
|
if defaults[i] == "" {
|
||||||
|
defaults = append(defaults[:i], defaults[i+1:]...)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return defaults
|
return defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DoesEnvExist(name string) bool {
|
||||||
|
for _, entry := range os.Environ() {
|
||||||
|
parts := strings.SplitN(entry, "=", 2)
|
||||||
|
if parts[0] == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ReadSymlinkedDirectory returns the target directory of a symlink.
|
// ReadSymlinkedDirectory returns the target directory of a symlink.
|
||||||
// The target of the symbolic link may not be a file.
|
// The target of the symbolic link may not be a file.
|
||||||
func ReadSymlinkedDirectory(path string) (string, error) {
|
func ReadSymlinkedDirectory(path string) (string, error) {
|
||||||
|
|
Loading…
Reference in a new issue