vuls: init at 0.27.0
[NixPkgs.git] / nixos / tests / podman / default.nix
blobf57523cf58886fa8a0e2aa52f74d55653e9b7bce
1 import ../make-test-python.nix (
2   { pkgs, lib, ... }:
3   let
4     quadletContainerFile = pkgs.writeText "quadlet.container" ''
5       [Unit]
6       Description=A test quadlet container
8       [Container]
9       Image=localhost/scratchimg:latest
10       Exec=bash -c 'trap exit SIGTERM SIGINT; while true; do sleep 1; done'
11       ContainerName=quadlet
12       Volume=/nix/store:/nix/store
13       Volume=/run/current-system/sw/bin:/bin
15       [Install]
16       WantedBy=default.target
17     '';
18   in
19   {
20     name = "podman";
21     meta = {
22       maintainers = lib.teams.podman.members;
23     };
25     nodes = {
26       rootful = { pkgs, ... }: {
27         virtualisation.podman.enable = true;
29         # hack to ensure that podman built with and without zfs in extraPackages is cached
30         boot.supportedFilesystems = [ "zfs" ];
31         networking.hostId = "00000000";
32       };
33       rootless = { pkgs, ... }: {
34         virtualisation.podman.enable = true;
36         users.users.alice = {
37           isNormalUser = true;
38         };
39       };
40       dns = { pkgs, ... }: {
41         virtualisation.podman.enable = true;
43         virtualisation.podman.defaultNetwork.settings.dns_enabled = true;
44       };
45       docker = { pkgs, ... }: {
46         virtualisation.podman.enable = true;
48         virtualisation.podman.dockerSocket.enable = true;
50         environment.systemPackages = [
51           pkgs.docker-client
52         ];
54         users.users.alice = {
55           isNormalUser = true;
56           extraGroups = [ "podman" ];
57         };
59         users.users.mallory = {
60           isNormalUser = true;
61         };
62       };
63     };
65     testScript = ''
66       import shlex
69       def su_cmd(cmd, user = "alice"):
70           cmd = shlex.quote(cmd)
71           return f"su {user} -l -c {cmd}"
74       rootful.wait_for_unit("sockets.target")
75       rootless.wait_for_unit("sockets.target")
76       dns.wait_for_unit("sockets.target")
77       docker.wait_for_unit("sockets.target")
78       start_all()
80       with subtest("Run container as root with runc"):
81           rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
82           rootful.succeed(
83               "podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
84           )
85           rootful.succeed("podman ps | grep sleeping")
86           rootful.succeed("podman stop sleeping")
87           rootful.succeed("podman rm sleeping")
89       with subtest("Run container as root with crun"):
90           rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
91           rootful.succeed(
92               "podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
93           )
94           rootful.succeed("podman ps | grep sleeping")
95           rootful.succeed("podman stop sleeping")
96           rootful.succeed("podman rm sleeping")
98       with subtest("Run container as root with the default backend"):
99           rootful.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
100           rootful.succeed(
101               "podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
102           )
103           rootful.succeed("podman ps | grep sleeping")
104           rootful.succeed("podman stop sleeping")
105           rootful.succeed("podman rm sleeping")
107       # start systemd session for rootless
108       rootless.succeed("loginctl enable-linger alice")
109       rootless.succeed(su_cmd("whoami"))
110       rootless.sleep(1)
112       with subtest("Run container rootless with runc"):
113           rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
114           rootless.succeed(
115               su_cmd(
116                   "podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
117               )
118           )
119           rootless.succeed(su_cmd("podman ps | grep sleeping"))
120           rootless.succeed(su_cmd("podman stop sleeping"))
121           rootless.succeed(su_cmd("podman rm sleeping"))
123       with subtest("Run container rootless with crun"):
124           rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
125           rootless.succeed(
126               su_cmd(
127                   "podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
128               )
129           )
130           rootless.succeed(su_cmd("podman ps | grep sleeping"))
131           rootless.succeed(su_cmd("podman stop sleeping"))
132           rootless.succeed(su_cmd("podman rm sleeping"))
134       with subtest("Run container rootless with the default backend"):
135           rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
136           rootless.succeed(
137               su_cmd(
138                   "podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
139               )
140           )
141           rootless.succeed(su_cmd("podman ps | grep sleeping"))
142           rootless.succeed(su_cmd("podman stop sleeping"))
143           rootless.succeed(su_cmd("podman rm sleeping"))
145       with subtest("rootlessport"):
146           rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
147           rootless.succeed(
148               su_cmd(
149                   "podman run -d -p 9000:8888 --name=rootlessport -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Testing</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8888"
150               )
151           )
152           rootless.succeed(su_cmd("podman ps | grep rootlessport"))
153           rootless.wait_until_succeeds(su_cmd("${pkgs.curl}/bin/curl localhost:9000 | grep Testing"))
154           rootless.succeed(su_cmd("podman stop rootlessport"))
155           rootless.succeed(su_cmd("podman rm rootlessport"))
157       with subtest("Run container with init"):
158           rootful.succeed(
159               "tar cv -C ${pkgs.pkgsStatic.busybox} . | podman import - busybox"
160           )
161           pid = rootful.succeed("podman run --rm busybox readlink /proc/self").strip()
162           assert pid == "1"
163           pid = rootful.succeed("podman run --rm --init busybox readlink /proc/self").strip()
164           assert pid == "2"
166       with subtest("aardvark-dns"):
167           dns.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
168           dns.succeed(
169               "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Testing</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8000"
170           )
171           dns.succeed("podman ps | grep webserver")
172           dns.wait_until_succeeds(
173               "podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${pkgs.curl}/bin/curl http://webserver:8000 | grep Testing"
174           )
175           dns.succeed("podman stop webserver")
176           dns.succeed("podman rm webserver")
178       with subtest("A podman member can use the docker cli"):
179           docker.succeed(su_cmd("docker version"))
181       with subtest("Run container via docker cli"):
182           docker.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
183           docker.succeed(
184             "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin localhost/scratchimg /bin/sleep 10"
185           )
186           docker.succeed("docker ps | grep sleeping")
187           docker.succeed("podman ps | grep sleeping")
188           docker.succeed("docker stop sleeping")
189           docker.succeed("docker rm sleeping")
191       with subtest("A podman non-member can not use the docker cli"):
192           docker.fail(su_cmd("docker version", user="mallory"))
194       with subtest("A rootless quadlet container service is created"):
195           dir = "/home/alice/.config/containers/systemd"
196           rootless.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
197           rootless.succeed(su_cmd(f"mkdir -p {dir}"))
198           rootless.succeed(su_cmd(f"cp -f ${quadletContainerFile} {dir}/quadlet.container"))
199           rootless.systemctl("daemon-reload", "alice")
200           rootless.systemctl("start quadlet", "alice")
201           rootless.wait_until_succeeds(su_cmd("podman ps | grep quadlet"), timeout=20)
202           rootless.systemctl("stop quadlet", "alice")
204       # TODO: add docker-compose test
206     '';
207   }