dockerTools.streamLayeredImage: resolve duplicate env vars
For images running on Kubernetes, there is no guarantee on how duplicate environment variables in the image config will be handled. This seems to be different from Docker, where the last environment variable value is consistently selected. The current code for `streamLayeredImage` was exploiting that assumption to easily propagate environment variables from the base image, leaving duplicates unchecked. It should rather resolve these duplicates to ensure consistent behavior on Docker and Kubernetes.
This commit is contained in:
parent
06733bcf29
commit
b3f68289df
2 changed files with 18 additions and 1 deletions
|
@ -221,6 +221,21 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
|||
assert "FROM_CHILD=true" in env, "envvars from the child should be preserved"
|
||||
assert "LAST_LAYER=child" in env, "envvars from the child should take priority"
|
||||
|
||||
with subtest(
|
||||
"Ensure inherited environment variables of layered images are correctly resolved"
|
||||
):
|
||||
# Read environment variables as stored in image config
|
||||
config = docker.succeed(
|
||||
"tar -xOf ${examples.environmentVariablesLayered} manifest.json | ${pkgs.jq}/bin/jq -r .[].Config"
|
||||
).strip()
|
||||
out = docker.succeed(
|
||||
f"tar -xOf ${examples.environmentVariablesLayered} {config} | ${pkgs.jq}/bin/jq -r '.config.Env | .[]'"
|
||||
)
|
||||
env = out.splitlines()
|
||||
assert (
|
||||
sum(entry.startswith("LAST_LAYER") for entry in env) == 1
|
||||
), "envvars overridden by child should be unique"
|
||||
|
||||
with subtest("Ensure image with only 2 layers can be loaded"):
|
||||
docker.succeed(
|
||||
"docker load --input='${examples.two-layered-image}'"
|
||||
|
|
|
@ -202,7 +202,9 @@ def overlay_base_config(from_image, final_config):
|
|||
# Preserve environment from base image
|
||||
final_env = base_config.get("Env", []) + final_config.get("Env", [])
|
||||
if final_env:
|
||||
final_config["Env"] = final_env
|
||||
# Resolve duplicates (last one wins) and format back as list
|
||||
resolved_env = {entry.split("=", 1)[0]: entry for entry in final_env}
|
||||
final_config["Env"] = list(resolved_env.values())
|
||||
return final_config
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue