]>
Commit | Line | Data |
---|---|---|
d17fe041 FW |
1 | package PVE::LXC::Test; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use lib qw(..); | |
7 | ||
8 | use Test::More; | |
9 | use Time::HiRes qw (gettimeofday tv_interval); | |
10 | ||
11 | use PVE::LXC; | |
12 | ||
13 | subtest 'valid: default config (unprivileged)' => sub { | |
14 | plan tests => 1; | |
15 | ||
16 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
17 | unprivileged => 1, | |
18 | lxc => [ ['rootfs', 'xyz'] ], | |
19 | }); | |
20 | ||
21 | $@ = undef; | |
22 | eval { | |
23 | PVE::LXC::validate_id_maps($id_maps); | |
24 | }; | |
25 | is($@, "", "no error"); | |
26 | }; | |
27 | ||
28 | subtest 'valid: mapping one user/group to host' => sub { | |
29 | plan tests => 1; | |
30 | ||
31 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
32 | lxc => [ | |
33 | ['lxc.idmap', 'u 0 100000 1005'], | |
34 | ['lxc.idmap', 'g 0 100000 1007'], | |
35 | ['lxc.idmap', 'u 1005 1005 1'], | |
36 | ['lxc.idmap', 'g 1007 1007 1'], | |
37 | ['lxc.idmap', 'u 1006 101006 64530'], | |
38 | ['lxc.idmap', 'g 1008 101008 64528'], | |
39 | ], | |
40 | }); | |
41 | ||
42 | $@ = undef; | |
43 | eval { | |
44 | PVE::LXC::validate_id_maps($id_maps); | |
45 | }; | |
46 | is($@, "", "no error"); | |
47 | }; | |
48 | ||
49 | subtest 'valid: mapping user/group ranges to host' => sub { | |
50 | plan tests => 1; | |
51 | ||
52 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
53 | lxc => [ | |
54 | ['lxc.idmap', 'u 3000 103000 60000'], | |
55 | ['lxc.idmap', 'u 2000 1000 1000'], | |
56 | ['lxc.idmap', 'u 0 100000 2000'], | |
57 | ['lxc.idmap', 'g 2000 102000 63534'], | |
58 | ['lxc.idmap', 'g 1000 2000 1000'], | |
59 | ['lxc.idmap', 'g 0 100000 1000'], | |
60 | ['lxc.idmap', 'u 63000 263000 2536'], | |
61 | ['lxc.idmap', 'g 65534 365534 2'], | |
62 | ], | |
63 | }); | |
64 | ||
65 | $@ = undef; | |
66 | eval { | |
67 | PVE::LXC::validate_id_maps($id_maps); | |
68 | }; | |
69 | is($@, "", "no error"); | |
70 | }; | |
71 | ||
72 | subtest 'invalid: ambiguous mappings' => sub { | |
73 | plan tests => 10; | |
74 | ||
75 | $@ = undef; | |
76 | eval { | |
77 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
78 | lxc => [ | |
79 | ['lxc.idmap', 'u 0 100000 1005'], | |
80 | ['lxc.idmap', 'u 1005 1005 2'], # maps host uid 1005 | |
81 | ['lxc.idmap', 'u 1007 101007 992'], | |
82 | ['lxc.idmap', 'u 11000 1000 10'], # maps host uid 1005 again | |
83 | ], | |
84 | }); | |
85 | PVE::LXC::validate_id_maps($id_maps); | |
86 | }; | |
87 | like($@, qr/invalid map entry 'u 1005 1005 2'/, '$@ correct'); | |
88 | like($@, qr/host uid 1005 is also mapped by entry 'u 11000 1000 10'/, '$@ correct'); | |
89 | ||
90 | $@ = undef; | |
91 | eval { | |
92 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
93 | lxc => [ | |
94 | ['lxc.idmap', 'u 0 100000 65536'], # maps container uid 1005 | |
95 | ['lxc.idmap', 'u 1005 1005 1'], # maps container uid 1005 again | |
96 | ['lxc.idmap', 'u 1006 201006 64530'], | |
97 | ], | |
98 | }); | |
99 | PVE::LXC::validate_id_maps($id_maps); | |
100 | }; | |
101 | ||
102 | like($@, qr/invalid map entry 'u 1005 1005 1'/, '$@ correct'); | |
103 | like($@, qr/container uid 1005 is also mapped by entry 'u 0 100000 65536'/, '$@ correct'); | |
104 | ||
105 | $@ = undef; | |
106 | eval { | |
107 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
108 | lxc => [ | |
109 | ['lxc.idmap', 'u 5 100000 6'], # 5..10 | |
110 | ['lxc.idmap', 'u 0 200000 11'], # 0..10 | |
111 | ['lxc.idmap', 'u 3 300000 2'], # 3..4 | |
112 | ], | |
113 | }); | |
114 | PVE::LXC::validate_id_maps($id_maps); | |
115 | }; | |
116 | ||
117 | # this flags line 2 and 3. the input is [ 0..10, 3..4, 5..10 ], and the | |
118 | # algorithm misses the conflict between 0..10 and 5..10. | |
119 | like($@, qr/invalid map entry 'u 3 300000 2'/, '$@ correct'); | |
120 | like($@, qr/container uid 3 is also mapped by entry 'u 0 200000 11'/, '$@ correct'); | |
121 | ||
122 | $@ = undef; | |
123 | eval { | |
124 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
125 | lxc => [ | |
126 | ['lxc.idmap', 'g 0 100000 1001'], # maps container gid 1000 | |
127 | ['lxc.idmap', 'g 1000 1000 10'], # maps container gid 1000 again | |
128 | ], | |
129 | }); | |
130 | PVE::LXC::validate_id_maps($id_maps); | |
131 | }; | |
132 | like($@, qr/invalid map entry 'g 1000 1000 10'/, '$@ correct'); | |
133 | like($@, qr/container gid 1000 is also mapped by entry 'g 0 100000 1001'/, '$@ correct'); | |
134 | ||
135 | $@ = undef; | |
136 | eval { | |
137 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ | |
138 | lxc => [ | |
139 | ['lxc.idmap', 'g 0 100000 1000'], # maps host gid 100000 | |
140 | ['lxc.idmap', 'g 2000 102000 1000'], | |
141 | ['lxc.idmap', 'g 3500 99500 5000'], # maps host gid 100000 again | |
142 | ], | |
143 | }); | |
144 | PVE::LXC::validate_id_maps($id_maps); | |
145 | }; | |
146 | like($@, qr/invalid map entry 'g 0 100000 1000'/, '$@ correct'); | |
147 | like($@, qr/host gid 100000 is also mapped by entry 'g 3500 99500 5000'/, '$@ correct'); | |
148 | }; | |
149 | ||
150 | subtest 'check performance' => sub { | |
151 | plan tests => 1; | |
152 | ||
153 | # generate mapping with 1000 entries | |
154 | my $entries = []; | |
155 | foreach my $i (0..999) { | |
156 | my $first_container_uid = $i * 10; | |
157 | my $first_host_uid = 100000 + $first_container_uid; | |
158 | push @$entries, ['lxc.idmap', "u $first_container_uid $first_host_uid 10"] | |
159 | } | |
160 | ||
161 | my ($id_maps, undef, undef) = PVE::LXC::parse_id_maps({ lxc => $entries }); | |
162 | ||
163 | my $start_time = [ gettimeofday() ]; | |
164 | $@ = undef; | |
165 | eval { | |
166 | PVE::LXC::validate_id_maps($id_maps); | |
167 | }; | |
168 | my $elapsed = tv_interval($start_time); | |
169 | ||
170 | is($@, "", "no error"); | |
171 | diag("validation took $elapsed seconds"); | |
172 | }; | |
173 | ||
174 | done_testing(); |