OCI-oriented build engine
2.9 kB
77 lines
1module Idmap = Builder.Idmap
2
3(* [supported] reports a kernel capability; it must answer without raising on
4 any host. On a non-Linux host it is always [false]. *)
5let test_supported_is_total () =
6 let answer = Idmap.supported () in
7 if Sys.os_type <> "Unix" || not (Sys.file_exists "/proc/self/ns/user") then
8 Alcotest.(check bool) "no idmap without a Linux /proc" false answer
9 else Alcotest.(check bool) "answers without raising" answer answer
10
11(* The primitive must never silently no-op: a host that cannot idmap (no
12 [mount_setattr], or a source that cannot be opened) has to raise so the
13 runtime can fall back to a chown rather than run a step unmapped. A missing
14 source directory cannot be idmapped on any host. *)
15let test_mount_fails_loudly () =
16 let raises f =
17 try
18 f ();
19 false
20 with Failure _ | Unix.Unix_error _ -> true
21 in
22 Alcotest.(check bool)
23 "idmap mount of a missing source raises" true
24 (raises (fun () ->
25 Idmap.mount
26 ~uid_mappings:
27 [ { Idmap.container_id = 0; host_id = 100000; size = 1 } ]
28 ~gid_mappings:
29 [ { Idmap.container_id = 0; host_id = 100000; size = 1 } ]
30 ~src:"/nonexistent/builder-idmap-src"
31 ~target:"/nonexistent/builder-idmap-target"))
32
33let wait_child ?(tries = 50) pid =
34 let rec loop n =
35 match Unix.waitpid [ Unix.WNOHANG ] pid with
36 | 0, _ when n > 0 ->
37 Unix.sleepf 0.02;
38 loop (n - 1)
39 | 0, _ ->
40 Unix.kill pid Sys.sigkill;
41 ignore (Unix.waitpid [] pid);
42 Alcotest.fail "child hung while reporting idmap failure"
43 | _, status -> status
44 in
45 loop tries
46
47let test_mount_failure_does_not_sigpipe () =
48 if Sys.file_exists "/proc/self/ns/user" then
49 let pid = Unix.fork () in
50 if pid = 0 then (
51 Sys.set_signal Sys.sigpipe Sys.Signal_default;
52 try
53 Idmap.mount
54 ~uid_mappings:
55 [ { Idmap.container_id = 0; host_id = 100000; size = 1 } ]
56 ~gid_mappings:
57 [ { Idmap.container_id = 0; host_id = 100000; size = 1 } ]
58 ~src:"/nonexistent/builder-idmap-src"
59 ~target:"/nonexistent/builder-idmap-target";
60 exit 2
61 with Failure _ | Unix.Unix_error _ -> exit 0)
62 else
63 match wait_child pid with
64 | Unix.WEXITED 0 -> ()
65 | Unix.WEXITED n -> Alcotest.failf "child exited %d" n
66 | Unix.WSIGNALED n ->
67 Alcotest.failf "child was signaled %d while reporting idmap failure" n
68 | Unix.WSTOPPED n -> Alcotest.failf "child stopped %d" n
69
70let suite =
71 ( "idmap",
72 [
73 Alcotest.test_case "supported is total" `Quick test_supported_is_total;
74 Alcotest.test_case "mount fails loudly" `Quick test_mount_fails_loudly;
75 Alcotest.test_case "mount failure does not sigpipe" `Quick
76 test_mount_failure_does_not_sigpipe;
77 ] )