compose: fix environment interpolation from the client#30781
compose: fix environment interpolation from the client#30781vdemeester merged 3 commits intomoby:masterfrom
Conversation
|
cc @dnephin |
975f9e4 to
9e92823
Compare
dnephin
left a comment
There was a problem hiding this comment.
This looks great, thanks!
Just a couple small issues
| home, ok := lookupEnv("HOME") | ||
| if !ok { | ||
| panic(errors.New("cannot expand '~', because the environment lacks HOME")) | ||
| } |
There was a problem hiding this comment.
I don't think this should be a panic. At most a warning.
There was a problem hiding this comment.
@dnephin What should we do with warning?
Keep unparsed '~' as-is? Or Ignore the entry?
There was a problem hiding this comment.
Keep it as-is with the ~ I think
| @@ -358,10 +363,18 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string) e | |||
|
|
|||
| serviceConfig.Environment = environment | |||
There was a problem hiding this comment.
nit: To be consistent I think this line should be at the end of the function, right before return nil
cli/compose/loader/loader.go
Outdated
|
|
||
| // env is prioritized over the file | ||
| for k := range serviceConfig.Environment { | ||
| v, ok := lookupEnv(k) |
There was a problem hiding this comment.
I think this is missing a check to see if v == "". If v is not the empty string we should not override from the client environment.
cli/command/stack/deploy.go
Outdated
| env := os.Environ() | ||
| details.Environment = make(map[string]string, len(env)) | ||
| for _, s := range env { | ||
| // if value is empty, s is like "K=", not "K". |
There was a problem hiding this comment.
This is probably a reasonable assumption, but it couldn't hurt to check.
9e92823 to
3852fbc
Compare
|
@dnephin @aaronlehmann Now this PR is much more compatible with Docker Compose, but maybe breaking compatibility with Docker Swarm-mode 1.13.1. (Please refer to changes in UT) cc @shin- |
cli/compose/loader/loader.go
Outdated
| if ok { | ||
| environment[k] = interpolatedV | ||
| } else { | ||
| delete(environment, k) |
There was a problem hiding this comment.
I don't think you ever want to delete things from the environment. What's this about?
There was a problem hiding this comment.
If the environment variable is specified to be interpolated in the YAML but its value is unset in the actual environment, it should be deleted (in Docker Compose's implementation).
Please refer to the example table listed in the description text of this PR.
There was a problem hiding this comment.
I don't think it's actually deleted. I don't see that in the Compose code anywhere. I think that's handled by the server when starting a container. It creates the variable unset.
There was a problem hiding this comment.
Yes, you are right, I didn't know that 😅
Opened #31634 for clarifying this behavior in the doc.
I'll update this PR as well in short.
cli/compose/loader/loader.go
Outdated
| environment[k] = interpolatedV | ||
| } else { | ||
| environment[k] = v | ||
| } |
There was a problem hiding this comment.
Here's the logic from Compose: https://github.com/docker/compose/blob/master/compose/config/config.py#L589-L598
I think we can reduce the size of this function quite a bit by matching the logic.
Once delete() is removed from below, i think these blocks will be nearly identical. So we could have a function like this:
func updateEnvironment(environment, map[string]string, vars map[string]string, lookupEnv template.Mapping) map[string[string {
...
}
environment = updateEnvironment(environment, runconfigopts.ConvertKVStringsToMap(envVars), lookupEnv)
serviceConfig.Environment = updateEnvironment(environment, serviceConfig.Environment, lookupEnv)
return nilThere was a problem hiding this comment.
Thank you for the pointer, I'll look into that.
|
Ping, any update here? |
3852fbc to
444a243
Compare
|
updated PR, sorry for delay |
|
oops, still something is wrong... (expected: |
|
trying to fix the issue 👆 by defining |
For an environment variable defined in the yaml without value, the value needs to be propagated from the client, as in Docker Compose. Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Load from env should only happen if the value is unset. Extract a buildEnvironment function and revert some changes to tests. Signed-off-by: Daniel Nephin <dnephin@docker.com>
|
I've rebased this PR, and fixed the remaining issue with empty values. |
|
@dnephin Thank you a lot 😃 |
cli/compose/types/types.go
Outdated
| @@ -135,7 +135,10 @@ type StringOrNumberList []string | |||
|
|
|||
| // MappingWithEquals is a mapping type that can be converted from a list of | |||
| // key=value strings | |||
There was a problem hiding this comment.
// MappingWithEquals is a mapping type that can be converted from a list of
// key[=value] strings.
// For the key with an empty value (`key=`), the mapped value is set to a pointer to `""`.
// For the key without value (`key`), the mapped value is set to nil.Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
|
LGTM for @dnephin 's work 😃 |
|
I think it's a bug fix |
|
ping @AkihiroSuda could you prepare a cherry-pick for this? |
|
sure, opened #32033 |
compose: fix environment interpolation from the client
|
When is this slated to be released? |
|
This has been released quite a while ago already |
|
Docker 17.04 and up should have this change |
- What I did
Fix (newly support?) environment interpolation from the client
e.g.
- How I did it
Please refer to the code.
- How to verify it
Prepare following files:
docker-compose.yaml:a.env:on Docker Compose:
$ FOO=foo_from_env QUUX=quux_from_env docker-compose upon Docker Swarm-mode:
Result:
FOOBARBAZQUXQUUXSwarm-mode with this PR
"foo_from_env""")"baz_from_file""")"quux_from_yaml""""""baz_from_file""""quux_from_yaml"ForBAR, I wonder Compose's result (unset) is unexpected and should be"", but not sure. (Could not find any doc 😅)- Description for the changelog
compose: support environment interpolation from the client
- A picture of a cute animal (not mandatory but encouraged)
Signed-off-by: Akihiro Suda suda.akihiro@lab.ntt.co.jp