| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  | # this test creates a simple GNU image with docker tools and sees if it executes | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  | import ./make-test-python.nix ({ pkgs, ... }: { | 
					
						
							| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  |   name = "docker-tools"; | 
					
						
							| 
									
										
										
										
											2021-01-10 20:08:30 +01:00
										 |  |  |   meta = with pkgs.lib.maintainers; { | 
					
						
							| 
									
										
										
										
											2018-04-14 13:41:23 +02:00
										 |  |  |     maintainers = [ lnl7 ]; | 
					
						
							| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nodes = { | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     docker = { ... }: { | 
					
						
							|  |  |  |       virtualisation = { | 
					
						
							|  |  |  |         diskSize = 2048; | 
					
						
							|  |  |  |         docker.enable = true; | 
					
						
							| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |   testScript = with pkgs.dockerTools; ''
 | 
					
						
							|  |  |  |     unix_time_second1 = "1970-01-01T00:00:01Z" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 15:53:43 +02:00
										 |  |  |     docker.wait_for_unit("sockets.target") | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure Docker images use a stable date by default"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.bash}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         assert unix_time_second1 in docker.succeed( | 
					
						
							|  |  |  |             "docker inspect ${examples.bash.imageName} " | 
					
						
							|  |  |  |             + "| ${pkgs.jq}/bin/jq -r .[].Created", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     docker.succeed("docker run --rm ${examples.bash.imageName} bash --version") | 
					
						
							| 
									
										
										
										
											2020-07-11 15:51:58 +02:00
										 |  |  |     # Check imageTag attribute matches image | 
					
						
							|  |  |  |     docker.succeed("docker images --format '{{.Tag}}' | grep -F '${examples.bash.imageTag}'") | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     docker.succeed("docker rmi ${examples.bash.imageName}") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-11 15:51:58 +02:00
										 |  |  |     # The remaining combinations | 
					
						
							|  |  |  |     with subtest("Ensure imageTag attribute matches image"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.bashNoTag}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker images --format '{{.Tag}}' | grep -F '${examples.bashNoTag.imageTag}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed("docker rmi ${examples.bashNoTag.imageName}:${examples.bashNoTag.imageTag}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.bashNoTagLayered}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker images --format '{{.Tag}}' | grep -F '${examples.bashNoTagLayered.imageTag}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed("docker rmi ${examples.bashNoTagLayered.imageName}:${examples.bashNoTagLayered.imageTag}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "${examples.bashNoTagStreamLayered} | docker load" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker images --format '{{.Tag}}' | grep -F '${examples.bashNoTagStreamLayered.imageTag}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker rmi ${examples.bashNoTagStreamLayered.imageName}:${examples.bashNoTagStreamLayered.imageTag}" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nixLayered}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         docker.succeed("docker images --format '{{.Tag}}' | grep -F '${examples.nixLayered.imageTag}'") | 
					
						
							|  |  |  |         docker.succeed("docker rmi ${examples.nixLayered.imageName}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     with subtest( | 
					
						
							|  |  |  |         "Check if the nix store is correctly initialized by listing " | 
					
						
							|  |  |  |         "dependencies of the installed Nix binary" | 
					
						
							|  |  |  |     ): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nix}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.nix.imageName} nix-store -qR ${pkgs.nix}", | 
					
						
							|  |  |  |             "docker rmi ${examples.nix.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-30 17:18:41 +02:00
										 |  |  |     with subtest( | 
					
						
							|  |  |  |         "Ensure (layered) nix store has correct permissions " | 
					
						
							|  |  |  |         "and that the container starts when its process does not have uid 0" | 
					
						
							|  |  |  |     ): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.bashLayeredWithUser}'", | 
					
						
							|  |  |  |             "docker run -u somebody --rm ${examples.bashLayeredWithUser.imageName} ${pkgs.bash}/bin/bash -c 'test 555 == $(stat --format=%a /nix) && test 555 == $(stat --format=%a /nix/store)'", | 
					
						
							|  |  |  |             "docker rmi ${examples.bashLayeredWithUser.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-18 17:29:21 +02:00
										 |  |  |     with subtest("The nix binary symlinks are intact"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nix}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.nix.imageName} ${pkgs.bash}/bin/bash -c 'test nix == $(readlink ${pkgs.nix}/bin/nix-daemon)'", | 
					
						
							|  |  |  |             "docker rmi ${examples.nix.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("The nix binary symlinks are intact when the image is layered"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nixLayered}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.nixLayered.imageName} ${pkgs.bash}/bin/bash -c 'test nix == $(readlink ${pkgs.nix}/bin/nix-daemon)'", | 
					
						
							|  |  |  |             "docker rmi ${examples.nixLayered.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     with subtest("The pullImage tool works"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nixFromDockerHub}'", | 
					
						
							|  |  |  |             "docker run --rm nix:2.2.1 nix-store --version", | 
					
						
							|  |  |  |             "docker rmi nix:2.2.1", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("runAsRoot and entry point work"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.nginx}'", | 
					
						
							|  |  |  |             "docker run --name nginx -d -p 8000:80 ${examples.nginx.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-09-16 10:00:25 -07:00
										 |  |  |         docker.wait_until_succeeds("curl -f http://localhost:8000/") | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |         docker.succeed( | 
					
						
							| 
									
										
										
										
											2020-12-02 08:03:38 +01:00
										 |  |  |             "docker rm --force nginx", | 
					
						
							|  |  |  |             "docker rmi '${examples.nginx.imageName}'", | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("A pulled image can be used as base image"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.onTopOfPulledImage}'", | 
					
						
							|  |  |  |             "docker run --rm ontopofpulledimage hello", | 
					
						
							|  |  |  |             "docker rmi ontopofpulledimage", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Regression test for issue #34779"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.runAsRootExtraCommands}'", | 
					
						
							|  |  |  |             "docker run --rm runasrootextracommands cat extraCommands", | 
					
						
							|  |  |  |             "docker run --rm runasrootextracommands cat runAsRoot", | 
					
						
							|  |  |  |             "docker rmi '${examples.runAsRootExtraCommands.imageName}'", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure Docker images can use an unstable date"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							| 
									
										
										
										
											2020-07-09 09:34:18 +02:00
										 |  |  |             "docker load --input='${examples.unstableDate}'" | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         assert unix_time_second1 not in docker.succeed( | 
					
						
							|  |  |  |             "docker inspect ${examples.unstableDate.imageName} " | 
					
						
							|  |  |  |             + "| ${pkgs.jq}/bin/jq -r .[].Created" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-09 09:34:18 +02:00
										 |  |  |     with subtest("Ensure Layered Docker images can use an unstable date"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.unstableDateLayered}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         assert unix_time_second1 not in docker.succeed( | 
					
						
							|  |  |  |             "docker inspect ${examples.unstableDateLayered.imageName} " | 
					
						
							|  |  |  |             + "| ${pkgs.jq}/bin/jq -r .[].Created" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     with subtest("Ensure Layered Docker images work"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.layered-image}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.layered-image.imageName}", | 
					
						
							|  |  |  |             "docker run --rm ${examples.layered-image.imageName} cat extraCommands", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure building an image on top of a layered Docker images work"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.layered-on-top}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.layered-on-top.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_of_layers(image_name): | 
					
						
							|  |  |  |         return set( | 
					
						
							|  |  |  |             docker.succeed( | 
					
						
							|  |  |  |                 f"docker inspect {image_name} " | 
					
						
							|  |  |  |                 + "| ${pkgs.jq}/bin/jq -r '.[] | .RootFS.Layers | .[]'" | 
					
						
							|  |  |  |             ).split() | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure layers are shared between images"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.another-layered-image}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         layers1 = set_of_layers("${examples.layered-image.imageName}") | 
					
						
							|  |  |  |         layers2 = set_of_layers("${examples.another-layered-image.imageName}") | 
					
						
							|  |  |  |         assert bool(layers1 & layers2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure order of layers is correct"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.layersOrder}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for index in 1, 2, 3: | 
					
						
							|  |  |  |             assert f"layer{index}" in docker.succeed( | 
					
						
							|  |  |  |                 f"docker run --rm  ${examples.layersOrder.imageName} cat /tmp/layer{index}" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-08 21:49:16 +12:00
										 |  |  |     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" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |     with subtest("Ensure image with only 2 layers can be loaded"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.two-layered-image}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with subtest( | 
					
						
							|  |  |  |         "Ensure the bulk layer doesn't miss store paths (regression test for #78744)" | 
					
						
							|  |  |  |     ): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${pkgs.dockerTools.examples.bulk-layer}'", | 
					
						
							|  |  |  |             # Ensure the two output paths (ls and hello) are in the layer | 
					
						
							|  |  |  |             "docker run bulk-layer ls /bin/hello", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-02-24 00:41:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure correct behavior when no store is needed"): | 
					
						
							| 
									
										
										
										
											2020-08-14 21:06:00 +12:00
										 |  |  |         # This check tests that buildLayeredImage can build images that don't need a store. | 
					
						
							| 
									
										
										
										
											2020-02-24 00:41:55 +01:00
										 |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${pkgs.dockerTools.examples.no-store-paths}'" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # This check may be loosened to allow an *empty* store rather than *no* store. | 
					
						
							|  |  |  |         docker.succeed("docker run --rm no-store-paths ls /") | 
					
						
							|  |  |  |         docker.fail("docker run --rm no-store-paths ls /nix/store") | 
					
						
							| 
									
										
										
										
											2020-07-04 22:00:57 +12:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 16:59:58 +12:00
										 |  |  |     with subtest("Ensure buildLayeredImage does not change store path contents."): | 
					
						
							| 
									
										
										
										
											2020-07-04 22:00:57 +12:00
										 |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${pkgs.dockerTools.examples.filesInStore}'", | 
					
						
							| 
									
										
										
										
											2020-07-06 16:59:58 +12:00
										 |  |  |             "docker run --rm file-in-store nix-store --verify --check-contents", | 
					
						
							|  |  |  |             "docker run --rm file-in-store |& grep 'some data'", | 
					
						
							| 
									
										
										
										
											2020-07-04 22:00:57 +12:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-11-19 18:12:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("Ensure cross compiled image can be loaded and has correct arch."): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							| 
									
										
										
										
											2020-11-20 11:57:56 +01:00
										 |  |  |             "docker load --input='${pkgs.dockerTools.examples.cross}'", | 
					
						
							| 
									
										
										
										
											2020-11-19 18:12:36 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         assert ( | 
					
						
							|  |  |  |             docker.succeed( | 
					
						
							| 
									
										
										
										
											2020-11-20 11:57:56 +01:00
										 |  |  |                 "docker inspect ${pkgs.dockerTools.examples.cross.imageName} " | 
					
						
							| 
									
										
										
										
											2020-11-19 18:12:36 +01:00
										 |  |  |                 + "| ${pkgs.jq}/bin/jq -r .[].Architecture" | 
					
						
							|  |  |  |             ).strip() | 
					
						
							| 
									
										
										
										
											2020-12-11 18:54:44 -08:00
										 |  |  |             == "${if pkgs.system == "aarch64-linux" then "amd64" else "arm64"}" | 
					
						
							| 
									
										
										
										
											2020-11-19 18:12:36 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-01-04 21:33:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with subtest("buildLayeredImage doesn't dereference /nix/store symlink layers"): | 
					
						
							|  |  |  |         docker.succeed( | 
					
						
							|  |  |  |             "docker load --input='${examples.layeredStoreSymlink}'", | 
					
						
							|  |  |  |             "docker run --rm ${examples.layeredStoreSymlink.imageName} bash -c 'test -L ${examples.layeredStoreSymlink.passthru.symlink}'", | 
					
						
							|  |  |  |             "docker rmi ${examples.layeredStoreSymlink.imageName}", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-02-13 12:38:26 +01:00
										 |  |  |   '';
 | 
					
						
							| 
									
										
										
										
											2018-02-14 06:20:16 +01:00
										 |  |  | }) |