]>
Commit | Line | Data |
---|---|---|
72d0e1cb SG |
1 | /* liblxcapi |
2 | * | |
3 | * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>. | |
4 | * Copyright © 2012 Canonical Ltd. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2, as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | */ | |
948955a2 | 19 | #include <lxc/lxccontainer.h> |
72d0e1cb SG |
20 | |
21 | #include <unistd.h> | |
22 | #include <signal.h> | |
23 | #include <stdio.h> | |
24 | #include <sys/types.h> | |
25 | #include <sys/wait.h> | |
26 | #include <stdlib.h> | |
27 | #include <errno.h> | |
95ee490b | 28 | #include <string.h> |
83319023 | 29 | |
f2363e38 | 30 | #include "lxc/state.h" |
83319023 | 31 | #include "lxctest.h" |
72d0e1cb SG |
32 | |
33 | #define MYNAME "lxctest1" | |
34 | ||
35 | int main(int argc, char *argv[]) | |
36 | { | |
d479e1f7 | 37 | int ret = EXIT_FAILURE; |
72d0e1cb | 38 | struct lxc_container *c; |
72d0e1cb SG |
39 | char v1[2], v2[256], v3[2048]; |
40 | ||
afeecbba | 41 | if ((c = lxc_container_new("testxyz", NULL)) == NULL) { |
72d0e1cb | 42 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); |
d479e1f7 | 43 | exit(EXIT_FAILURE); |
72d0e1cb SG |
44 | } |
45 | ||
83319023 CB |
46 | /* EXPECT SUCCESS: lxc.syslog with valid value. */ |
47 | if (!c->set_config_item(c, "lxc.syslog", "local0")) { | |
48 | lxc_error("%s\n", "Failed to set lxc.syslog.\n"); | |
49 | goto out; | |
50 | } | |
51 | ret = c->get_config_item(c, "lxc.syslog", v2, 255); | |
52 | if (ret < 0) { | |
53 | lxc_error("Failed to retrieve lxc.syslog: %d.\n", ret); | |
54 | goto out; | |
55 | } | |
56 | if (strcmp(v2, "local0") != 0) { | |
57 | lxc_error("Expected: local0 == %s.\n", v2); | |
58 | goto out; | |
59 | } | |
60 | lxc_debug("Retrieving value for lxc.syslog correctly returned: %s.\n", v2); | |
61 | ||
62 | /* EXPECT FAILURE: lxc.syslog with invalid value. */ | |
63 | if (c->set_config_item(c, "lxc.syslog", "NONSENSE")) { | |
64 | lxc_error("%s\n", "Succeeded int setting lxc.syslog to invalid value \"NONSENSE\".\n"); | |
65 | goto out; | |
66 | } | |
67 | lxc_debug("%s\n", "Successfully failed to set lxc.syslog to invalid value.\n"); | |
68 | ||
72d0e1cb SG |
69 | if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) { |
70 | fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__); | |
72d0e1cb SG |
71 | goto out; |
72 | } | |
73 | ret = c->get_config_item(c, "lxc.hook.pre-start", v2, 255); | |
74 | if (ret < 0) { | |
75 | fprintf(stderr, "%d: get_config_item(lxc.hook.pre-start) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
76 | goto out; |
77 | } | |
78 | fprintf(stderr, "lxc.hook.pre-start returned %d %s\n", ret, v2); | |
79 | ||
80 | ret = c->get_config_item(c, "lxc.network", v2, 255); | |
81 | if (ret < 0) { | |
82 | fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
83 | goto out; |
84 | } | |
85 | fprintf(stderr, "%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); | |
86 | if (!c->set_config_item(c, "lxc.tty", "4")) { | |
87 | fprintf(stderr, "%d: failed to set tty\n", __LINE__); | |
72d0e1cb SG |
88 | goto out; |
89 | } | |
90 | ret = c->get_config_item(c, "lxc.tty", v2, 255); | |
91 | if (ret < 0) { | |
92 | fprintf(stderr, "%d: get_config_item(lxc.tty) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
93 | goto out; |
94 | } | |
95 | fprintf(stderr, "lxc.tty returned %d %s\n", ret, v2); | |
96 | ||
97 | if (!c->set_config_item(c, "lxc.arch", "x86")) { | |
98 | fprintf(stderr, "%d: failed to set arch\n", __LINE__); | |
72d0e1cb SG |
99 | goto out; |
100 | } | |
101 | ret = c->get_config_item(c, "lxc.arch", v2, 255); | |
102 | if (ret < 0) { | |
103 | fprintf(stderr, "%d: get_config_item(lxc.arch) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
104 | goto out; |
105 | } | |
106 | printf("lxc.arch returned %d %s\n", ret, v2); | |
107 | ||
68d18db8 PT |
108 | if (!c->set_config_item(c, "lxc.init_uid", "100")) { |
109 | fprintf(stderr, "%d: failed to set init_uid\n", __LINE__); | |
68d18db8 PT |
110 | goto out; |
111 | } | |
112 | ret = c->get_config_item(c, "lxc.init_uid", v2, 255); | |
113 | if (ret < 0) { | |
114 | fprintf(stderr, "%d: get_config_item(lxc.init_uid) returned %d\n", __LINE__, ret); | |
68d18db8 PT |
115 | goto out; |
116 | } | |
117 | printf("lxc.init_uid returned %d %s\n", ret, v2); | |
118 | ||
119 | if (!c->set_config_item(c, "lxc.init_gid", "100")) { | |
120 | fprintf(stderr, "%d: failed to set init_gid\n", __LINE__); | |
68d18db8 PT |
121 | goto out; |
122 | } | |
123 | ret = c->get_config_item(c, "lxc.init_gid", v2, 255); | |
124 | if (ret < 0) { | |
125 | fprintf(stderr, "%d: get_config_item(lxc.init_gid) returned %d\n", __LINE__, ret); | |
68d18db8 PT |
126 | goto out; |
127 | } | |
128 | printf("lxc.init_gid returned %d %s\n", ret, v2); | |
129 | ||
72d0e1cb SG |
130 | #define HNAME "hostname1" |
131 | // demonstrate proper usage: | |
132 | char *alloced; | |
133 | if (!c->set_config_item(c, "lxc.utsname", HNAME)) { | |
134 | fprintf(stderr, "%d: failed to set utsname\n", __LINE__); | |
72d0e1cb SG |
135 | goto out; |
136 | } | |
137 | ||
138 | int len; | |
139 | len = c->get_config_item(c, "lxc.utsname", NULL, 0); // query the size of the string | |
140 | if (len < 0) { | |
141 | fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, len); | |
72d0e1cb SG |
142 | goto out; |
143 | } | |
144 | printf("lxc.utsname returned %d\n", len); | |
145 | ||
146 | // allocate the length of string + 1 for trailing \0 | |
147 | alloced = malloc(len+1); | |
148 | if (!alloced) { | |
149 | fprintf(stderr, "%d: failed to allocate %d bytes for utsname\n", __LINE__, len); | |
72d0e1cb SG |
150 | goto out; |
151 | } | |
152 | // now pass in the malloc'd array, and pass in length of string + 1: again | |
153 | // because we need room for the trailing \0 | |
154 | ret = c->get_config_item(c, "lxc.utsname", alloced, len+1); | |
155 | if (ret < 0) { | |
156 | fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
157 | goto out; |
158 | } | |
159 | if (strcmp(alloced, HNAME) != 0 || ret != len) { | |
160 | fprintf(stderr, "lxc.utsname returned wrong value: %d %s not %d %s\n", ret, alloced, len, HNAME); | |
72d0e1cb SG |
161 | goto out; |
162 | } | |
163 | printf("lxc.utsname returned %d %s\n", len, alloced); | |
164 | free(alloced); | |
165 | ||
166 | if (!c->set_config_item(c, "lxc.mount.entry", "hi there")) { | |
167 | fprintf(stderr, "%d: failed to set mount.entry\n", __LINE__); | |
72d0e1cb SG |
168 | goto out; |
169 | } | |
170 | ret = c->get_config_item(c, "lxc.mount.entry", v2, 255); | |
171 | if (ret < 0) { | |
172 | fprintf(stderr, "%d: get_config_item(lxc.mount.entry) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
173 | goto out; |
174 | } | |
175 | printf("lxc.mount.entry returned %d %s\n", ret, v2); | |
176 | ||
177 | if (!c->set_config_item(c, "lxc.aa_profile", "unconfined")) { | |
178 | fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__); | |
72d0e1cb SG |
179 | goto out; |
180 | } | |
181 | ret = c->get_config_item(c, "lxc.aa_profile", v2, 255); | |
182 | if (ret < 0) { | |
183 | fprintf(stderr, "%d: get_config_item(lxc.aa_profile) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
184 | goto out; |
185 | } | |
186 | printf("lxc.aa_profile returned %d %s\n", ret, v2); | |
187 | ||
188 | lxc_container_put(c); | |
189 | ||
190 | // new test with real container | |
afeecbba | 191 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { |
72d0e1cb | 192 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); |
72d0e1cb SG |
193 | goto out; |
194 | } | |
195 | c->destroy(c); | |
196 | lxc_container_put(c); | |
197 | ||
afeecbba | 198 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { |
72d0e1cb | 199 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); |
72d0e1cb SG |
200 | goto out; |
201 | } | |
787c3ebe | 202 | if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) { |
e403a064 | 203 | fprintf(stderr, "%d: failed to create a trusty container\n", __LINE__); |
72d0e1cb SG |
204 | goto out; |
205 | } | |
72d0e1cb SG |
206 | lxc_container_put(c); |
207 | ||
208 | /* XXX TODO load_config needs to clear out any old config first */ | |
afeecbba | 209 | if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { |
72d0e1cb | 210 | fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); |
72d0e1cb SG |
211 | goto out; |
212 | } | |
213 | ||
214 | ret = c->get_config_item(c, "lxc.cap.drop", NULL, 300); | |
215 | if (ret < 5 || ret > 255) { | |
216 | fprintf(stderr, "%d: get_config_item(lxc.cap.drop) with NULL returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
217 | goto out; |
218 | } | |
219 | ret = c->get_config_item(c, "lxc.cap.drop", v1, 1); | |
220 | if (ret < 5 || ret > 255) { | |
221 | fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
222 | goto out; |
223 | } | |
224 | ret = c->get_config_item(c, "lxc.cap.drop", v2, 255); | |
225 | if (ret < 0) { | |
226 | fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); | |
72d0e1cb SG |
227 | goto out; |
228 | } | |
229 | printf("%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); | |
230 | ret = c->get_config_item(c, "lxc.network", v2, 255); | |
231 | if (ret < 0) { | |
232 | fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
233 | goto out; |
234 | } | |
235 | printf("%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); | |
236 | ||
237 | if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) { | |
238 | fprintf(stderr, "%d: failed to set ipv4\n", __LINE__); | |
72d0e1cb SG |
239 | goto out; |
240 | } | |
241 | ||
242 | ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); | |
243 | if (ret <= 0) { | |
244 | fprintf(stderr, "%d: lxc.network.0.ipv4 returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
245 | goto out; |
246 | } | |
247 | if (!c->clear_config_item(c, "lxc.network.0.ipv4")) { | |
248 | fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__); | |
72d0e1cb SG |
249 | goto out; |
250 | } | |
251 | ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); | |
252 | if (ret != 0) { | |
253 | fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
254 | goto out; |
255 | } | |
256 | ||
9eaf8a59 SJ |
257 | if (!c->set_config_item(c, "lxc.network.ipv4.gateway", "10.2.3.254")) { |
258 | fprintf(stderr, "%d: failed to set ipv4.gateway\n", __LINE__); | |
9eaf8a59 SJ |
259 | goto out; |
260 | } | |
261 | ||
262 | ret = c->get_config_item(c, "lxc.network.0.ipv4.gateway", v2, 255); | |
263 | if (ret <= 0) { | |
264 | fprintf(stderr, "%d: lxc.network.0.ipv4.gateway returned %d\n", __LINE__, ret); | |
9eaf8a59 SJ |
265 | goto out; |
266 | } | |
8d19ce7b | 267 | if (!c->set_config_item(c, "lxc.network.0.ipv4.gateway", "")) { |
9eaf8a59 | 268 | fprintf(stderr, "%d: failed clearing ipv4.gateway\n", __LINE__); |
9eaf8a59 SJ |
269 | goto out; |
270 | } | |
271 | ret = c->get_config_item(c, "lxc.network.0.ipv4.gateway", v2, 255); | |
272 | if (ret != 0) { | |
273 | fprintf(stderr, "%d: after clearing ipv4.gateway get_item(lxc.network.0.ipv4.gateway returned %d\n", __LINE__, ret); | |
9eaf8a59 SJ |
274 | goto out; |
275 | } | |
276 | ||
72d0e1cb SG |
277 | ret = c->get_config_item(c, "lxc.network.0.link", v2, 255); |
278 | if (ret < 0) { | |
279 | fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
280 | goto out; |
281 | } | |
282 | printf("%d: get_config_item (link) returned %d %s\n", __LINE__, ret, v2); | |
283 | ret = c->get_config_item(c, "lxc.network.0.name", v2, 255); | |
284 | if (ret < 0) { | |
285 | fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
286 | goto out; |
287 | } | |
288 | printf("%d: get_config_item (name) returned %d %s\n", __LINE__, ret, v2); | |
289 | ||
290 | if (!c->clear_config_item(c, "lxc.network")) { | |
291 | fprintf(stderr, "%d: clear_config_item failed\n", __LINE__); | |
72d0e1cb SG |
292 | goto out; |
293 | } | |
294 | ret = c->get_config_item(c, "lxc.network", v2, 255); | |
295 | if (ret != 0) { | |
296 | fprintf(stderr, "%d: network was not actually cleared (get_network returned %d)\n", __LINE__, ret); | |
72d0e1cb SG |
297 | goto out; |
298 | } | |
299 | ||
300 | ret = c->get_config_item(c, "lxc.cgroup", v3, 2047); | |
301 | if (ret < 0) { | |
302 | fprintf(stderr, "%d: get_config_item(cgroup.devices) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
303 | goto out; |
304 | } | |
305 | printf("%d: get_config_item (cgroup.devices) returned %d %s\n", __LINE__, ret, v3); | |
306 | ||
307 | ret = c->get_config_item(c, "lxc.cgroup.devices.allow", v3, 2047); | |
308 | if (ret < 0) { | |
309 | fprintf(stderr, "%d: get_config_item(cgroup.devices.devices.allow) returned %d\n", __LINE__, ret); | |
72d0e1cb SG |
310 | goto out; |
311 | } | |
312 | printf("%d: get_config_item (cgroup.devices.devices.allow) returned %d %s\n", __LINE__, ret, v3); | |
313 | ||
314 | if (!c->clear_config_item(c, "lxc.cgroup")) { | |
03fadd16 | 315 | fprintf(stderr, "%d: failed clearing lxc.cgroup\n", __LINE__); |
72d0e1cb SG |
316 | goto out; |
317 | } | |
318 | if (!c->clear_config_item(c, "lxc.cap.drop")) { | |
03fadd16 | 319 | fprintf(stderr, "%d: failed clearing lxc.cap.drop\n", __LINE__); |
72d0e1cb SG |
320 | goto out; |
321 | } | |
6a564066 SG |
322 | if (!c->clear_config_item(c, "lxc.mount.entry")) { |
323 | fprintf(stderr, "%d: failed clearing lxc.mount.entry\n", __LINE__); | |
72d0e1cb SG |
324 | goto out; |
325 | } | |
326 | if (!c->clear_config_item(c, "lxc.hook")) { | |
03fadd16 | 327 | fprintf(stderr, "%d: failed clearing lxc.hook\n", __LINE__); |
72d0e1cb SG |
328 | goto out; |
329 | } | |
72d0e1cb | 330 | printf("All get_item tests passed\n"); |
d479e1f7 | 331 | ret = EXIT_SUCCESS; |
72d0e1cb | 332 | out: |
d479e1f7 | 333 | c->destroy(c); |
72d0e1cb SG |
334 | lxc_container_put(c); |
335 | exit(ret); | |
d479e1f7 | 336 | } |