Skip to content

Commit

Permalink
Merge pull request NixOS#87253 from utdemir/dockertools-preserve-env
Browse files Browse the repository at this point in the history
Preserve environment variables from the parent image on dockerTools.buildImage
  • Loading branch information
nlewo committed May 15, 2020
2 parents c956b59 + f5a90a7 commit 98a723e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
10 changes: 10 additions & 0 deletions nixos/tests/docker-tools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ import ./make-test-python.nix ({ pkgs, ... }: {
f"docker run --rm ${examples.layersOrder.imageName} cat /tmp/layer{index}"
)
with subtest("Ensure environment variables are correctly inherited"):
docker.succeed(
"docker load --input='${examples.environmentVariables}'"
)
out = docker.succeed("docker run --rm ${examples.environmentVariables.imageName} env")
env = out.splitlines()
assert "FROM_PARENT=true" in env, "envvars from the parent should be preserved"
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 image with only 2 layers can be loaded"):
docker.succeed(
"docker load --input='${examples.two-layered-image}'"
Expand Down
9 changes: 7 additions & 2 deletions pkgs/build-support/docker/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -773,13 +773,17 @@ rec {
mkdir image
touch baseFiles
baseEnvs='[]'
if [[ -n "$fromImage" ]]; then
echo "Unpacking base image..."
tar -C image -xpf "$fromImage"
# Store the layers and the environment variables from the base image
cat ./image/manifest.json | jq -r '.[0].Layers | .[]' > layer-list
configName="$(cat ./image/manifest.json | jq -r '.[0].Config')"
baseEnvs="$(cat "./image/$configName" | jq '.config.Env // []')"
# Do not import the base image configuration and manifest
# Otherwise do not import the base image configuration and manifest
chmod a+w image image/*.json
rm -f image/*.json
Expand Down Expand Up @@ -859,7 +863,8 @@ rec {
) | sponge layer-list
# Create image json and image manifest
imageJson=$(cat ${baseJson} | jq ". + {\"rootfs\": {\"diff_ids\": [], \"type\": \"layers\"}}")
imageJson=$(cat ${baseJson} | jq '.config.Env = $baseenv + .config.Env' --argjson baseenv "$baseEnvs")
imageJson=$(echo "$imageJson" | jq ". + {\"rootfs\": {\"diff_ids\": [], \"type\": \"layers\"}}")
manifestJson=$(jq -n "[{\"RepoTags\":[\"$imageName:$imageTag\"]}]")
for layerTar in $(cat ./layer-list); do
Expand Down
35 changes: 31 additions & 4 deletions pkgs/build-support/docker/examples.nix
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,41 @@ rec {
'';
};

# 14. Create another layered image, for comparing layers with image 10.
# 14. Environment variable inheritance.
# Child image should inherit parents environment variables,
# optionally overriding them.
environmentVariables = let
parent = pkgs.dockerTools.buildImage {
name = "parent";
tag = "latest";
config = {
Env = [
"FROM_PARENT=true"
"LAST_LAYER=parent"
];
};
};
in pkgs.dockerTools.buildImage {
name = "child";
fromImage = parent;
tag = "latest";
contents = [ pkgs.coreutils ];
config = {
Env = [
"FROM_CHILD=true"
"LAST_LAYER=child"
];
};
};

# 15. Create another layered image, for comparing layers with image 10.
another-layered-image = pkgs.dockerTools.buildLayeredImage {
name = "another-layered-image";
tag = "latest";
config.Cmd = [ "${pkgs.hello}/bin/hello" ];
};

# 15. Create a layered image with only 2 layers
# 16. Create a layered image with only 2 layers
two-layered-image = pkgs.dockerTools.buildLayeredImage {
name = "two-layered-image";
tag = "latest";
Expand All @@ -247,7 +274,7 @@ rec {
maxLayers = 2;
};

# 16. Create a layered image with more packages than max layers.
# 17. Create a layered image with more packages than max layers.
# coreutils and hello are part of the same layer
bulk-layer = pkgs.dockerTools.buildLayeredImage {
name = "bulk-layer";
Expand All @@ -258,7 +285,7 @@ rec {
maxLayers = 2;
};

# 17. Create a "layered" image without nix store layers. This is not
# 18. Create a "layered" image without nix store layers. This is not
# recommended, but can be useful for base images in rare cases.
no-store-paths = pkgs.dockerTools.buildLayeredImage {
name = "no-store-paths";
Expand Down

0 comments on commit 98a723e

Please sign in to comment.