at master 4.4 kB view raw
1{ 2 system ? builtins.currentSystem, 3 config ? { }, 4 pkgs ? import ../.. { inherit system config; }, 5 lib ? pkgs.lib, 6}: 7 8let 9 10 inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest; 11 12 serviceName = "nginxtest"; # different on purpose to verify proper systemd unit generation 13 14 mkOCITest = 15 backend: 16 makeTest { 17 name = "oci-containers-${backend}"; 18 19 meta.maintainers = lib.teams.serokell.members ++ (with lib.maintainers; [ benley ]); 20 21 nodes = { 22 ${backend} = 23 { pkgs, ... }: 24 { 25 virtualisation.oci-containers = { 26 inherit backend; 27 containers.nginx = { 28 inherit serviceName; 29 image = "nginx-container"; 30 imageStream = pkgs.dockerTools.examples.nginxStream; 31 ports = [ "8181:80" ]; 32 capabilities = { 33 CAP_AUDIT_READ = true; 34 CAP_AUDIT_WRITE = false; 35 }; 36 privileged = false; 37 devices = [ 38 "/dev/random:/dev/random" 39 ]; 40 }; 41 }; 42 43 # Stop systemd from killing remaining processes if ExecStop script 44 # doesn't work, so that proper stopping can be tested. 45 systemd.services.${serviceName}.serviceConfig.KillSignal = "SIGCONT"; 46 }; 47 }; 48 49 testScript = '' 50 import json 51 52 start_all() 53 ${backend}.wait_for_unit("${serviceName}.service") 54 ${backend}.wait_for_open_port(8181) 55 ${backend}.wait_until_succeeds("curl -f http://localhost:8181 | grep Hello") 56 output = json.loads(${backend}.succeed("${backend} inspect nginx --format json").strip())[0] 57 ${backend}.succeed("systemctl stop ${serviceName}.service", timeout=10) 58 assert output['HostConfig']['CapAdd'] == ["CAP_AUDIT_READ"] 59 assert output['HostConfig']['CapDrop'] == ${ 60 if backend == "docker" then "[\"CAP_AUDIT_WRITE\"]" else "[]" 61 } # Rootless podman runs with no capabilities so it cannot drop them 62 assert output['HostConfig']['Privileged'] == False 63 assert output['HostConfig']['Devices'] == [{'PathOnHost': '/dev/random', 'PathInContainer': '/dev/random', 'CgroupPermissions': '${ 64 if backend == "docker" then "rwm" else "" 65 }'}] 66 '' 67 + lib.strings.optionalString (backend == "podman") '' 68 assert output['Config']['Labels']['PODMAN_SYSTEMD_UNIT'] == '${serviceName}.service' 69 ''; 70 }; 71 72 podmanRootlessTests = lib.genAttrs [ "conmon" "healthy" ] ( 73 type: 74 makeTest { 75 name = "oci-containers-podman-rootless-${type}"; 76 meta.maintainers = lib.teams.flyingcircus.members ++ [ lib.maintainers.ma27 ]; 77 nodes = { 78 podman = 79 { pkgs, ... }: 80 { 81 environment.systemPackages = [ pkgs.redis ]; 82 users.groups.redis = { }; 83 users.users.redis = { 84 isSystemUser = true; 85 group = "redis"; 86 home = "/var/lib/redis"; 87 linger = type == "healthy"; 88 createHome = true; 89 uid = 2342; 90 subUidRanges = [ 91 { 92 count = 65536; 93 startUid = 2147483646; 94 } 95 ]; 96 subGidRanges = [ 97 { 98 count = 65536; 99 startGid = 2147483647; 100 } 101 ]; 102 }; 103 virtualisation.oci-containers = { 104 backend = "podman"; 105 containers.redis = { 106 image = "redis:latest"; 107 imageFile = pkgs.dockerTools.examples.redis; 108 ports = [ "6379:6379" ]; 109 podman = { 110 user = "redis"; 111 sdnotify = type; 112 }; 113 }; 114 }; 115 }; 116 }; 117 118 testScript = '' 119 start_all() 120 podman.wait_for_unit("podman-redis.service") 121 ${lib.optionalString (type != "healthy") '' 122 podman.wait_for_open_port(6379) 123 ''} 124 podman.wait_until_succeeds("set -eo pipefail; echo 'keys *' | redis-cli") 125 ''; 126 } 127 ); 128in 129{ 130 docker = mkOCITest "docker"; 131 podman = mkOCITest "podman"; 132 podman-rootless-conmon = podmanRootlessTests.conmon; 133 podman-rootless-healthy = podmanRootlessTests.healthy; 134}