mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-03-01 02:02:11 +00:00
Compare commits
539 Commits
3.1.2
...
3.2.0-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2e92c9ec9 | ||
|
|
f527f614c1 | ||
|
|
0364620844 | ||
|
|
2ea8acaaa5 | ||
|
|
f6e1b1152c | ||
|
|
4cb83dc219 | ||
|
|
df615ff252 | ||
|
|
ca6892ddb1 | ||
|
|
3a4b924226 | ||
|
|
e762f70920 | ||
|
|
ca1531fe9d | ||
|
|
851b97fa51 | ||
|
|
8ce14e709a | ||
|
|
206df04b99 | ||
|
|
259158f1c3 | ||
|
|
fa832f4709 | ||
|
|
cbb9fe8b81 | ||
|
|
724437efb3 | ||
|
|
521dad2a47 | ||
|
|
72308ddb07 | ||
|
|
da0f92cef8 | ||
|
|
12f43bea0f | ||
|
|
9630c13ac0 | ||
|
|
e4a458035c | ||
|
|
3ccc29030d | ||
|
|
e0e46de12d | ||
|
|
1a3f8fc1a2 | ||
|
|
b76058c979 | ||
|
|
ebc8e8e2fd | ||
|
|
87cb98c01d | ||
|
|
a96fcfd5be | ||
|
|
c5a59caca1 | ||
|
|
bfdf0144aa | ||
|
|
dd7562522a | ||
|
|
05de7b2607 | ||
|
|
3a9d3c72aa | ||
|
|
4cde844f70 | ||
|
|
8d10d157b3 | ||
|
|
47a02dcc7f | ||
|
|
911d8a5a7f | ||
|
|
2cd2d02d1f | ||
|
|
3d8185863d | ||
|
|
593840e075 | ||
|
|
bdb75fb21e | ||
|
|
20cb875087 | ||
|
|
da877a603d | ||
|
|
b9a1db2601 | ||
|
|
3e85bf5b17 | ||
|
|
5f3f844a1e | ||
|
|
9e83795fca | ||
|
|
802cd2f673 | ||
|
|
815b4e8dac | ||
|
|
777c3dc8d2 | ||
|
|
50cc9c582f | ||
|
|
136e2415da | ||
|
|
3bf767cfcd | ||
|
|
ac88d34e0c | ||
|
|
32b39ee347 | ||
|
|
73913c8eb7 | ||
|
|
2856d3f23d | ||
|
|
42dce15b1f | ||
|
|
e8f81ee93d | ||
|
|
cfe63527c5 | ||
|
|
197c336516 | ||
|
|
181017d1d8 | ||
|
|
76f975e5e6 | ||
|
|
20ac3917ad | ||
|
|
1ad442e656 | ||
|
|
4d17ea4a01 | ||
|
|
a133fadbfa | ||
|
|
a7dd6cbadd | ||
|
|
b9990c2017 | ||
|
|
14939d00ad | ||
|
|
c9bf7808b6 | ||
|
|
3665b42045 | ||
|
|
edfaae85cb | ||
|
|
fe33015075 | ||
|
|
c937d0a5d4 | ||
|
|
2c90cac751 | ||
|
|
4da6eb588d | ||
|
|
14dd053758 | ||
|
|
0bb37bff78 | ||
|
|
13f9ba2298 | ||
|
|
af7f2519bf | ||
|
|
dbcc3b5cc8 | ||
|
|
b8bbe6325f | ||
|
|
cf0ca265f9 | ||
|
|
db095ddeb4 | ||
|
|
f4ee00576a | ||
|
|
7a58a91fa6 | ||
|
|
879333bfc7 | ||
|
|
38ce4a32af | ||
|
|
5f8008b69c | ||
|
|
a085a6d7b4 | ||
|
|
772d4db262 | ||
|
|
45fa366926 | ||
|
|
4770d3064a | ||
|
|
fb9c1fc36e | ||
|
|
813e4c576f | ||
|
|
af18806a8d | ||
|
|
76ae7a3abe | ||
|
|
12c5ef9020 | ||
|
|
b87820ee8c | ||
|
|
e1f3b871cd | ||
|
|
022a33de92 | ||
|
|
6881b9558b | ||
|
|
7218229af0 | ||
|
|
b0e6a094be | ||
|
|
b0b5d7082e | ||
|
|
4e0dce6802 | ||
|
|
a4c0303d89 | ||
|
|
65670e6b0a | ||
|
|
b86d32aba9 | ||
|
|
9443c4aea7 | ||
|
|
09134c30de | ||
|
|
8495f830b7 | ||
|
|
e57ac2ae18 | ||
|
|
13d7f39c71 | ||
|
|
6594a9329d | ||
|
|
f5ff975560 | ||
|
|
b6e54676eb | ||
|
|
03a8cd69c2 | ||
|
|
9e2b7ff177 | ||
|
|
5c9246db19 | ||
|
|
c57a44436c | ||
|
|
29785a43d7 | ||
|
|
65c61785fc | ||
|
|
4064192896 | ||
|
|
fb40c71a21 | ||
|
|
1016bc17b7 | ||
|
|
b908a780a0 | ||
|
|
b1920198be | ||
|
|
f2b2621dec | ||
|
|
c849bdb0a5 | ||
|
|
6bf1fc6051 | ||
|
|
0d49ceee0b | ||
|
|
138ada049c | ||
|
|
defb643346 | ||
|
|
f7ad75cb12 | ||
|
|
0fec2e6986 | ||
|
|
f2ebdd81c2 | ||
|
|
9a94f1f149 | ||
|
|
2f81f48dae | ||
|
|
07f7d17db5 | ||
|
|
68f6357731 | ||
|
|
7565b33568 | ||
|
|
94a00f9346 | ||
|
|
572b338b3b | ||
|
|
376884b8a4 | ||
|
|
17daeb9dd7 | ||
|
|
521519d745 | ||
|
|
205909fbed | ||
|
|
5226f15c84 | ||
|
|
0f45b0faa9 | ||
|
|
dded731db3 | ||
|
|
2a830177ca | ||
|
|
131f056a12 | ||
|
|
c8cf7ed3bc | ||
|
|
e2b5e7f73b | ||
|
|
6107c32d70 | ||
|
|
377ebc2ad1 | ||
|
|
c18ceae109 | ||
|
|
509bc8b6c8 | ||
|
|
b6d880510a | ||
|
|
9c38204f13 | ||
|
|
1c1ee8057c | ||
|
|
cc8ea3232e | ||
|
|
7fdaab49bc | ||
|
|
0ca6d3b726 | ||
|
|
3d8688f92e | ||
|
|
97291d88e9 | ||
|
|
96e8470dbe | ||
|
|
432d407440 | ||
|
|
b1730e4a67 | ||
|
|
ceefd50bd0 | ||
|
|
a7b4b69230 | ||
|
|
a1568cd2f5 | ||
|
|
3e7b902265 | ||
|
|
53c749a9de | ||
|
|
5c032c64ac | ||
|
|
2e3f19af92 | ||
|
|
4849c56faa | ||
|
|
0a582f7815 | ||
|
|
73253850e6 | ||
|
|
76d2e30547 | ||
|
|
eb3d20dccb | ||
|
|
59568c79dd | ||
|
|
a6b4d92c84 | ||
|
|
ac7c63bc66 | ||
|
|
a0cc8a75f2 | ||
|
|
a81fff706f | ||
|
|
8af6fc77cd | ||
|
|
009b42dbff | ||
|
|
392732e213 | ||
|
|
f4f958d53c | ||
|
|
825e769483 | ||
|
|
e4ee07f7d4 | ||
|
|
243cb2e3af | ||
|
|
a1272bcf1d | ||
|
|
3fa0890e5e | ||
|
|
80e3a2d408 | ||
|
|
fffe2c6082 | ||
|
|
a819ce145f | ||
|
|
87ea43cd4e | ||
|
|
aca6ff7289 | ||
|
|
dc662333df | ||
|
|
897c0bc67e | ||
|
|
eb1762e813 | ||
|
|
f9a94f8fc5 | ||
|
|
f478b9115e | ||
|
|
3b76abb366 | ||
|
|
5ec9ae0f04 | ||
|
|
ea386700fe | ||
|
|
e31efc861c | ||
|
|
542bb0f3f3 | ||
|
|
d7fdf19e9b | ||
|
|
da35241a91 | ||
|
|
db2cac34d8 | ||
|
|
6d315719f0 | ||
|
|
328793bb27 | ||
|
|
e4b3b08871 | ||
|
|
fef531f565 | ||
|
|
9327bb0912 | ||
|
|
69ba2098f8 | ||
|
|
b31f103d12 | ||
|
|
3b3656d96d | ||
|
|
50ce33b02d | ||
|
|
4751adbea1 | ||
|
|
69d7a959c8 | ||
|
|
5a0727ecb4 | ||
|
|
98682805be | ||
|
|
3e15800199 | ||
|
|
3c5ffb0c85 | ||
|
|
ed145365ec | ||
|
|
25b3cdd38c | ||
|
|
01bdacb4e4 | ||
|
|
9feec533ce | ||
|
|
ce8d982512 | ||
|
|
39c3fab7b1 | ||
|
|
054174d3e6 | ||
|
|
800fb49da1 | ||
|
|
fbf03d7aca | ||
|
|
5d79e96966 | ||
|
|
6e4726e454 | ||
|
|
fc22ed0a8a | ||
|
|
502844ced9 | ||
|
|
b2585eecff | ||
|
|
f33345c311 | ||
|
|
20ab2c2420 | ||
|
|
3d9ce3982b | ||
|
|
33dc6c65aa | ||
|
|
eceaae30a5 | ||
|
|
f7b7c187ec | ||
|
|
3018c9ad51 | ||
|
|
800ee5cd88 | ||
|
|
1315bb45f9 | ||
|
|
73e108136a | ||
|
|
1d851b4be3 | ||
|
|
49ce685ebf | ||
|
|
e2a770df55 | ||
|
|
aee6174a53 | ||
|
|
dc74133e74 | ||
|
|
8cdec5707e | ||
|
|
d1f550bd1e | ||
|
|
f3595e48b0 | ||
|
|
3bfaafbf44 | ||
|
|
c1fbaae8d6 | ||
|
|
375187e045 | ||
|
|
79f3047f06 | ||
|
|
ee5dda012b | ||
|
|
2f35b4d4e5 | ||
|
|
e7bd2545ef | ||
|
|
0d96d49633 | ||
|
|
c7ee45f7e5 | ||
|
|
5d4d720647 | ||
|
|
13d857a56d | ||
|
|
abaf881f4a | ||
|
|
dc6569dbbc | ||
|
|
85cc5bb534 | ||
|
|
68cb5689f5 | ||
|
|
ae488cc09f | ||
|
|
2c38e17ef0 | ||
|
|
6af52cef3a | ||
|
|
a3e3b0591f | ||
|
|
cbe6f04194 | ||
|
|
1688e4f3f0 | ||
|
|
108d80a86d | ||
|
|
2550d4462d | ||
|
|
e81b8b8ee5 | ||
|
|
13929fc610 | ||
|
|
41026f003e | ||
|
|
7855b43062 | ||
|
|
3a760a157a | ||
|
|
a159ffdba7 | ||
|
|
8086c75f61 | ||
|
|
1c6d7cb0f7 | ||
|
|
fe86c08a63 | ||
|
|
3215860a47 | ||
|
|
d17dfe4cdd | ||
|
|
e1f972fb1d | ||
|
|
b661e0cf3f | ||
|
|
60c62c3b69 | ||
|
|
43894e9459 | ||
|
|
cab9ca0436 | ||
|
|
53b526b6bd | ||
|
|
c444c24bc5 | ||
|
|
11e0099fb5 | ||
|
|
5d89d08fc4 | ||
|
|
73be4bd3f9 | ||
|
|
d38d7fbf1a | ||
|
|
56331bd7bc | ||
|
|
a552a1953a | ||
|
|
7796e6ccc6 | ||
|
|
41fdda1d84 | ||
|
|
07e49c63e1 | ||
|
|
a914283ce0 | ||
|
|
245ed2cecf | ||
|
|
d0f79e66b9 | ||
|
|
0f73515561 | ||
|
|
4a246309ee | ||
|
|
75987aae72 | ||
|
|
4a95375dc8 | ||
|
|
43dd4440f4 | ||
|
|
293119df78 | ||
|
|
bbc699ddd8 | ||
|
|
8b008fc743 | ||
|
|
da676872b1 | ||
|
|
74ec38cf02 | ||
|
|
ac58588682 | ||
|
|
96555186b3 | ||
|
|
e3c2d727ba | ||
|
|
f06f72b5e9 | ||
|
|
adaabd141a | ||
|
|
20da7f3ec8 | ||
|
|
2fe0733dcb | ||
|
|
ece5edc641 | ||
|
|
1e8005ff88 | ||
|
|
dd23f452ab | ||
|
|
59c81ed2bb | ||
|
|
96252db787 | ||
|
|
4f0887ce42 | ||
|
|
09c4828ac3 | ||
|
|
fbf891fdff | ||
|
|
82a04dbce1 | ||
|
|
3b99004897 | ||
|
|
1b8c5474da | ||
|
|
09ce4ab893 | ||
|
|
1e1c843b8b | ||
|
|
64832ab65b | ||
|
|
04fb52f6c9 | ||
|
|
8a40f6f234 | ||
|
|
194d5dc8a6 | ||
|
|
a34272cf20 | ||
|
|
7898db5f79 | ||
|
|
e90891059b | ||
|
|
7aed8f8c80 | ||
|
|
cb4cbe2958 | ||
|
|
762f9f4c3e | ||
|
|
6b1b424fc7 | ||
|
|
08fe49f708 | ||
|
|
d281d1b90a | ||
|
|
99505c0f4f | ||
|
|
f4938c0d90 | ||
|
|
96baa83895 | ||
|
|
e6e719699f | ||
|
|
56c63a9b1c | ||
|
|
f666f8e2df | ||
|
|
b546eca26f | ||
|
|
4c527d00c7 | ||
|
|
db89c88f4f | ||
|
|
68a586e52c | ||
|
|
814d07af58 | ||
|
|
a8b55bf874 | ||
|
|
530b2a7685 | ||
|
|
97cdba97ea | ||
|
|
dc42f0a33b | ||
|
|
974a5c22f0 | ||
|
|
ab0bd7a1ee | ||
|
|
40f4eef535 | ||
|
|
ae9be1d94b | ||
|
|
4b877b0a3e | ||
|
|
a6c67a161e | ||
|
|
99a4eaa898 | ||
|
|
44bc222ca4 | ||
|
|
844bf053b2 | ||
|
|
e7bca62c32 | ||
|
|
30e235f0a1 | ||
|
|
e029988bc2 | ||
|
|
42b8867148 | ||
|
|
462d4a1af2 | ||
|
|
e68186d9af | ||
|
|
439ff9d4c4 | ||
|
|
7566a7eae4 | ||
|
|
43ce3f7588 | ||
|
|
33c5c49719 | ||
|
|
614d1817ce | ||
|
|
fef268a7de | ||
|
|
cc1821fb8b | ||
|
|
861552c305 | ||
|
|
16e2c3cc55 | ||
|
|
3896c7a22b | ||
|
|
23488312f5 | ||
|
|
8546387348 | ||
|
|
736aae47a4 | ||
|
|
0749657c73 | ||
|
|
dbae281924 | ||
|
|
76b4591e2b | ||
|
|
cd2aaeda2a | ||
|
|
2d43e13102 | ||
|
|
760f78137d | ||
|
|
93a40cb35e | ||
|
|
df35f8f885 | ||
|
|
98d611623f | ||
|
|
9bc7bef3d6 | ||
|
|
78ba363f8e | ||
|
|
6267909501 | ||
|
|
3443f558a6 | ||
|
|
395645e1ce | ||
|
|
f8e44172f6 | ||
|
|
ebe916b372 | ||
|
|
f31c79d210 | ||
|
|
60bb9d114a | ||
|
|
6fc4c8b099 | ||
|
|
4a7a859592 | ||
|
|
b20d5289cb | ||
|
|
8030e469b2 | ||
|
|
7d292d7fc3 | ||
|
|
e07162e79d | ||
|
|
572c385774 | ||
|
|
7286f8f706 | ||
|
|
7201279647 | ||
|
|
dd2713521e | ||
|
|
2934ab4a3c | ||
|
|
bd1ed26c8d | ||
|
|
fea7e8816f | ||
|
|
65fa19fe92 | ||
|
|
a9e2fc8678 | ||
|
|
b6880c60d3 | ||
|
|
12cfad4858 | ||
|
|
828d467222 | ||
|
|
4b8a5a1a3d | ||
|
|
785310fe18 | ||
|
|
703589c279 | ||
|
|
ba9227184e | ||
|
|
2c4428ee02 | ||
|
|
e80c9f7b74 | ||
|
|
977f281c5c | ||
|
|
875f2db528 | ||
|
|
ecac3a9e10 | ||
|
|
e90989b16b | ||
|
|
3ac6f29e95 | ||
|
|
262daaa2ef | ||
|
|
192df84588 | ||
|
|
b0691806f1 | ||
|
|
dc86d6dac3 | ||
|
|
c4ef5fd325 | ||
|
|
cbe6ad9034 | ||
|
|
44a780f262 | ||
|
|
a0b1f81867 | ||
|
|
109071855d | ||
|
|
5e2fe5f932 | ||
|
|
5c6e56931f | ||
|
|
3483272bbd | ||
|
|
fbee6c820e | ||
|
|
578f2e7c2e | ||
|
|
7aff118c82 | ||
|
|
1bff1ca30a | ||
|
|
fc5c62a5a1 | ||
|
|
ab5b45f615 | ||
|
|
4f20cb7ced | ||
|
|
ad8968c8d9 | ||
|
|
b4a1527aa6 | ||
|
|
2c4f8077fd | ||
|
|
73d0ca0bd5 | ||
|
|
5c16e98d4f | ||
|
|
afaccf924d | ||
|
|
b1fd4b093b | ||
|
|
4c39c4ef9f | ||
|
|
a3b615919e | ||
|
|
76e926453a | ||
|
|
6a0ac2b3a5 | ||
|
|
0dea57c452 | ||
|
|
697ec8e578 | ||
|
|
ced3c99895 | ||
|
|
da8a6417aa | ||
|
|
0301194851 | ||
|
|
9d78bf9086 | ||
|
|
299fc35c37 | ||
|
|
3cfce5a709 | ||
|
|
f44dae75c9 | ||
|
|
6a29088b81 | ||
|
|
919d19f415 | ||
|
|
b7fe29f033 | ||
|
|
b835c40bbd | ||
|
|
781ed2986a | ||
|
|
45668fae15 | ||
|
|
e8c6bfbdeb | ||
|
|
3fa24f7acc | ||
|
|
f076fa4c77 | ||
|
|
c7f515172d | ||
|
|
fb7b86b8e0 | ||
|
|
d0181bb262 | ||
|
|
7c93428a18 | ||
|
|
8c227e2471 | ||
|
|
7ee00d8e57 | ||
|
|
24767d82aa | ||
|
|
e84af6a620 | ||
|
|
6c3c771a52 | ||
|
|
b9b23112bf | ||
|
|
869827d77f | ||
|
|
e69a6f5749 | ||
|
|
6c05e5c67a | ||
|
|
bd9af5569f | ||
|
|
1047840cf8 | ||
|
|
95e3364493 | ||
|
|
a96ba99239 | ||
|
|
619ef54452 | ||
|
|
a161d11920 | ||
|
|
be40683bc5 | ||
|
|
47c058599a | ||
|
|
c1602c848a | ||
|
|
b582c0db86 | ||
|
|
07802a19dc | ||
|
|
629a31ec6e | ||
|
|
f5b28736ce | ||
|
|
04e930073c | ||
|
|
32ebe1895b | ||
|
|
139ad8e95f | ||
|
|
eba2bb275d | ||
|
|
44aaec9020 | ||
|
|
a68c5004f8 | ||
|
|
ee76b398b3 | ||
|
|
bbc733d6c8 | ||
|
|
37b594c0d2 | ||
|
|
545151829d | ||
|
|
2dd2421ad0 | ||
|
|
0a21ad78b1 | ||
|
|
9a01d4e446 | ||
|
|
d3bb254188 |
8
.github/workflows/add-backport-label.yaml
vendored
8
.github/workflows/add-backport-label.yaml
vendored
@@ -62,15 +62,15 @@ jobs:
|
||||
has_backport_needed_label=${{ contains(github.event.pull_request.labels.*.name, 'needs-backport') }}
|
||||
has_no_backport_needed_label=${{ contains(github.event.pull_request.labels.*.name, 'no-backport-needed') }}
|
||||
|
||||
echo "::set-output name=add_backport_label::false"
|
||||
echo "add_backport_label=false" >> $GITHUB_OUTPUT
|
||||
if [ $has_backport_needed_label = true ] || [ $has_bug = true ]; then
|
||||
if [[ $has_no_backport_needed_label = false ]]; then
|
||||
echo "::set-output name=add_backport_label::true"
|
||||
echo "add_backport_label=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
fi
|
||||
|
||||
# Do not spam comment, only if auto-backport label is going to be newly added.
|
||||
echo "::set-output name=auto_backport_added::$CONTAINS_AUTO_BACKPORT"
|
||||
echo "auto_backport_added=$CONTAINS_AUTO_BACKPORT" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Add comment
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') && steps.add_label.outputs.add_backport_label == 'true' && steps.add_label.outputs.auto_backport_added == 'false' }}
|
||||
@@ -97,4 +97,4 @@ jobs:
|
||||
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90
|
||||
with:
|
||||
add-labels: "auto-backport"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
85
.github/workflows/build-kata-static-tarball-amd64.yaml
vendored
Normal file
85
.github/workflows/build-kata-static-tarball-amd64.yaml
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
name: CI | Build kata-static tarball for amd64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
push-to-registry:
|
||||
required: false
|
||||
type: string
|
||||
default: no
|
||||
|
||||
jobs:
|
||||
build-asset:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- cloud-hypervisor
|
||||
- firecracker
|
||||
- kernel
|
||||
- kernel-sev
|
||||
- kernel-dragonball-experimental
|
||||
- kernel-tdx-experimental
|
||||
- kernel-nvidia-gpu
|
||||
- kernel-nvidia-gpu-snp
|
||||
- kernel-nvidia-gpu-tdx-experimental
|
||||
- nydus
|
||||
- ovmf
|
||||
- ovmf-sev
|
||||
- qemu
|
||||
- qemu-snp-experimental
|
||||
- qemu-tdx-experimental
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- rootfs-initrd-sev
|
||||
- shim-v2
|
||||
- tdvf
|
||||
- virtiofsd
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0 # This is needed in order to keep the commit ids history
|
||||
- name: Build ${{ matrix.asset }}
|
||||
run: |
|
||||
make "${KATA_ASSET}-tarball"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r "${build_dir}" "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
TAR_OUTPUT: ${{ matrix.asset }}.tar.gz
|
||||
PUSH_TO_REGISTRY: ${{ inputs.push-to-registry }}
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-amd64${{ inputs.tarball-suffix }}
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-asset
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: get-artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-amd64${{ inputs.tarball-suffix }}
|
||||
path: kata-artifacts
|
||||
- name: merge-artifacts
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-merge-builds.sh kata-artifacts
|
||||
- name: store-artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-amd64${{ inputs.tarball-suffix }}
|
||||
path: kata-static.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
82
.github/workflows/build-kata-static-tarball-arm64.yaml
vendored
Normal file
82
.github/workflows/build-kata-static-tarball-arm64.yaml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: CI | Build kata-static tarball for arm64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
push-to-registry:
|
||||
required: false
|
||||
type: string
|
||||
default: no
|
||||
|
||||
jobs:
|
||||
build-asset:
|
||||
runs-on: arm64
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- cloud-hypervisor
|
||||
- firecracker
|
||||
- kernel
|
||||
- kernel-dragonball-experimental
|
||||
- nydus
|
||||
- qemu
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- shim-v2
|
||||
- virtiofsd
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0 # This is needed in order to keep the commit ids history
|
||||
- name: Build ${{ matrix.asset }}
|
||||
run: |
|
||||
make "${KATA_ASSET}-tarball"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r "${build_dir}" "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
TAR_OUTPUT: ${{ matrix.asset }}.tar.gz
|
||||
PUSH_TO_REGISTRY: ${{ inputs.push-to-registry }}
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-arm64${{ inputs.tarball-suffix }}
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: arm64
|
||||
needs: build-asset
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: get-artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-arm64${{ inputs.tarball-suffix }}
|
||||
path: kata-artifacts
|
||||
- name: merge-artifacts
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-merge-builds.sh kata-artifacts
|
||||
- name: store-artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-arm64${{ inputs.tarball-suffix }}
|
||||
path: kata-static.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
79
.github/workflows/build-kata-static-tarball-s390x.yaml
vendored
Normal file
79
.github/workflows/build-kata-static-tarball-s390x.yaml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
name: CI | Build kata-static tarball for s390x
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
push-to-registry:
|
||||
required: false
|
||||
type: string
|
||||
default: no
|
||||
|
||||
jobs:
|
||||
build-asset:
|
||||
runs-on: s390x
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- kernel
|
||||
- qemu
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- shim-v2
|
||||
- virtiofsd
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0 # This is needed in order to keep the commit ids history
|
||||
- name: Build ${{ matrix.asset }}
|
||||
run: |
|
||||
make "${KATA_ASSET}-tarball"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r "${build_dir}" "kata-build"
|
||||
sudo chown -R $(id -u):$(id -g) "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
TAR_OUTPUT: ${{ matrix.asset }}.tar.gz
|
||||
PUSH_TO_REGISTRY: ${{ inputs.push-to-registry }}
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-s390x${{ inputs.tarball-suffix }}
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: s390x
|
||||
needs: build-asset
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: get-artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-artifacts-s390x${{ inputs.tarball-suffix }}
|
||||
path: kata-artifacts
|
||||
- name: merge-artifacts
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-merge-builds.sh kata-artifacts
|
||||
- name: store-artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-s390x${{ inputs.tarball-suffix }}
|
||||
path: kata-static.tar.xz
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
54
.github/workflows/ci-on-push.yaml
vendored
Normal file
54
.github/workflows/ci-on-push.yaml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Kata Containers CI
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
build-kata-static-tarball-amd64:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-amd64.yaml
|
||||
with:
|
||||
tarball-suffix: -${{ github.event.pull_request.number}}-${{ github.event.pull_request.head.sha }}
|
||||
|
||||
publish-kata-deploy-payload-amd64:
|
||||
needs: build-kata-static-tarball-amd64
|
||||
uses: ./.github/workflows/publish-kata-deploy-payload-amd64.yaml
|
||||
with:
|
||||
tarball-suffix: -${{ github.event.pull_request.number}}-${{ github.event.pull_request.head.sha }}
|
||||
registry: ghcr.io
|
||||
repo: ${{ github.repository_owner }}/kata-deploy-ci
|
||||
tag: ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-amd64
|
||||
secrets: inherit
|
||||
|
||||
run-k8s-tests-on-aks:
|
||||
needs: publish-kata-deploy-payload-amd64
|
||||
uses: ./.github/workflows/run-k8s-tests-on-aks.yaml
|
||||
with:
|
||||
registry: ghcr.io
|
||||
repo: ${{ github.repository_owner }}/kata-deploy-ci
|
||||
tag: ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-amd64
|
||||
secrets: inherit
|
||||
|
||||
run-k8s-tests-on-sev:
|
||||
needs: publish-kata-deploy-payload-amd64
|
||||
uses: ./.github/workflows/run-k8s-tests-on-sev.yaml
|
||||
with:
|
||||
registry: ghcr.io
|
||||
repo: ${{ github.repository_owner }}/kata-deploy-ci
|
||||
tag: ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-amd64
|
||||
|
||||
run-k8s-tests-on-snp:
|
||||
needs: publish-kata-deploy-payload-amd64
|
||||
uses: ./.github/workflows/run-k8s-tests-on-snp.yaml
|
||||
with:
|
||||
registry: ghcr.io
|
||||
repo: ${{ github.repository_owner }}/kata-deploy-ci
|
||||
tag: ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-amd64
|
||||
|
||||
run-k8s-tests-on-tdx:
|
||||
needs: publish-kata-deploy-payload-amd64
|
||||
uses: ./.github/workflows/run-k8s-tests-on-tdx.yaml
|
||||
with:
|
||||
registry: ghcr.io
|
||||
repo: ${{ github.repository_owner }}/kata-deploy-ci
|
||||
tag: ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-amd64
|
||||
5
.github/workflows/commit-message-check.yaml
vendored
5
.github/workflows/commit-message-check.yaml
vendored
@@ -62,6 +62,9 @@ jobs:
|
||||
# to be specified at the start of the regex as the action is passed
|
||||
# the entire commit message.
|
||||
#
|
||||
# - This check will pass if the commit message only contains a subject
|
||||
# line, as other body message properties are enforced elsewhere.
|
||||
#
|
||||
# - Body lines *can* be longer than the maximum if they start
|
||||
# with a non-alphabetic character or if there is no whitespace in
|
||||
# the line.
|
||||
@@ -75,7 +78,7 @@ jobs:
|
||||
#
|
||||
# - A SoB comment can be any length (as it is unreasonable to penalise
|
||||
# people with long names/email addresses :)
|
||||
pattern: '^.+(\n([a-zA-Z].{0,150}|[^a-zA-Z\n].*|[^\s\n]*|Signed-off-by:.*|))+$'
|
||||
pattern: '(^[^\n]+$|^.+(\n([a-zA-Z].{0,150}|[^a-zA-Z\n].*|[^\s\n]*|Signed-off-by:.*|))+$)'
|
||||
error: 'Body line too long (max 150)'
|
||||
post_error: ${{ env.error_msg }}
|
||||
|
||||
|
||||
80
.github/workflows/kata-deploy-push.yaml
vendored
80
.github/workflows/kata-deploy-push.yaml
vendored
@@ -1,80 +0,0 @@
|
||||
name: kata deploy build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- reopened
|
||||
- synchronize
|
||||
paths:
|
||||
- tools/**
|
||||
- versions.yaml
|
||||
|
||||
jobs:
|
||||
build-asset:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- kernel
|
||||
- kernel-dragonball-experimental
|
||||
- shim-v2
|
||||
- qemu
|
||||
- cloud-hypervisor
|
||||
- firecracker
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- virtiofsd
|
||||
- nydus
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build ${{ matrix.asset }}
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
make "${KATA_ASSET}-tarball"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r --preserve=all "${build_dir}" "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-asset
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: get-artifacts
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: build
|
||||
- name: merge-artifacts
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
make merge-builds
|
||||
- name: store-artifacts
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
path: kata-static.tar.xz
|
||||
|
||||
make-kata-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: make kata-tarball
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
make kata-tarball
|
||||
sudo make install-tarball
|
||||
164
.github/workflows/kata-deploy-test.yaml
vendored
164
.github/workflows/kata-deploy-test.yaml
vendored
@@ -1,164 +0,0 @@
|
||||
on:
|
||||
workflow_dispatch: # this is used to trigger the workflow on non-main branches
|
||||
inputs:
|
||||
pr:
|
||||
description: 'PR number from the selected branch to test'
|
||||
type: string
|
||||
required: true
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
name: test-kata-deploy
|
||||
|
||||
jobs:
|
||||
check-comment-and-membership:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.issue.pull_request
|
||||
&& github.event_name == 'issue_comment'
|
||||
&& github.event.action == 'created'
|
||||
&& startsWith(github.event.comment.body, '/test_kata_deploy')
|
||||
|| github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
- name: Check membership on comment or dispatch
|
||||
uses: kata-containers/is-organization-member@1.0.1
|
||||
id: is_organization_member
|
||||
with:
|
||||
organization: kata-containers
|
||||
username: ${{ github.event.comment.user.login || github.event.sender.login }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Fail if not member
|
||||
run: |
|
||||
result=${{ steps.is_organization_member.outputs.result }}
|
||||
if [ $result == false ]; then
|
||||
user=${{ github.event.comment.user.login || github.event.sender.login }}
|
||||
echo Either ${user} is not part of the kata-containers organization
|
||||
echo or ${user} has its Organization Visibility set to Private at
|
||||
echo https://github.com/orgs/kata-containers/people?query=${user}
|
||||
echo
|
||||
echo Ensure you change your Organization Visibility to Public and
|
||||
echo trigger the test again.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build-asset:
|
||||
runs-on: ubuntu-latest
|
||||
needs: check-comment-and-membership
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- cloud-hypervisor
|
||||
- firecracker
|
||||
- kernel
|
||||
- kernel-dragonball-experimental
|
||||
- nydus
|
||||
- qemu
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- shim-v2
|
||||
- virtiofsd
|
||||
steps:
|
||||
- name: get-PR-ref
|
||||
id: get-PR-ref
|
||||
run: |
|
||||
if [ ${{ github.event_name }} == 'issue_comment' ]; then
|
||||
ref=$(cat $GITHUB_EVENT_PATH | jq -r '.issue.pull_request.url' | sed 's#^.*\/pulls#refs\/pull#' | sed 's#$#\/merge#')
|
||||
else # workflow_dispatch
|
||||
ref="refs/pull/${{ github.event.inputs.pr }}/merge"
|
||||
fi
|
||||
echo "reference for PR: " ${ref} "event:" ${{ github.event_name }}
|
||||
echo "##[set-output name=pr-ref;]${ref}"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ steps.get-PR-ref.outputs.pr-ref }}
|
||||
|
||||
- name: Build ${{ matrix.asset }}
|
||||
run: |
|
||||
make "${KATA_ASSET}-tarball"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r "${build_dir}" "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
TAR_OUTPUT: ${{ matrix.asset }}.tar.gz
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-asset
|
||||
steps:
|
||||
- name: get-PR-ref
|
||||
id: get-PR-ref
|
||||
run: |
|
||||
if [ ${{ github.event_name }} == 'issue_comment' ]; then
|
||||
ref=$(cat $GITHUB_EVENT_PATH | jq -r '.issue.pull_request.url' | sed 's#^.*\/pulls#refs\/pull#' | sed 's#$#\/merge#')
|
||||
else # workflow_dispatch
|
||||
ref="refs/pull/${{ github.event.inputs.pr }}/merge"
|
||||
fi
|
||||
echo "reference for PR: " ${ref} "event:" ${{ github.event_name }}
|
||||
echo "##[set-output name=pr-ref;]${ref}"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ steps.get-PR-ref.outputs.pr-ref }}
|
||||
- name: get-artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: kata-artifacts
|
||||
- name: merge-artifacts
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-merge-builds.sh kata-artifacts
|
||||
- name: store-artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
path: kata-static.tar.xz
|
||||
|
||||
kata-deploy:
|
||||
needs: create-kata-tarball
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: get-PR-ref
|
||||
id: get-PR-ref
|
||||
run: |
|
||||
if [ ${{ github.event_name }} == 'issue_comment' ]; then
|
||||
ref=$(cat $GITHUB_EVENT_PATH | jq -r '.issue.pull_request.url' | sed 's#^.*\/pulls#refs\/pull#' | sed 's#$#\/merge#')
|
||||
else # workflow_dispatch
|
||||
ref="refs/pull/${{ github.event.inputs.pr }}/merge"
|
||||
fi
|
||||
echo "reference for PR: " ${ref} "event:" ${{ github.event_name }}
|
||||
echo "##[set-output name=pr-ref;]${ref}"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ steps.get-PR-ref.outputs.pr-ref }}
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
- name: build-and-push-kata-deploy-ci
|
||||
id: build-and-push-kata-deploy-ci
|
||||
run: |
|
||||
PR_SHA=$(git log --format=format:%H -n1)
|
||||
mv kata-static.tar.xz $GITHUB_WORKSPACE/tools/packaging/kata-deploy/kata-static.tar.xz
|
||||
docker build --build-arg KATA_ARTIFACTS=kata-static.tar.xz -t quay.io/kata-containers/kata-deploy-ci:$PR_SHA $GITHUB_WORKSPACE/tools/packaging/kata-deploy
|
||||
docker login -u ${{ secrets.QUAY_DEPLOYER_USERNAME }} -p ${{ secrets.QUAY_DEPLOYER_PASSWORD }} quay.io
|
||||
docker push quay.io/kata-containers/kata-deploy-ci:$PR_SHA
|
||||
mkdir -p packaging/kata-deploy
|
||||
ln -s $GITHUB_WORKSPACE/tools/packaging/kata-deploy/action packaging/kata-deploy/action
|
||||
echo "::set-output name=PKG_SHA::${PR_SHA}"
|
||||
- name: test-kata-deploy-ci-in-aks
|
||||
uses: ./packaging/kata-deploy/action
|
||||
with:
|
||||
packaging-sha: ${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}}
|
||||
env:
|
||||
PKG_SHA: ${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}}
|
||||
AZ_APPID: ${{ secrets.AZ_APPID }}
|
||||
AZ_PASSWORD: ${{ secrets.AZ_PASSWORD }}
|
||||
AZ_SUBSCRIPTION_ID: ${{ secrets.AZ_SUBSCRIPTION_ID }}
|
||||
AZ_TENANT_ID: ${{ secrets.AZ_TENANT_ID }}
|
||||
71
.github/workflows/payload-after-push.yaml
vendored
Normal file
71
.github/workflows/payload-after-push.yaml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: CI | Publish Kata Containers payload
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- stable-*
|
||||
|
||||
jobs:
|
||||
build-assets-amd64:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-amd64.yaml
|
||||
with:
|
||||
push-to-registry: yes
|
||||
|
||||
build-assets-arm64:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-arm64.yaml
|
||||
with:
|
||||
push-to-registry: yes
|
||||
|
||||
build-assets-s390x:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-s390x.yaml
|
||||
with:
|
||||
push-to-registry: yes
|
||||
|
||||
publish-kata-deploy-payload-amd64:
|
||||
needs: build-assets-amd64
|
||||
uses: ./.github/workflows/publish-kata-deploy-payload-amd64.yaml
|
||||
with:
|
||||
registry: quay.io
|
||||
repo: kata-containers/kata-deploy-ci
|
||||
tag: kata-containers-amd64
|
||||
secrets: inherit
|
||||
|
||||
publish-kata-deploy-payload-arm64:
|
||||
needs: build-assets-arm64
|
||||
uses: ./.github/workflows/publish-kata-deploy-payload-arm64.yaml
|
||||
with:
|
||||
registry: quay.io
|
||||
repo: kata-containers/kata-deploy-ci
|
||||
tag: kata-containers-arm64
|
||||
secrets: inherit
|
||||
|
||||
publish-kata-deploy-payload-s390x:
|
||||
needs: build-assets-s390x
|
||||
uses: ./.github/workflows/publish-kata-deploy-payload-s390x.yaml
|
||||
with:
|
||||
registry: quay.io
|
||||
repo: kata-containers/kata-deploy-ci
|
||||
tag: kata-containers-s390x
|
||||
secrets: inherit
|
||||
|
||||
publish-manifest:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [publish-kata-deploy-payload-amd64, publish-kata-deploy-payload-arm64, publish-kata-deploy-payload-s390x]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- name: Push multi-arch manifest
|
||||
run: |
|
||||
docker manifest create quay.io/kata-containers/kata-deploy-ci:kata-containers-latest \
|
||||
--amend quay.io/kata-containers/kata-deploy-ci:kata-containers-amd64 \
|
||||
--amend quay.io/kata-containers/kata-deploy-ci:kata-containers-arm64 \
|
||||
--amend quay.io/kata-containers/kata-deploy-ci:kata-containers-s390x
|
||||
docker manifest push quay.io/kata-containers/kata-deploy-ci:kata-containers-latest
|
||||
52
.github/workflows/publish-kata-deploy-payload-amd64.yaml
vendored
Normal file
52
.github/workflows/publish-kata-deploy-payload-amd64.yaml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: CI | Publish kata-deploy payload for amd64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
kata-payload:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-amd64${{ inputs.tarball-suffix }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
if: ${{ inputs.registry == 'quay.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers ghcr.io
|
||||
if: ${{ inputs.registry == 'ghcr.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: build-and-push-kata-payload
|
||||
id: build-and-push-kata-payload
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz \
|
||||
${{ inputs.registry }}/${{ inputs.repo }} ${{ inputs.tag }}
|
||||
57
.github/workflows/publish-kata-deploy-payload-arm64.yaml
vendored
Normal file
57
.github/workflows/publish-kata-deploy-payload-arm64.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: CI | Publish kata-deploy payload for arm64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
kata-payload:
|
||||
runs-on: arm64
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-arm64${{ inputs.tarball-suffix }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
if: ${{ inputs.registry == 'quay.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers ghcr.io
|
||||
if: ${{ inputs.registry == 'ghcr.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: build-and-push-kata-payload
|
||||
id: build-and-push-kata-payload
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz \
|
||||
${{ inputs.registry }}/${{ inputs.repo }} ${{ inputs.tag }}
|
||||
|
||||
56
.github/workflows/publish-kata-deploy-payload-s390x.yaml
vendored
Normal file
56
.github/workflows/publish-kata-deploy-payload-s390x.yaml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: CI | Publish kata-deploy payload for s390x
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tarball-suffix:
|
||||
required: false
|
||||
type: string
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
kata-payload:
|
||||
runs-on: s390x
|
||||
steps:
|
||||
- name: Adjust a permission for repo
|
||||
run: |
|
||||
sudo chown -R $USER:$USER $GITHUB_WORKSPACE
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-s390x${{ inputs.tarball-suffix }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
if: ${{ inputs.registry == 'quay.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers ghcr.io
|
||||
if: ${{ inputs.registry == 'ghcr.io' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: build-and-push-kata-payload
|
||||
id: build-and-push-kata-payload
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz \
|
||||
${{ inputs.registry }}/${{ inputs.repo }} ${{ inputs.tag }}
|
||||
63
.github/workflows/release-amd64.yaml
vendored
Normal file
63
.github/workflows/release-amd64.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Publish Kata release artifacts for amd64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
target-arch:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-kata-static-tarball-amd64:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-amd64.yaml
|
||||
|
||||
kata-deploy:
|
||||
needs: build-kata-static-tarball-amd64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Login to Kata Containers docker.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-amd64
|
||||
|
||||
- name: build-and-push-kata-deploy-ci-amd64
|
||||
id: build-and-push-kata-deploy-ci-amd64
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
pushd $GITHUB_WORKSPACE
|
||||
git checkout $tag
|
||||
pkg_sha=$(git rev-parse HEAD)
|
||||
popd
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "docker.io/katadocker/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "quay.io/kata-containers/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
|
||||
- name: push-tarball
|
||||
run: |
|
||||
# tag the container image we created and push to DockerHub
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tags=($tag)
|
||||
tags+=($([[ "$tag" =~ "alpha"|"rc" ]] && echo "latest" || echo "stable"))
|
||||
for tag in ${tags[@]}; do
|
||||
docker tag docker.io/katadocker/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-amd64.outputs.PKG_SHA}}-${{ inputs.target-arch }} docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker tag quay.io/kata-containers/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-amd64.outputs.PKG_SHA}}-${{ inputs.target-arch }} quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
done
|
||||
63
.github/workflows/release-arm64.yaml
vendored
Normal file
63
.github/workflows/release-arm64.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Publish Kata release artifacts for arm64
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
target-arch:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-kata-static-tarball-arm64:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-arm64.yaml
|
||||
|
||||
kata-deploy:
|
||||
needs: build-kata-static-tarball-arm64
|
||||
runs-on: arm64
|
||||
steps:
|
||||
- name: Login to Kata Containers docker.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-arm64
|
||||
|
||||
- name: build-and-push-kata-deploy-ci-arm64
|
||||
id: build-and-push-kata-deploy-ci-arm64
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
pushd $GITHUB_WORKSPACE
|
||||
git checkout $tag
|
||||
pkg_sha=$(git rev-parse HEAD)
|
||||
popd
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "docker.io/katadocker/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "quay.io/kata-containers/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
|
||||
- name: push-tarball
|
||||
run: |
|
||||
# tag the container image we created and push to DockerHub
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tags=($tag)
|
||||
tags+=($([[ "$tag" =~ "alpha"|"rc" ]] && echo "latest" || echo "stable"))
|
||||
for tag in ${tags[@]}; do
|
||||
docker tag docker.io/katadocker/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-arm64.outputs.PKG_SHA}}-${{ inputs.target-arch }} docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker tag quay.io/kata-containers/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-arm64.outputs.PKG_SHA}}-${{ inputs.target-arch }} quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
done
|
||||
63
.github/workflows/release-s390x.yaml
vendored
Normal file
63
.github/workflows/release-s390x.yaml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Publish Kata release artifacts for s390x
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
target-arch:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-kata-static-tarball-s390x:
|
||||
uses: ./.github/workflows/build-kata-static-tarball-s390x.yaml
|
||||
|
||||
kata-deploy:
|
||||
needs: create-kata-tarball
|
||||
runs-on: s390x
|
||||
steps:
|
||||
- name: Login to Kata Containers docker.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-s390x
|
||||
|
||||
- name: build-and-push-kata-deploy-ci-s390x
|
||||
id: build-and-push-kata-deploy-ci-s390x
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
pushd $GITHUB_WORKSPACE
|
||||
git checkout $tag
|
||||
pkg_sha=$(git rev-parse HEAD)
|
||||
popd
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "docker.io/katadocker/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \
|
||||
$(pwd)/kata-static.tar.xz "quay.io/kata-containers/kata-deploy-ci" \
|
||||
"${pkg_sha}-${{ inputs.target-arch }}"
|
||||
|
||||
- name: push-tarball
|
||||
run: |
|
||||
# tag the container image we created and push to DockerHub
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tags=($tag)
|
||||
tags+=($([[ "$tag" =~ "alpha"|"rc" ]] && echo "latest" || echo "stable"))
|
||||
for tag in ${tags[@]}; do
|
||||
docker tag docker.io/katadocker/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-s390x.outputs.PKG_SHA}}-${{ inputs.target-arch }} docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker tag quay.io/kata-containers/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci-s390x.outputs.PKG_SHA}}-${{ inputs.target-arch }} quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push docker.io/katadocker/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
docker push quay.io/kata-containers/kata-deploy:${tag}-${{ inputs.target-arch }}
|
||||
done
|
||||
187
.github/workflows/release.yaml
vendored
187
.github/workflows/release.yaml
vendored
@@ -5,124 +5,83 @@ on:
|
||||
- '[0-9]+.[0-9]+.[0-9]+*'
|
||||
|
||||
jobs:
|
||||
build-asset:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
asset:
|
||||
- cloud-hypervisor
|
||||
- firecracker
|
||||
- kernel
|
||||
- kernel-dragonball-experimental
|
||||
- nydus
|
||||
- qemu
|
||||
- rootfs-image
|
||||
- rootfs-initrd
|
||||
- shim-v2
|
||||
- virtiofsd
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build ${{ matrix.asset }}
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-copy-yq-installer.sh
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-binaries-in-docker.sh --build="${KATA_ASSET}"
|
||||
build_dir=$(readlink -f build)
|
||||
# store-artifact does not work with symlink
|
||||
sudo cp -r "${build_dir}" "kata-build"
|
||||
env:
|
||||
KATA_ASSET: ${{ matrix.asset }}
|
||||
TAR_OUTPUT: ${{ matrix.asset }}.tar.gz
|
||||
build-and-push-assets-amd64:
|
||||
uses: ./.github/workflows/release-amd64.yaml
|
||||
with:
|
||||
target-arch: amd64
|
||||
secrets: inherit
|
||||
|
||||
- name: store-artifact ${{ matrix.asset }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: kata-build/kata-static-${{ matrix.asset }}.tar.xz
|
||||
if-no-files-found: error
|
||||
build-and-push-assets-arm64:
|
||||
uses: ./.github/workflows/release-arm64.yaml
|
||||
with:
|
||||
target-arch: arm64
|
||||
secrets: inherit
|
||||
|
||||
create-kata-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-asset
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: get-artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kata-artifacts
|
||||
path: kata-artifacts
|
||||
- name: merge-artifacts
|
||||
run: |
|
||||
./tools/packaging/kata-deploy/local-build/kata-deploy-merge-builds.sh kata-artifacts
|
||||
- name: store-artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
path: kata-static.tar.xz
|
||||
build-and-push-assets-s390x:
|
||||
uses: ./.github/workflows/release-s390x.yaml
|
||||
with:
|
||||
target-arch: s390x
|
||||
secrets: inherit
|
||||
|
||||
kata-deploy:
|
||||
needs: create-kata-tarball
|
||||
publish-multi-arch-images:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-and-push-assets-amd64, build-and-push-assets-arm64, build-and-push-assets-s390x]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: get-kata-tarball
|
||||
uses: actions/download-artifact@v2
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Login to Kata Containers docker.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
- name: build-and-push-kata-deploy-ci
|
||||
id: build-and-push-kata-deploy-ci
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
pushd $GITHUB_WORKSPACE
|
||||
git checkout $tag
|
||||
pkg_sha=$(git rev-parse HEAD)
|
||||
popd
|
||||
mv kata-static.tar.xz $GITHUB_WORKSPACE/tools/packaging/kata-deploy/kata-static.tar.xz
|
||||
docker build --build-arg KATA_ARTIFACTS=kata-static.tar.xz -t katadocker/kata-deploy-ci:$pkg_sha -t quay.io/kata-containers/kata-deploy-ci:$pkg_sha $GITHUB_WORKSPACE/tools/packaging/kata-deploy
|
||||
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
docker push katadocker/kata-deploy-ci:$pkg_sha
|
||||
docker login -u ${{ secrets.QUAY_DEPLOYER_USERNAME }} -p ${{ secrets.QUAY_DEPLOYER_PASSWORD }} quay.io
|
||||
docker push quay.io/kata-containers/kata-deploy-ci:$pkg_sha
|
||||
mkdir -p packaging/kata-deploy
|
||||
ln -s $GITHUB_WORKSPACE/tools/packaging/kata-deploy/action packaging/kata-deploy/action
|
||||
echo "::set-output name=PKG_SHA::${pkg_sha}"
|
||||
- name: test-kata-deploy-ci-in-aks
|
||||
uses: ./packaging/kata-deploy/action
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to Kata Containers quay.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
packaging-sha: ${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}}
|
||||
env:
|
||||
PKG_SHA: ${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}}
|
||||
AZ_APPID: ${{ secrets.AZ_APPID }}
|
||||
AZ_PASSWORD: ${{ secrets.AZ_PASSWORD }}
|
||||
AZ_SUBSCRIPTION_ID: ${{ secrets.AZ_SUBSCRIPTION_ID }}
|
||||
AZ_TENANT_ID: ${{ secrets.AZ_TENANT_ID }}
|
||||
- name: push-tarball
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_DEPLOYER_USERNAME }}
|
||||
password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }}
|
||||
|
||||
- name: Push multi-arch manifest
|
||||
run: |
|
||||
# tag the container image we created and push to DockerHub
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tags=($tag)
|
||||
tags+=($([[ "$tag" =~ "alpha"|"rc" ]] && echo "latest" || echo "stable"))
|
||||
for tag in ${tags[@]}; do \
|
||||
docker tag katadocker/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}} katadocker/kata-deploy:${tag} && \
|
||||
docker tag quay.io/kata-containers/kata-deploy-ci:${{steps.build-and-push-kata-deploy-ci.outputs.PKG_SHA}} quay.io/kata-containers/kata-deploy:${tag} && \
|
||||
docker push katadocker/kata-deploy:${tag} && \
|
||||
docker push quay.io/kata-containers/kata-deploy:${tag}; \
|
||||
# push to quay.io and docker.io
|
||||
for tag in ${tags[@]}; do
|
||||
docker manifest create quay.io/kata-containers/kata-deploy:${tag} \
|
||||
--amend quay.io/kata-containers/kata-deploy:${tag}-amd64 \
|
||||
--amend quay.io/kata-containers/kata-deploy:${tag}-arm64 \
|
||||
--amend quay.io/kata-containers/kata-deploy:${tag}-s390x
|
||||
|
||||
docker manifest create docker.io/katadocker/kata-deploy:${tag} \
|
||||
--amend docker.io/katadocker/kata-deploy:${tag}-amd64 \
|
||||
--amend docker.io/katadocker/kata-deploy:${tag}-arm64 \
|
||||
--amend docker.io/katadocker/kata-deploy:${tag}-s390x
|
||||
|
||||
docker manifest push quay.io/kata-containers/kata-deploy:${tag}
|
||||
docker manifest push docker.io/katadocker/kata-deploy:${tag}
|
||||
done
|
||||
|
||||
upload-static-tarball:
|
||||
needs: kata-deploy
|
||||
upload-multi-arch-static-tarball:
|
||||
needs: publish-multi-arch-images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: download-artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: kata-static-tarball
|
||||
- uses: actions/checkout@v3
|
||||
- name: install hub
|
||||
run: |
|
||||
HUB_VER=$(curl -s "https://api.github.com/repos/github/hub/releases/latest" | jq -r .tag_name | sed 's/^v//')
|
||||
wget -q -O- https://github.com/github/hub/releases/download/v$HUB_VER/hub-linux-amd64-$HUB_VER.tgz | \
|
||||
tar xz --strip-components=2 --wildcards '*/bin/hub' && sudo mv hub /usr/local/bin/hub
|
||||
- name: push static tarball to github
|
||||
|
||||
- name: download-artifacts-amd64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-amd64
|
||||
- name: push amd64 static tarball to github
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tarball="kata-static-$tag-x86_64.tar.xz"
|
||||
@@ -132,11 +91,39 @@ jobs:
|
||||
GITHUB_TOKEN=${{ secrets.GIT_UPLOAD_TOKEN }} hub release edit -m "" -a "${tarball}" "${tag}"
|
||||
popd
|
||||
|
||||
- name: download-artifacts-arm64
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-arm64
|
||||
- name: push arm64 static tarball to github
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tarball="kata-static-$tag-aarch64.tar.xz"
|
||||
mv kata-static.tar.xz "$GITHUB_WORKSPACE/${tarball}"
|
||||
pushd $GITHUB_WORKSPACE
|
||||
echo "uploading asset '${tarball}' for tag: ${tag}"
|
||||
GITHUB_TOKEN=${{ secrets.GIT_UPLOAD_TOKEN }} hub release edit -m "" -a "${tarball}" "${tag}"
|
||||
popd
|
||||
|
||||
- name: download-artifacts-s390x
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: kata-static-tarball-s390x
|
||||
- name: push s390x static tarball to github
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
tarball="kata-static-$tag-s390x.tar.xz"
|
||||
mv kata-static.tar.xz "$GITHUB_WORKSPACE/${tarball}"
|
||||
pushd $GITHUB_WORKSPACE
|
||||
echo "uploading asset '${tarball}' for tag: ${tag}"
|
||||
GITHUB_TOKEN=${{ secrets.GIT_UPLOAD_TOKEN }} hub release edit -m "" -a "${tarball}" "${tag}"
|
||||
popd
|
||||
|
||||
upload-cargo-vendored-tarball:
|
||||
needs: upload-static-tarball
|
||||
needs: upload-multi-arch-static-tarball
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: generate-and-upload-tarball
|
||||
run: |
|
||||
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
|
||||
@@ -150,7 +137,7 @@ jobs:
|
||||
needs: upload-cargo-vendored-tarball
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: download-and-upload-tarball
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GIT_UPLOAD_TOKEN }}
|
||||
|
||||
95
.github/workflows/run-k8s-tests-on-aks.yaml
vendored
Normal file
95
.github/workflows/run-k8s-tests-on-aks.yaml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
name: CI | Run kubernetes tests on AKS
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run-k8s-tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
vmm:
|
||||
- clh
|
||||
- dragonball
|
||||
- qemu
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Download Azure CLI
|
||||
run: |
|
||||
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
|
||||
|
||||
- name: Log into the Azure account
|
||||
run: |
|
||||
az login \
|
||||
--service-principal \
|
||||
-u "${{ secrets.AZ_APPID }}" \
|
||||
-p "${{ secrets.AZ_PASSWORD }}" \
|
||||
--tenant "${{ secrets.AZ_TENANT_ID }}"
|
||||
|
||||
- name: Create AKS cluster
|
||||
run: |
|
||||
az aks create \
|
||||
-g "kataCI" \
|
||||
-n "${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-${{ matrix.vmm }}-amd64" \
|
||||
-s "Standard_D4s_v5" \
|
||||
--node-count 1 \
|
||||
--generate-ssh-keys
|
||||
|
||||
- name: Install `bats`
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install bats
|
||||
|
||||
- name: Install `kubectl`
|
||||
run: |
|
||||
sudo az aks install-cli
|
||||
|
||||
- name: Download credentials for the Kubernetes CLI to use them
|
||||
run: |
|
||||
az aks get-credentials -g "kataCI" -n ${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-${{ matrix.vmm }}-amd64
|
||||
|
||||
- name: Run tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
kubectl -n kube-system wait --timeout=10m --for=condition=Ready -l name=kata-deploy pod
|
||||
kubectl apply -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
|
||||
# This is needed as the kata-deploy pod will be set to "Ready" when it starts running,
|
||||
# which may cause issues like not having the node properly labeled or the artefacts
|
||||
# properly deployed when the tests actually start running.
|
||||
sleep 60s
|
||||
|
||||
pushd tests/integration/kubernetes
|
||||
sed -i -e 's|runtimeClassName: kata|runtimeClassName: kata-${{ matrix.vmm }}|' runtimeclass_workloads/*.yaml
|
||||
bash run_kubernetes_tests.sh
|
||||
popd
|
||||
env:
|
||||
KATA_HYPERVISOR: ${{ matrix.vmm }}
|
||||
|
||||
- name: Delete AKS cluster
|
||||
if: always()
|
||||
run: |
|
||||
az aks delete \
|
||||
-g "kataCI" \
|
||||
-n "${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-${{ matrix.vmm }}-amd64" \
|
||||
--yes \
|
||||
--no-wait
|
||||
68
.github/workflows/run-k8s-tests-on-sev.yaml
vendored
Normal file
68
.github/workflows/run-k8s-tests-on-sev.yaml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: CI | Run kubernetes tests on SEV
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run-k8s-tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
vmm:
|
||||
- qemu-sev
|
||||
runs-on: sev
|
||||
env:
|
||||
KUBECONFIG: /home/kata/.kube/config
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Run tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
kubectl -n kube-system wait --timeout=10m --for=condition=Ready -l name=kata-deploy pod
|
||||
kubectl apply -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
|
||||
# This is needed as the kata-deploy pod will be set to "Ready" when it starts running,
|
||||
# which may cause issues like not having the node properly labeled or the artefacts
|
||||
# properly deployed when the tests actually start running.
|
||||
sleep 60s
|
||||
|
||||
pushd tests/integration/kubernetes
|
||||
sed -i -e 's|runtimeClassName: kata|runtimeClassName: kata-${{ matrix.vmm }}|' runtimeclass_workloads/*.yaml
|
||||
bash run_kubernetes_tests.sh
|
||||
popd
|
||||
env:
|
||||
KATA_HYPERVISOR: ${{ matrix.vmm }}
|
||||
|
||||
- name: Delete kata-deploy
|
||||
if: always()
|
||||
run: |
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
kubectl -n kube-system wait --timeout=10m --for=delete -l name=kata-deploy pod
|
||||
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
sleep 180s
|
||||
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl delete -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
68
.github/workflows/run-k8s-tests-on-snp.yaml
vendored
Normal file
68
.github/workflows/run-k8s-tests-on-snp.yaml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: CI | Run kubernetes tests on SEV-SNP
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run-k8s-tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
vmm:
|
||||
- qemu-snp
|
||||
runs-on: sev-snp
|
||||
env:
|
||||
KUBECONFIG: /home/kata/.kube/config
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Run tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
kubectl -n kube-system wait --timeout=10m --for=condition=Ready -l name=kata-deploy pod
|
||||
kubectl apply -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
|
||||
# This is needed as the kata-deploy pod will be set to "Ready" when it starts running,
|
||||
# which may cause issues like not having the node properly labeled or the artefacts
|
||||
# properly deployed when the tests actually start running.
|
||||
sleep 60s
|
||||
|
||||
pushd tests/integration/kubernetes
|
||||
sed -i -e 's|runtimeClassName: kata|runtimeClassName: kata-${{ matrix.vmm }}|' runtimeclass_workloads/*.yaml
|
||||
bash run_kubernetes_tests.sh
|
||||
popd
|
||||
env:
|
||||
KATA_HYPERVISOR: ${{ matrix.vmm }}
|
||||
|
||||
- name: Delete kata-deploy
|
||||
if: always()
|
||||
run: |
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
kubectl -n kube-system wait --timeout=10m --for=delete -l name=kata-deploy pod
|
||||
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
sleep 180s
|
||||
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl delete -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
68
.github/workflows/run-k8s-tests-on-tdx.yaml
vendored
Normal file
68
.github/workflows/run-k8s-tests-on-tdx.yaml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: CI | Run kubernetes tests on TDX
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
registry:
|
||||
required: true
|
||||
type: string
|
||||
repo:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run-k8s-tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
vmm:
|
||||
- qemu-tdx
|
||||
runs-on: tdx
|
||||
env:
|
||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Run tests
|
||||
timeout-minutes: 30
|
||||
run: |
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
|
||||
cat tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
|
||||
kubectl apply -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl apply -k tools/packaging/kata-deploy/kata-deploy/overlays/k3s
|
||||
kubectl -n kube-system wait --timeout=10m --for=condition=Ready -l name=kata-deploy pod
|
||||
kubectl apply -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
|
||||
# This is needed as the kata-deploy pod will be set to "Ready" when it starts running,
|
||||
# which may cause issues like not having the node properly labeled or the artefacts
|
||||
# properly deployed when the tests actually start running.
|
||||
sleep 60s
|
||||
|
||||
pushd tests/integration/kubernetes
|
||||
sed -i -e 's|runtimeClassName: kata|runtimeClassName: kata-${{ matrix.vmm }}|' runtimeclass_workloads/*.yaml
|
||||
bash run_kubernetes_tests.sh
|
||||
popd
|
||||
env:
|
||||
KATA_HYPERVISOR: ${{ matrix.vmm }}
|
||||
|
||||
- name: Delete kata-deploy
|
||||
if: always()
|
||||
run: |
|
||||
kubectl delete -k tools/packaging/kata-deploy/kata-deploy/overlays/k3s
|
||||
kubectl -n kube-system wait --timeout=10m --for=delete -l name=kata-deploy pod
|
||||
|
||||
sed -i -e "s|quay.io/kata-containers/kata-deploy:latest|${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}|g" tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml
|
||||
cat tools/packaging/kata-deploy/kata-cleanup/base/kata-cleanup.yaml | grep "${{ inputs.registry }}/${{ inputs.repo }}:${{ inputs.tag }}" || die "Failed to setup the tests image"
|
||||
kubectl apply -k tools/packaging/kata-deploy/kata-cleanup/overlays/k3s
|
||||
sleep 180s
|
||||
|
||||
kubectl delete -k tools/packaging/kata-deploy/kata-cleanup/overlays/k3s
|
||||
kubectl delete -f tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
|
||||
kubectl delete -f tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
|
||||
3
.github/workflows/snap-release.yaml
vendored
3
.github/workflows/snap-release.yaml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -32,6 +32,7 @@ jobs:
|
||||
run: |
|
||||
# Removing man-db, workflow kept failing, fixes: #4480
|
||||
sudo apt -y remove --purge man-db
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git git-extras
|
||||
kata_url="https://github.com/kata-containers/kata-containers"
|
||||
latest_version=$(git ls-remote --tags ${kata_url} | egrep -o "refs.*" | egrep -v "\-alpha|\-rc|{}" | egrep -o "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+" | sort -V -r | head -1)
|
||||
|
||||
2
.github/workflows/snap.yaml
vendored
2
.github/workflows/snap.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check out
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
31
.github/workflows/static-checks.yaml
vendored
31
.github/workflows/static-checks.yaml
vendored
@@ -19,13 +19,14 @@ jobs:
|
||||
- "make test"
|
||||
- "sudo -E PATH=\"$PATH\" make test"
|
||||
env:
|
||||
TRAVIS: "true"
|
||||
TRAVIS_BRANCH: ${{ github.base_ref }}
|
||||
TRAVIS_PULL_REQUEST_BRANCH: ${{ github.head_ref }}
|
||||
TRAVIS_PULL_REQUEST_SHA : ${{ github.event.pull_request.head.sha }}
|
||||
RUST_BACKTRACE: "1"
|
||||
target_branch: ${{ github.base_ref }}
|
||||
GOPATH: ${{ github.workspace }}
|
||||
steps:
|
||||
- name: Free disk space
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -35,16 +36,13 @@ jobs:
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19.3
|
||||
env:
|
||||
GOPATH: ${{ runner.workspace }}/kata-containers
|
||||
- name: Check kernel config version
|
||||
run: |
|
||||
cd "${{ github.workspace }}/src/github.com/${{ github.repository }}"
|
||||
kernel_dir="tools/packaging/kernel/"
|
||||
kernel_version_file="${kernel_dir}kata_config_version"
|
||||
modified_files=$(git diff --name-only origin/main..HEAD)
|
||||
result=$(git whatchanged origin/main..HEAD "${kernel_dir}" >>"/dev/null")
|
||||
if git whatchanged origin/main..HEAD "${kernel_dir}" >>"/dev/null"; then
|
||||
if git diff --name-only origin/main..HEAD "${kernel_dir}" | grep "${kernel_dir}"; then
|
||||
echo "Kernel directory has changed, checking if $kernel_version_file has been updated"
|
||||
if echo "$modified_files" | grep -v "README.md" | grep "${kernel_dir}" >>"/dev/null"; then
|
||||
echo "$modified_files" | grep "$kernel_version_file" >>/dev/null || ( echo "Please bump version in $kernel_version_file" && exit 1)
|
||||
@@ -53,29 +51,14 @@ jobs:
|
||||
fi
|
||||
echo "Check passed"
|
||||
fi
|
||||
- name: Setup GOPATH
|
||||
- name: Set PATH
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
echo "TRAVIS_BRANCH: ${TRAVIS_BRANCH}"
|
||||
echo "TRAVIS_PULL_REQUEST_BRANCH: ${TRAVIS_PULL_REQUEST_BRANCH}"
|
||||
echo "TRAVIS_PULL_REQUEST_SHA: ${TRAVIS_PULL_REQUEST_SHA}"
|
||||
echo "TRAVIS: ${TRAVIS}"
|
||||
- name: Set env
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
echo "GOPATH=${{ github.workspace }}" >> $GITHUB_ENV
|
||||
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
|
||||
- name: Setup travis references
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
echo "TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = \"/\" } ; { print $3 }')}"
|
||||
target_branch=${TRAVIS_BRANCH}
|
||||
- name: Setup
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
cd ${GOPATH}/src/github.com/${{ github.repository }} && ./ci/setup.sh
|
||||
env:
|
||||
GOPATH: ${{ runner.workspace }}/kata-containers
|
||||
- name: Installing rust
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }}
|
||||
run: |
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,6 +6,8 @@
|
||||
**/.vscode
|
||||
**/.idea
|
||||
**/.fleet
|
||||
**/*.swp
|
||||
**/*.swo
|
||||
pkg/logging/Cargo.lock
|
||||
src/agent/src/version.rs
|
||||
src/agent/kata-agent.service
|
||||
|
||||
1
Makefile
1
Makefile
@@ -18,6 +18,7 @@ TOOLS =
|
||||
TOOLS += agent-ctl
|
||||
TOOLS += kata-ctl
|
||||
TOOLS += log-parser
|
||||
TOOLS += log-parser-rs
|
||||
TOOLS += runk
|
||||
TOOLS += trace-forwarder
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ The table below lists the remaining parts of the project:
|
||||
| [osbuilder](tools/osbuilder) | infrastructure | Tool to create "mini O/S" rootfs and initrd images and kernel for the hypervisor. |
|
||||
| [`agent-ctl`](src/tools/agent-ctl) | utility | Tool that provides low-level access for testing the agent. |
|
||||
| [`kata-ctl`](src/tools/kata-ctl) | utility | Tool that provides advanced commands and debug facilities. |
|
||||
| [`log-parser-rs`](src/tools/log-parser-rs) | utility | Tool that aid in analyzing logs from the kata runtime. |
|
||||
| [`trace-forwarder`](src/tools/trace-forwarder) | utility | Agent tracing helper. |
|
||||
| [`runk`](src/tools/runk) | utility | Standard OCI container runtime based on the agent. |
|
||||
| [`ci`](https://github.com/kata-containers/ci) | CI | Continuous Integration configuration files and scripts. |
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
This document is written **specifically for developers**: it is not intended for end users.
|
||||
|
||||
If you want to contribute changes that you have made, please read the [community guidelines](https://github.com/kata-containers/community/blob/main/CONTRIBUTING.md) for information about our processes.
|
||||
|
||||
# Assumptions
|
||||
|
||||
- You are working on a non-critical test or development system.
|
||||
@@ -654,7 +656,7 @@ section when using rootfs, or when using initrd, complete the steps in the [Buil
|
||||
|
||||
Install the image:
|
||||
|
||||
>**Note**: When using an initrd image, replace the below rootfs image name `kata-containers.img`
|
||||
>**Note**: When using an initrd image, replace the below rootfs image name `kata-containers.img`
|
||||
>with the initrd image name `kata-containers-initrd.img`.
|
||||
|
||||
```bash
|
||||
@@ -688,25 +690,25 @@ $ sudo crictl run -r kata container.yaml pod.yaml
|
||||
|
||||
The steps required to enable debug console for QEMU slightly differ with
|
||||
those for firecracker / cloud-hypervisor.
|
||||
|
||||
|
||||
##### Enabling debug console for QEMU
|
||||
|
||||
Add `agent.debug_console` to the guest kernel command line to allow the agent process to start a debug console.
|
||||
Add `agent.debug_console` to the guest kernel command line to allow the agent process to start a debug console.
|
||||
|
||||
```bash
|
||||
$ sudo sed -i -e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.debug_console"/g' "${kata_configuration_file}"
|
||||
```
|
||||
|
||||
Here `kata_configuration_file` could point to `/etc/kata-containers/configuration.toml`
|
||||
Here `kata_configuration_file` could point to `/etc/kata-containers/configuration.toml`
|
||||
or `/usr/share/defaults/kata-containers/configuration.toml`
|
||||
or `/opt/kata/share/defaults/kata-containers/configuration-{hypervisor}.toml`, if
|
||||
you installed Kata Containers using `kata-deploy`.
|
||||
|
||||
##### Enabling debug console for cloud-hypervisor / firecracker
|
||||
|
||||
Slightly different configuration is required in case of firecracker and cloud hypervisor.
|
||||
Firecracker and cloud-hypervisor don't have a UNIX socket connected to `/dev/console`.
|
||||
Hence, the kernel command line option `agent.debug_console` will not work for them.
|
||||
Slightly different configuration is required in case of firecracker and cloud hypervisor.
|
||||
Firecracker and cloud-hypervisor don't have a UNIX socket connected to `/dev/console`.
|
||||
Hence, the kernel command line option `agent.debug_console` will not work for them.
|
||||
These hypervisors support `hybrid vsocks`, which can be used for communication
|
||||
between the host and the guest. The kernel command line option `agent.debug_console_vport`
|
||||
was added to allow developers specify on which `vsock` port the debugging console should be connected.
|
||||
@@ -719,7 +721,7 @@ sudo sed -i -e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.debug_cons
|
||||
```
|
||||
|
||||
> **Note** Ports 1024 and 1025 are reserved for communication with the agent
|
||||
> and gathering of agent logs respectively.
|
||||
> and gathering of agent logs respectively.
|
||||
|
||||
##### Connecting to the debug console
|
||||
|
||||
|
||||
@@ -28,23 +28,6 @@
|
||||
$ ./update-repository-version.sh -p "$NEW_VERSION" "$BRANCH"
|
||||
```
|
||||
|
||||
### Point tests repository to stable branch
|
||||
|
||||
If you create a new stable branch, i.e. if your release changes a major or minor version number (not a patch release), then
|
||||
you should modify the `tests` repository to point to that newly created stable branch and not the `main` branch.
|
||||
The objective is that changes in the CI on the main branch will not impact the stable branch.
|
||||
|
||||
In the test directory, change references the main branch in:
|
||||
* `README.md`
|
||||
* `versions.yaml`
|
||||
* `cmd/github-labels/labels.yaml.in`
|
||||
* `cmd/pmemctl/pmemctl.sh`
|
||||
* `.ci/lib.sh`
|
||||
* `.ci/static-checks.sh`
|
||||
|
||||
See the commits in [the corresponding PR for stable-2.1](https://github.com/kata-containers/tests/pull/3504) for an example of the changes.
|
||||
|
||||
|
||||
### Merge all bump version Pull requests
|
||||
|
||||
- The above step will create a GitHub pull request in the Kata projects. Trigger the CI using `/test` command on each bump Pull request.
|
||||
@@ -63,6 +46,24 @@
|
||||
$ ./tag_repos.sh -p -b "$BRANCH" tag
|
||||
```
|
||||
|
||||
### Point tests repository to stable branch
|
||||
|
||||
If your release changes a major or minor version number(not a patch release), then the above
|
||||
`./tag_repos.sh` script will create a new stable branch in all the repositories in addition to tagging them.
|
||||
This happens when you are making the first `rc` release for a new major or minor version in Kata.
|
||||
In this case, you should modify the `tests` repository to point to the newly created stable branch and not the `main` branch.
|
||||
The objective is that changes in the CI on the main branch will not impact the stable branch.
|
||||
|
||||
In the test directory, change references of the `main` branch to the new stable branch in:
|
||||
* `README.md`
|
||||
* `versions.yaml`
|
||||
* `cmd/github-labels/labels.yaml.in`
|
||||
* `cmd/pmemctl/pmemctl.sh`
|
||||
* `.ci/lib.sh`
|
||||
* `.ci/static-checks.sh`
|
||||
|
||||
See the commits in [the corresponding PR for stable-2.1](https://github.com/kata-containers/tests/pull/3504) for an example of the changes.
|
||||
|
||||
### Check Git-hub Actions
|
||||
|
||||
We make use of [GitHub actions](https://github.com/features/actions) in this [file](../.github/workflows/release.yaml) in the `kata-containers/kata-containers` repository to build and upload release artifacts. This action is auto triggered with the above step when a new tag is pushed to the `kata-containers/kata-containers` repository.
|
||||
|
||||
@@ -11,6 +11,7 @@ Kata Containers design documents:
|
||||
- [Host cgroups](host-cgroups.md)
|
||||
- [Agent systemd cgroup](agent-systemd-cgroup.md)
|
||||
- [`Inotify` support](inotify.md)
|
||||
- [`Hooks` support](hooks-handling.md)
|
||||
- [Metrics(Kata 2.0)](kata-2-0-metrics.md)
|
||||
- [Design for Kata Containers `Lazyload` ability with `nydus`](kata-nydus-design.md)
|
||||
- [Design for direct-assigned volume](direct-blk-device-assignment.md)
|
||||
|
||||
@@ -36,7 +36,7 @@ compatibility, and performance on par with MACVTAP.
|
||||
Kata Containers has deprecated support for bridge due to lacking performance relative to TC-filter and MACVTAP.
|
||||
|
||||
Kata Containers supports both
|
||||
[CNM](https://github.com/docker/libnetwork/blob/master/docs/design.md#the-container-network-model)
|
||||
[CNM](https://github.com/moby/libnetwork/blob/master/docs/design.md#the-container-network-model)
|
||||
and [CNI](https://github.com/containernetworking/cni) for networking management.
|
||||
|
||||
## Network Hotplug
|
||||
|
||||
63
docs/design/hooks-handling.md
Normal file
63
docs/design/hooks-handling.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Kata Containers support for `Hooks`
|
||||
|
||||
## Introduction
|
||||
|
||||
During container's lifecycle, different Hooks can be executed to do custom actions. In Kata Containers, we support two types of Hooks, `OCI Hooks` and `Kata Hooks`.
|
||||
|
||||
### OCI Hooks
|
||||
|
||||
The OCI Spec stipulates six hooks that can be executed at different time points and namespaces, including `Prestart Hooks`, `CreateRuntime Hooks`, `CreateContainer Hooks`, `StartContainer Hooks`, `Poststart Hooks` and `Poststop Hooks`. We support these types of Hooks as compatible as possible in Kata Containers.
|
||||
|
||||
The path and arguments of these hooks will be passed to Kata for execution via `bundle/config.json`. For example:
|
||||
```
|
||||
...
|
||||
"hooks": {
|
||||
"prestart": [
|
||||
{
|
||||
"path": "/usr/bin/prestart-hook",
|
||||
"args": ["prestart-hook", "arg1", "arg2"],
|
||||
"env": [ "key1=value1"]
|
||||
}
|
||||
],
|
||||
"createRuntime": [
|
||||
{
|
||||
"path": "/usr/bin/createRuntime-hook",
|
||||
"args": ["createRuntime-hook", "arg1", "arg2"],
|
||||
"env": [ "key1=value1"]
|
||||
}
|
||||
]
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
### Kata Hooks
|
||||
|
||||
In Kata, we support another three kinds of hooks executed in guest VM, including `Guest Prestart Hook`, `Guest Poststart Hook`, `Guest Poststop Hook`.
|
||||
|
||||
The executable files for Kata Hooks must be packaged in the *guest rootfs*. The file path to those guest hooks should be specified in the configuration file, and guest hooks must be stored in a subdirectory of `guest_hook_path` according to their hook type. For example:
|
||||
|
||||
+ In configuration file:
|
||||
```
|
||||
guest_hook_path="/usr/share/hooks"
|
||||
```
|
||||
+ In guest rootfs, prestart-hook is stored in `/usr/share/hooks/prestart/prestart-hook`.
|
||||
|
||||
## Execution
|
||||
The table below summarized when and where those different hooks will be executed in Kata Containers:
|
||||
|
||||
| Hook Name | Hook Type | Hook Path | Exec Place | Exec Time |
|
||||
|---|---|---|---|---|
|
||||
| `Prestart(deprecated)` | OCI hook | host runtime namespace | host runtime namespace | After VM is started, before container is created. |
|
||||
| `CreateRuntime` | OCI hook | host runtime namespace | host runtime namespace | After VM is started, before container is created, after `Prestart` hooks. |
|
||||
| `CreateContainer` | OCI hook | host runtime namespace | host vmm namespace* | After VM is started, before container is created, after `CreateRuntime` hooks. |
|
||||
| `StartContainer` | OCI hook | guest container namespace | guest container namespace | After container is created, before container is started. |
|
||||
| `Poststart` | OCI hook | host runtime namespace | host runtime namespace | After container is started, before start operation returns. |
|
||||
| `Poststop` | OCI hook | host runtime namespace | host runtime namespace | After container is deleted, before delete operation returns. |
|
||||
| `Guest Prestart` | Kata hook | guest agent namespace | guest agent namespace | During start operation, before container command is executed. |
|
||||
| `Guest Poststart` | Kata hook | guest agent namespace | guest agent namespace | During start operation, after container command is executed, before start operation returns. |
|
||||
| `Guest Poststop` | Kata hook | guest agent namespace | guest agent namespace | During delete operation, after container is deleted, before delete operation returns. |
|
||||
|
||||
+ `Hook Path` specifies where hook's path be resolved.
|
||||
+ `Exec Place` specifies in which namespace those hooks can be executed.
|
||||
+ For `CreateContainer` Hooks, OCI requires to run them inside the container namespace while the hook executable path is in the host runtime, which is a non-starter for VM-based containers. So we design to keep them running in the *host vmm namespace.*
|
||||
+ `Exec Time` specifies at which time point those hooks can be executed.
|
||||
@@ -44,12 +44,11 @@ $ popd
|
||||
- Build a custom QEMU
|
||||
```bash
|
||||
$ source kata-containers/tools/packaging/scripts/lib.sh
|
||||
$ qemu_url="$(get_from_kata_deps "assets.hypervisor.qemu.snp.url")"
|
||||
$ qemu_branch="$(get_from_kata_deps "assets.hypervisor.qemu.snp.branch")"
|
||||
$ qemu_commit="$(get_from_kata_deps "assets.hypervisor.qemu.snp.commit")"
|
||||
$ git clone -b "${qemu_branch}" "${qemu_url}"
|
||||
$ qemu_url="$(get_from_kata_deps "assets.hypervisor.qemu-snp-experimental.url")"
|
||||
$ qemu_tag="$(get_from_kata_deps "assets.hypervisor.qemu-snp-experimental.tag")"
|
||||
$ git clone "${qemu_url}"
|
||||
$ pushd qemu
|
||||
$ git checkout "${qemu_commit}"
|
||||
$ git checkout "${qemu_tag}"
|
||||
$ ./configure --enable-virtfs --target-list=x86_64-softmmu --enable-debug
|
||||
$ make -j "$(nproc)"
|
||||
$ popd
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Introduction
|
||||
To improve security, Kata Container supports running the VMM process (currently only QEMU) as a non-`root` user.
|
||||
To improve security, Kata Container supports running the VMM process (QEMU and cloud-hypervisor) as a non-`root` user.
|
||||
This document describes how to enable the rootless VMM mode and its limitations.
|
||||
|
||||
## Pre-requisites
|
||||
@@ -27,7 +27,7 @@ Another necessary change is to move the hypervisor runtime files (e.g. `vhost-fs
|
||||
## Limitations
|
||||
|
||||
1. Only the VMM process is running as a non-root user. Other processes such as Kata Container shimv2 and `virtiofsd` still run as the root user.
|
||||
2. Currently, this feature is only supported in QEMU. Still need to bring it to Firecracker and Cloud Hypervisor (see https://github.com/kata-containers/kata-containers/issues/2567).
|
||||
2. Currently, this feature is only supported in QEMU and cloud-hypervisor. For firecracker, you can use jailer to run the VMM process with a non-root user.
|
||||
3. Certain features will not work when rootless VMM is enabled, including:
|
||||
1. Passing devices to the guest (`virtio-blk`, `virtio-scsi`) will not work if the non-privileged user does not have permission to access it (leading to a permission denied error). A more permissive permission (e.g. 666) may overcome this issue. However, you need to be aware of the potential security implications of reducing the security on such devices.
|
||||
2. `vfio` device will also not work because of permission denied error.
|
||||
@@ -19,7 +19,7 @@ Packaged installation methods uses your distribution's native package format (su
|
||||
|------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------|-----------------------------------------------------------------------------------------------|
|
||||
| [Using kata-deploy](#kata-deploy-installation) | The preferred way to deploy the Kata Containers distributed binaries on a Kubernetes cluster | **No!** | Best way to give it a try on kata-containers on an already up and running Kubernetes cluster. |
|
||||
| [Using official distro packages](#official-packages) | Kata packages provided by Linux distributions official repositories | yes | Recommended for most users. |
|
||||
| [Using snap](#snap-installation) | Easy to install | yes | Good alternative to official distro packages. |
|
||||
| ~~[Using snap](#snap-installation)~~ | ~~Easy to install~~ | ~~yes~~ | **Snap is unmaintained!** ~~Good alternative to official distro packages.~~ |
|
||||
| [Automatic](#automatic-installation) | Run a single command to install a full system | **No!** | For those wanting the latest release quickly. |
|
||||
| [Manual](#manual-installation) | Follow a guide step-by-step to install a working system | **No!** | For those who want the latest release with more control. |
|
||||
| [Build from source](#build-from-source-installation) | Build the software components manually | **No!** | Power users and developers only. |
|
||||
@@ -44,9 +44,24 @@ Kata packages are provided by official distribution repositories for:
|
||||
|
||||
### Snap Installation
|
||||
|
||||
The snap installation is available for all distributions which support `snapd`.
|
||||
> **WARNING:**
|
||||
>
|
||||
> The Snap package method is **unmaintained** and only provides an old
|
||||
> version of Kata Containers:
|
||||
> The [latest Kata Containers snap](https://snapcraft.io/kata-containers)
|
||||
> provides Kata Containers
|
||||
> [version 2.4.2](https://github.com/kata-containers/kata-containers/releases/tag/2.4.2)
|
||||
> but the latest stable Kata Containers release at the time of writing is
|
||||
> [version 3.1.0](https://github.com/kata-containers/kata-containers/releases/tag/3.1.0).
|
||||
>
|
||||
> We recommend strongly that you switch to an alternative Kata Containers installation method.
|
||||
>
|
||||
> See: https://github.com/kata-containers/kata-containers/issues/6769
|
||||
> for further details.
|
||||
|
||||
[Use snap](snap-installation-guide.md) to install Kata Containers from https://snapcraft.io.
|
||||
~~The snap installation is available for all distributions which support `snapd`.~~
|
||||
|
||||
~~[Use snap](snap-installation-guide.md) to install Kata Containers from https://snapcraft.io. ~~
|
||||
|
||||
### Automatic Installation
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ Refer to [this guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-ec2-l
|
||||
SSH into the machine
|
||||
|
||||
```bash
|
||||
$ ssh -i MyKeyPair.pen ubuntu@${IP}
|
||||
$ ssh -i MyKeyPair.pem ubuntu@${IP}
|
||||
```
|
||||
|
||||
Go onto the next step.
|
||||
|
||||
@@ -49,14 +49,14 @@ Follow the [`kata-deploy`](../../tools/packaging/kata-deploy/README.md).
|
||||
|
||||
* Download `Rustup` and install `Rust`
|
||||
> **Notes:**
|
||||
> Rust version 1.62.0 is needed
|
||||
> For Rust version, please set `RUST_VERSION` to the value of `languages.rust.meta.newest-version key` in [`versions.yaml`](../../versions.yaml) or, if `yq` is available on your system, run `export RUST_VERSION=$(yq read versions.yaml languages.rust.meta.newest-version)`.
|
||||
|
||||
Example for `x86_64`
|
||||
```
|
||||
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
$ source $HOME/.cargo/env
|
||||
$ rustup install 1.62.0
|
||||
$ rustup default 1.62.0-x86_64-unknown-linux-gnu
|
||||
$ rustup install ${RUST_VERSION}
|
||||
$ rustup default ${RUST_VERSION}-x86_64-unknown-linux-gnu
|
||||
```
|
||||
|
||||
* Musl support for fully static binary
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# Kata Containers snap package
|
||||
|
||||
> **WARNING:**
|
||||
>
|
||||
> The Snap package method is **unmaintained** and only provides an old
|
||||
> version of Kata Containers:
|
||||
> The [latest Kata Containers snap](https://snapcraft.io/kata-containers)
|
||||
> provides Kata Containers
|
||||
> [version 2.4.2](https://github.com/kata-containers/kata-containers/releases/tag/2.4.2)
|
||||
> but the latest stable Kata Containers release at the time of writing is
|
||||
> [version 3.1.0](https://github.com/kata-containers/kata-containers/releases/tag/3.1.0).
|
||||
>
|
||||
> We recommend strongly that you switch to an alternative Kata Containers installation method.
|
||||
>
|
||||
> See: https://github.com/kata-containers/kata-containers/issues/6769
|
||||
> for further details.
|
||||
|
||||
## Install Kata Containers
|
||||
|
||||
Kata Containers can be installed in any Linux distribution that supports
|
||||
@@ -7,6 +22,21 @@ Kata Containers can be installed in any Linux distribution that supports
|
||||
|
||||
Run the following command to install **Kata Containers**:
|
||||
|
||||
> **WARNING:**
|
||||
>
|
||||
> The Snap package method is **unmaintained** and only provides an old
|
||||
> version of Kata Containers:
|
||||
> The [latest Kata Containers snap](https://snapcraft.io/kata-containers)
|
||||
> provides Kata Containers
|
||||
> [version 2.4.2](https://github.com/kata-containers/kata-containers/releases/tag/2.4.2)
|
||||
> but the latest stable Kata Containers release at the time of writing is
|
||||
> [version 3.1.0](https://github.com/kata-containers/kata-containers/releases/tag/3.1.0).
|
||||
>
|
||||
> We recommend strongly that you switch to an alternative Kata Containers installation method.
|
||||
>
|
||||
> See: https://github.com/kata-containers/kata-containers/issues/6769
|
||||
> for further details.
|
||||
|
||||
```sh
|
||||
$ sudo snap install kata-containers --stable --classic
|
||||
```
|
||||
|
||||
@@ -34,54 +34,6 @@ parts:
|
||||
mkdir -p $(dirname ${kata_dir})
|
||||
ln -sf $(realpath "${SNAPCRAFT_STAGE}/..") ${kata_dir}
|
||||
|
||||
godeps:
|
||||
after: [metadata]
|
||||
plugin: nil
|
||||
prime:
|
||||
- -*
|
||||
build-packages:
|
||||
- curl
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
# put everything in stage
|
||||
cd "${SNAPCRAFT_STAGE}"
|
||||
|
||||
version="$(${yq} r ${kata_dir}/versions.yaml languages.golang.meta.newest-version)"
|
||||
tarfile="go${version}.${goos}-${goarch}.tar.gz"
|
||||
curl -LO https://golang.org/dl/${tarfile}
|
||||
tar -xf ${tarfile} --strip-components=1
|
||||
|
||||
rustdeps:
|
||||
after: [metadata]
|
||||
plugin: nil
|
||||
prime:
|
||||
- -*
|
||||
build-packages:
|
||||
- curl
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
# put everything in stage
|
||||
cd "${SNAPCRAFT_STAGE}"
|
||||
|
||||
version="$(${yq} r ${kata_dir}/versions.yaml languages.rust.meta.newest-version)"
|
||||
if ! command -v rustup > /dev/null; then
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${version}
|
||||
fi
|
||||
|
||||
export PATH=${PATH}:${HOME}/.cargo/bin
|
||||
rustup toolchain install ${version}
|
||||
rustup default ${version}
|
||||
if [ "${arch}" == "ppc64le" ] || [ "${arch}" == "s390x" ] ; then
|
||||
[ "${arch}" == "ppc64le" ] && arch="powerpc64le"
|
||||
rustup target add ${arch}-unknown-linux-gnu
|
||||
else
|
||||
rustup target add ${arch}-unknown-linux-musl
|
||||
$([ "$(whoami)" != "root" ] && echo sudo) ln -sf /usr/bin/g++ /bin/musl-g++
|
||||
fi
|
||||
rustup component add rustfmt
|
||||
|
||||
docker:
|
||||
after: [metadata]
|
||||
plugin: nil
|
||||
@@ -111,240 +63,92 @@ parts:
|
||||
echo "Adding $USER into docker group"
|
||||
sudo -E gpasswd -a $USER docker
|
||||
echo "Starting docker"
|
||||
# docker may fail to start using "fd://" in docker.service
|
||||
sudo sed -i 's/fd:\/\//unix:\/\//g' /lib/systemd/system/docker.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo -E systemctl start docker || true
|
||||
|
||||
image:
|
||||
after: [godeps, docker, qemu, kernel]
|
||||
after: [docker]
|
||||
plugin: nil
|
||||
build-packages:
|
||||
- docker.io
|
||||
- cpio
|
||||
- git
|
||||
- iptables
|
||||
- software-properties-common
|
||||
- uidmap
|
||||
- gnupg2
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
[ "${arch}" = "ppc64le" ] || [ "${arch}" = "s390x" ] && sudo apt-get --no-install-recommends install -y protobuf-compiler
|
||||
cd "${SNAPCRAFT_PROJECT_DIR}"
|
||||
sudo -E NO_TTY=true make rootfs-image-tarball
|
||||
|
||||
if [ -n "$http_proxy" ]; then
|
||||
echo "Setting proxy $http_proxy"
|
||||
sudo -E systemctl set-environment http_proxy="$http_proxy" || true
|
||||
sudo -E systemctl set-environment https_proxy="$https_proxy" || true
|
||||
fi
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-rootfs-image.tar.xz"
|
||||
|
||||
# Copy yq binary. It's used in the container
|
||||
cp -a "${yq}" "${GOPATH}/bin/"
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
cd "${kata_dir}/tools/osbuilder"
|
||||
|
||||
# build image
|
||||
export AGENT_INIT=yes
|
||||
export USE_DOCKER=1
|
||||
export DEBUG=1
|
||||
initrd_distro=$(${yq} r -X ${kata_dir}/versions.yaml assets.initrd.architecture.${arch}.name)
|
||||
image_distro=$(${yq} r -X ${kata_dir}/versions.yaml assets.image.architecture.${arch}.name)
|
||||
case "$arch" in
|
||||
x86_64)
|
||||
# In some build systems it's impossible to build a rootfs image, try with the initrd image
|
||||
sudo -E PATH=$PATH make image DISTRO="${image_distro}" || sudo -E PATH="$PATH" make initrd DISTRO="${initrd_distro}"
|
||||
;;
|
||||
sudo -E NO_TTY=true make rootfs-initrd-tarball
|
||||
|
||||
aarch64|ppc64le|s390x)
|
||||
sudo -E PATH="$PATH" make initrd DISTRO="${initrd_distro}"
|
||||
;;
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-rootfs-initrd.tar.xz"
|
||||
|
||||
*) die "unsupported architecture: ${arch}" ;;
|
||||
esac
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
# Install image
|
||||
kata_image_dir="${SNAPCRAFT_PART_INSTALL}/usr/share/kata-containers"
|
||||
mkdir -p "${kata_image_dir}"
|
||||
cp kata-containers*.img "${kata_image_dir}"
|
||||
|
||||
runtime:
|
||||
after: [godeps, image, cloud-hypervisor]
|
||||
after: [docker]
|
||||
plugin: nil
|
||||
build-attributes: [no-patchelf]
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
cd "${kata_dir}/src/runtime"
|
||||
cd "${SNAPCRAFT_PROJECT_DIR}"
|
||||
sudo -E NO_TTY=true make shim-v2-tarball
|
||||
|
||||
qemu_cmd="qemu-system-${qemu_arch}"
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-shim-v2.tar.xz"
|
||||
|
||||
# build and install runtime
|
||||
make \
|
||||
PREFIX="/snap/${SNAPCRAFT_PROJECT_NAME}/current/usr" \
|
||||
SKIP_GO_VERSION_CHECK=1 \
|
||||
QEMUCMD="${qemu_cmd}"
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
make install \
|
||||
PREFIX=/usr \
|
||||
DESTDIR="${SNAPCRAFT_PART_INSTALL}" \
|
||||
SKIP_GO_VERSION_CHECK=1 \
|
||||
QEMUCMD="${qemu_cmd}"
|
||||
|
||||
if [ ! -f ${SNAPCRAFT_PART_INSTALL}/../../image/install/usr/share/kata-containers/kata-containers.img ]; then
|
||||
sed -i -e "s|^image =.*|initrd = \"/snap/${SNAPCRAFT_PROJECT_NAME}/current/usr/share/kata-containers/kata-containers-initrd.img\"|" \
|
||||
${SNAPCRAFT_PART_INSTALL}/usr/share/defaults/${SNAPCRAFT_PROJECT_NAME}/configuration.toml
|
||||
fi
|
||||
mkdir -p "${SNAPCRAFT_PART_INSTALL}/usr/bin"
|
||||
ln -sf "${SNAPCRAFT_PART_INSTALL}/opt/kata/bin/containerd-shim-kata-v2" "${SNAPCRAFT_PART_INSTALL}/usr/bin/containerd-shim-kata-v2"
|
||||
ln -sf "${SNAPCRAFT_PART_INSTALL}/opt/kata/bin/kata-runtime" "${SNAPCRAFT_PART_INSTALL}/usr/bin/kata-runtime"
|
||||
ln -sf "${SNAPCRAFT_PART_INSTALL}/opt/kata/bin/kata-collect-data.sh" "${SNAPCRAFT_PART_INSTALL}/usr/bin/kata-collect-data.sh"
|
||||
|
||||
kernel:
|
||||
after: [godeps]
|
||||
after: [docker]
|
||||
plugin: nil
|
||||
build-packages:
|
||||
- libelf-dev
|
||||
- curl
|
||||
- build-essential
|
||||
- bison
|
||||
- flex
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
kernel_version="$(${yq} r $versions_file assets.kernel.version)"
|
||||
#Remove extra 'v'
|
||||
kernel_version="${kernel_version#v}"
|
||||
cd "${SNAPCRAFT_PROJECT_DIR}"
|
||||
sudo -E NO_TTY=true make kernel-tarball
|
||||
|
||||
[ "${arch}" = "s390x" ] && sudo apt-get --no-install-recommends install -y libssl-dev
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-kernel.tar.xz"
|
||||
|
||||
cd "${kata_dir}/tools/packaging/kernel"
|
||||
kernel_dir_prefix="kata-linux-"
|
||||
|
||||
# Setup and build kernel
|
||||
./build-kernel.sh -v "${kernel_version}" -d setup
|
||||
cd ${kernel_dir_prefix}*
|
||||
make -j $(nproc ${CI:+--ignore 1}) EXTRAVERSION=".container"
|
||||
|
||||
kernel_suffix="${kernel_version}.container"
|
||||
kata_kernel_dir="${SNAPCRAFT_PART_INSTALL}/usr/share/kata-containers"
|
||||
mkdir -p "${kata_kernel_dir}"
|
||||
|
||||
# Install bz kernel
|
||||
make install INSTALL_PATH="${kata_kernel_dir}" EXTRAVERSION=".container" || true
|
||||
vmlinuz_name="vmlinuz-${kernel_suffix}"
|
||||
ln -sf "${vmlinuz_name}" "${kata_kernel_dir}/vmlinuz.container"
|
||||
|
||||
# Install raw kernel
|
||||
vmlinux_path="vmlinux"
|
||||
[ "${arch}" = "s390x" ] && vmlinux_path="arch/s390/boot/vmlinux"
|
||||
vmlinux_name="vmlinux-${kernel_suffix}"
|
||||
cp "${vmlinux_path}" "${kata_kernel_dir}/${vmlinux_name}"
|
||||
ln -sf "${vmlinux_name}" "${kata_kernel_dir}/vmlinux.container"
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
qemu:
|
||||
plugin: make
|
||||
after: [godeps]
|
||||
build-packages:
|
||||
- gcc
|
||||
- python3
|
||||
- zlib1g-dev
|
||||
- libcap-ng-dev
|
||||
- libglib2.0-dev
|
||||
- libpixman-1-dev
|
||||
- libnuma-dev
|
||||
- libltdl-dev
|
||||
- libcap-dev
|
||||
- libattr1-dev
|
||||
- libfdt-dev
|
||||
- curl
|
||||
- libcapstone-dev
|
||||
- bc
|
||||
- libblkid-dev
|
||||
- libffi-dev
|
||||
- libmount-dev
|
||||
- libseccomp-dev
|
||||
- libselinux1-dev
|
||||
- ninja-build
|
||||
after: [docker]
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
branch="$(${yq} r ${versions_file} assets.hypervisor.qemu.version)"
|
||||
url="$(${yq} r ${versions_file} assets.hypervisor.qemu.url)"
|
||||
commit=""
|
||||
patches_dir="${kata_dir}/tools/packaging/qemu/patches/$(echo ${branch} | sed -e 's/.[[:digit:]]*$//' -e 's/^v//').x"
|
||||
patches_version_dir="${kata_dir}/tools/packaging/qemu/patches/tag_patches/${branch}"
|
||||
cd "${SNAPCRAFT_PROJECT_DIR}"
|
||||
sudo -E NO_TTY=true make qemu-tarball
|
||||
|
||||
# download source
|
||||
qemu_dir="${SNAPCRAFT_STAGE}/qemu"
|
||||
rm -rf "${qemu_dir}"
|
||||
git clone --depth 1 --branch ${branch} --single-branch ${url} "${qemu_dir}"
|
||||
cd "${qemu_dir}"
|
||||
[ -z "${commit}" ] || git checkout "${commit}"
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-qemu.tar.xz"
|
||||
|
||||
[ -n "$(ls -A ui/keycodemapdb)" ] || git clone --depth 1 https://github.com/qemu/keycodemapdb ui/keycodemapdb/
|
||||
[ -n "$(ls -A capstone)" ] || git clone --depth 1 https://github.com/qemu/capstone capstone
|
||||
|
||||
# Apply branch patches
|
||||
[ -d "${patches_version_dir}" ] || mkdir "${patches_version_dir}"
|
||||
${kata_dir}/tools/packaging/scripts/apply_patches.sh "${patches_dir}"
|
||||
${kata_dir}/tools/packaging/scripts/apply_patches.sh "${patches_version_dir}"
|
||||
|
||||
# Only x86_64 supports libpmem
|
||||
[ "${arch}" = "x86_64" ] && sudo apt-get --no-install-recommends install -y apt-utils ca-certificates libpmem-dev
|
||||
|
||||
configure_hypervisor="${kata_dir}/tools/packaging/scripts/configure-hypervisor.sh"
|
||||
chmod +x "${configure_hypervisor}"
|
||||
# static build. The --prefix, --libdir, --libexecdir, --datadir arguments are
|
||||
# based on PREFIX and set by configure-hypervisor.sh
|
||||
echo "$(PREFIX=/snap/${SNAPCRAFT_PROJECT_NAME}/current/usr ${configure_hypervisor} -s kata-qemu) \
|
||||
--disable-rbd " \
|
||||
| xargs ./configure
|
||||
|
||||
# Copy QEMU configurations (Kconfigs)
|
||||
case "${branch}" in
|
||||
"v5.1.0")
|
||||
cp -a "${kata_dir}"/tools/packaging/qemu/default-configs/* default-configs
|
||||
;;
|
||||
|
||||
*)
|
||||
cp -a "${kata_dir}"/tools/packaging/qemu/default-configs/* configs/devices/
|
||||
;;
|
||||
esac
|
||||
|
||||
# build and install
|
||||
make -j $(nproc ${CI:+--ignore 1})
|
||||
make install DESTDIR="${SNAPCRAFT_PART_INSTALL}"
|
||||
prime:
|
||||
- -snap/
|
||||
- -usr/bin/qemu-ga
|
||||
- -usr/bin/qemu-pr-helper
|
||||
- -usr/bin/virtfs-proxy-helper
|
||||
- -usr/include/
|
||||
- -usr/share/applications/
|
||||
- -usr/share/icons/
|
||||
- -usr/var/
|
||||
- usr/*
|
||||
- lib/*
|
||||
organize:
|
||||
# Hack: move qemu to /
|
||||
"snap/kata-containers/current/": "./"
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
virtiofsd:
|
||||
plugin: nil
|
||||
after: [godeps, rustdeps, docker]
|
||||
after: [docker]
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
echo "INFO: Building rust version of virtiofsd"
|
||||
|
||||
cd "${SNAPCRAFT_PROJECT_DIR}"
|
||||
# Clean-up build dir in case it already exists
|
||||
sudo -E NO_TTY=true make virtiofsd-tarball
|
||||
|
||||
sudo install \
|
||||
--owner='root' \
|
||||
--group='root' \
|
||||
--mode=0755 \
|
||||
-D \
|
||||
--target-directory="${SNAPCRAFT_PART_INSTALL}/usr/libexec/" \
|
||||
build/virtiofsd/builddir/virtiofsd/virtiofsd
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-virtiofsd.tar.xz"
|
||||
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
|
||||
cloud-hypervisor:
|
||||
plugin: nil
|
||||
after: [godeps, docker]
|
||||
after: [docker]
|
||||
override-build: |
|
||||
source "${SNAPCRAFT_PROJECT_DIR}/snap/local/snap-common.sh"
|
||||
|
||||
@@ -353,13 +157,8 @@ parts:
|
||||
sudo -E NO_TTY=true make cloud-hypervisor-tarball
|
||||
|
||||
tarfile="${SNAPCRAFT_PROJECT_DIR}/tools/packaging/kata-deploy/local-build/build/kata-static-cloud-hypervisor.tar.xz"
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
tar -xvJpf "${tarfile}" -C "${tmpdir}"
|
||||
|
||||
install -D "${tmpdir}/opt/kata/bin/cloud-hypervisor" "${SNAPCRAFT_PART_INSTALL}/usr/bin/cloud-hypervisor"
|
||||
|
||||
rm -rf "${tmpdir}"
|
||||
tar -xvJpf "${tarfile}" -C "${SNAPCRAFT_PART_INSTALL}"
|
||||
fi
|
||||
|
||||
apps:
|
||||
|
||||
88
src/agent/Cargo.lock
generated
88
src/agent/Cargo.lock
generated
@@ -801,6 +801,7 @@ dependencies = [
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"capctl",
|
||||
"cfg-if 1.0.0",
|
||||
"cgroups-rs",
|
||||
"clap",
|
||||
"futures",
|
||||
@@ -818,7 +819,7 @@ dependencies = [
|
||||
"opentelemetry",
|
||||
"procfs",
|
||||
"prometheus",
|
||||
"protobuf",
|
||||
"protobuf 3.2.0",
|
||||
"protocols",
|
||||
"regex",
|
||||
"rtnetlink",
|
||||
@@ -1430,7 +1431,7 @@ dependencies = [
|
||||
"memchr",
|
||||
"parking_lot 0.12.1",
|
||||
"procfs",
|
||||
"protobuf",
|
||||
"protobuf 2.27.1",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -1490,9 +1491,16 @@ name = "protobuf"
|
||||
version = "2.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96"
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"once_cell",
|
||||
"protobuf-support",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1501,17 +1509,47 @@ version = "2.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aec1632b7c8f2e620343439a7dfd1f3c47b18906c4be58982079911482b5d707"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf 2.27.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-codegen-pure"
|
||||
version = "2.27.1"
|
||||
name = "protobuf-codegen"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f8122fdb18e55190c796b088a16bdb70cd7acdcd48f7a8b796b58c62e532cc6"
|
||||
checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"anyhow",
|
||||
"once_cell",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-parse",
|
||||
"regex",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-parse"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"log",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-support",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-support"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1520,7 +1558,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"oci",
|
||||
"protobuf",
|
||||
"protobuf 3.2.0",
|
||||
"ttrpc",
|
||||
"ttrpc-codegen",
|
||||
]
|
||||
@@ -1704,7 +1742,7 @@ dependencies = [
|
||||
"nix 0.24.2",
|
||||
"oci",
|
||||
"path-absolutize",
|
||||
"protobuf",
|
||||
"protobuf 3.2.0",
|
||||
"protocols",
|
||||
"regex",
|
||||
"rlimit",
|
||||
@@ -2226,9 +2264,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc"
|
||||
version = "0.6.1"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ecfff459a859c6ba6668ff72b34c2f1d94d9d58f7088414c2674ad0f31cc7d8"
|
||||
checksum = "a35f22a2964bea14afee161665bb260b83cb48e665e0260ca06ec0e775c8b06c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"byteorder",
|
||||
@@ -2236,8 +2274,8 @@ dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.23.1",
|
||||
"protobuf",
|
||||
"protobuf-codegen-pure",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-codegen 3.2.0",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-vsock",
|
||||
@@ -2245,28 +2283,28 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc-codegen"
|
||||
version = "0.2.0"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809eda4e459820237104e4b61d6b41bbe6c9e1ce6adf4057955e6e6722a90408"
|
||||
checksum = "94d7f7631d7a9ebed715a47cd4cb6072cbc7ae1d4ec01598971bbec0024340c2"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"protobuf-codegen-pure",
|
||||
"protobuf 2.27.1",
|
||||
"protobuf-codegen 3.2.0",
|
||||
"protobuf-support",
|
||||
"ttrpc-compiler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc-compiler"
|
||||
version = "0.4.1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2978ed3fa047d8fd55cbeb4d4a61d461fb3021a90c9618519c73ce7e5bb66c15"
|
||||
checksum = "ec3cb5dbf1f0865a34fe3f722290fe776cacb16f50428610b779467b76ddf647"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"protobuf 2.27.1",
|
||||
"protobuf-codegen 2.27.1",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ oci = { path = "../libs/oci" }
|
||||
rustjail = { path = "rustjail" }
|
||||
protocols = { path = "../libs/protocols", features = ["async"] }
|
||||
lazy_static = "1.3.0"
|
||||
ttrpc = { version = "0.6.0", features = ["async"], default-features = false }
|
||||
protobuf = "2.27.0"
|
||||
ttrpc = { version = "0.7.1", features = ["async"], default-features = false }
|
||||
protobuf = "3.2.0"
|
||||
libc = "0.2.58"
|
||||
nix = "0.24.2"
|
||||
capctl = "0.2.0"
|
||||
@@ -48,6 +48,7 @@ slog-scope = "4.1.2"
|
||||
slog-stdlog = "4.0.0"
|
||||
log = "0.4.11"
|
||||
|
||||
cfg-if = "1.0.0"
|
||||
prometheus = { version = "0.13.0", features = ["process"] }
|
||||
procfs = "0.12.0"
|
||||
anyhow = "1.0.32"
|
||||
|
||||
@@ -33,6 +33,12 @@ ifeq ($(SECCOMP),yes)
|
||||
override EXTRA_RUSTFEATURES += seccomp
|
||||
endif
|
||||
|
||||
include ../../utils.mk
|
||||
|
||||
ifeq ($(ARCH), ppc64le)
|
||||
override ARCH = powerpc64le
|
||||
endif
|
||||
|
||||
##VAR STANDARD_OCI_RUNTIME=yes|no define if agent enables standard oci runtime feature
|
||||
STANDARD_OCI_RUNTIME := no
|
||||
|
||||
@@ -45,8 +51,6 @@ ifneq ($(EXTRA_RUSTFEATURES),)
|
||||
override EXTRA_RUSTFEATURES := --features "$(EXTRA_RUSTFEATURES)"
|
||||
endif
|
||||
|
||||
include ../../utils.mk
|
||||
|
||||
TARGET_PATH = target/$(TRIPLE)/$(BUILD_TYPE)/$(TARGET)
|
||||
|
||||
##VAR DESTDIR=<path> is a directory prepended to each installed target file
|
||||
|
||||
@@ -18,7 +18,7 @@ scopeguard = "1.0.0"
|
||||
capctl = "0.2.0"
|
||||
lazy_static = "1.3.0"
|
||||
libc = "0.2.58"
|
||||
protobuf = "2.27.0"
|
||||
protobuf = "3.2.0"
|
||||
slog = "2.5.2"
|
||||
slog-scope = "4.1.2"
|
||||
scan_fmt = "0.2.6"
|
||||
|
||||
@@ -27,7 +27,7 @@ use oci::{
|
||||
LinuxNetwork, LinuxPids, LinuxResources,
|
||||
};
|
||||
|
||||
use protobuf::{CachedSize, RepeatedField, SingularPtrField, UnknownFields};
|
||||
use protobuf::MessageField;
|
||||
use protocols::agent::{
|
||||
BlkioStats, BlkioStatsEntry, CgroupStats, CpuStats, CpuUsage, HugetlbStats, MemoryData,
|
||||
MemoryStats, PidsStats, ThrottlingData,
|
||||
@@ -50,7 +50,7 @@ macro_rules! get_controller_or_return_singular_none {
|
||||
($cg:ident) => {
|
||||
match $cg.controller_of() {
|
||||
Some(c) => c,
|
||||
None => return SingularPtrField::none(),
|
||||
None => return MessageField::none(),
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -134,11 +134,10 @@ impl CgroupManager for Manager {
|
||||
|
||||
let throttling_data = get_cpu_stats(&self.cgroup);
|
||||
|
||||
let cpu_stats = SingularPtrField::some(CpuStats {
|
||||
let cpu_stats = MessageField::some(CpuStats {
|
||||
cpu_usage,
|
||||
throttling_data,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// Memorystats
|
||||
@@ -160,8 +159,7 @@ impl CgroupManager for Manager {
|
||||
pids_stats,
|
||||
blkio_stats,
|
||||
hugetlb_stats,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -446,14 +444,14 @@ fn set_memory_resources(cg: &cgroups::Cgroup, memory: &LinuxMemory, update: bool
|
||||
let memstat = get_memory_stats(cg)
|
||||
.into_option()
|
||||
.ok_or_else(|| anyhow!("failed to get the cgroup memory stats"))?;
|
||||
let memusage = memstat.get_usage();
|
||||
let memusage = memstat.usage();
|
||||
|
||||
// When update memory limit, the kernel would check the current memory limit
|
||||
// set against the new swap setting, if the current memory limit is large than
|
||||
// the new swap, then set limit first, otherwise the kernel would complain and
|
||||
// refused to set; on the other hand, if the current memory limit is smaller than
|
||||
// the new swap, then we should set the swap first and then set the memor limit.
|
||||
if swap == -1 || memusage.get_limit() < swap as u64 {
|
||||
if swap == -1 || memusage.limit() < swap as u64 {
|
||||
mem_controller.set_memswap_limit(swap)?;
|
||||
set_resource!(mem_controller, set_limit, memory, limit);
|
||||
} else {
|
||||
@@ -657,21 +655,20 @@ lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
fn get_cpu_stats(cg: &cgroups::Cgroup) -> SingularPtrField<ThrottlingData> {
|
||||
fn get_cpu_stats(cg: &cgroups::Cgroup) -> MessageField<ThrottlingData> {
|
||||
let cpu_controller: &CpuController = get_controller_or_return_singular_none!(cg);
|
||||
let stat = cpu_controller.cpu().stat;
|
||||
let h = lines_to_map(&stat);
|
||||
|
||||
SingularPtrField::some(ThrottlingData {
|
||||
MessageField::some(ThrottlingData {
|
||||
periods: *h.get("nr_periods").unwrap_or(&0),
|
||||
throttled_periods: *h.get("nr_throttled").unwrap_or(&0),
|
||||
throttled_time: *h.get("throttled_time").unwrap_or(&0),
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
|
||||
fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> MessageField<CpuUsage> {
|
||||
if let Some(cpuacct_controller) = cg.controller_of::<CpuAcctController>() {
|
||||
let cpuacct = cpuacct_controller.cpuacct();
|
||||
|
||||
@@ -685,13 +682,12 @@ fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
|
||||
|
||||
let percpu_usage = line_to_vec(&cpuacct.usage_percpu);
|
||||
|
||||
return SingularPtrField::some(CpuUsage {
|
||||
return MessageField::some(CpuUsage {
|
||||
total_usage,
|
||||
percpu_usage,
|
||||
usage_in_kernelmode,
|
||||
usage_in_usermode,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -704,17 +700,16 @@ fn get_cpuacct_stats(cg: &cgroups::Cgroup) -> SingularPtrField<CpuUsage> {
|
||||
let total_usage = *h.get("usage_usec").unwrap_or(&0);
|
||||
let percpu_usage = vec![];
|
||||
|
||||
SingularPtrField::some(CpuUsage {
|
||||
MessageField::some(CpuUsage {
|
||||
total_usage,
|
||||
percpu_usage,
|
||||
usage_in_kernelmode,
|
||||
usage_in_usermode,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn get_memory_stats(cg: &cgroups::Cgroup) -> SingularPtrField<MemoryStats> {
|
||||
fn get_memory_stats(cg: &cgroups::Cgroup) -> MessageField<MemoryStats> {
|
||||
let memory_controller: &MemController = get_controller_or_return_singular_none!(cg);
|
||||
|
||||
// cache from memory stat
|
||||
@@ -726,52 +721,48 @@ fn get_memory_stats(cg: &cgroups::Cgroup) -> SingularPtrField<MemoryStats> {
|
||||
let use_hierarchy = value == 1;
|
||||
|
||||
// get memory data
|
||||
let usage = SingularPtrField::some(MemoryData {
|
||||
let usage = MessageField::some(MemoryData {
|
||||
usage: memory.usage_in_bytes,
|
||||
max_usage: memory.max_usage_in_bytes,
|
||||
failcnt: memory.fail_cnt,
|
||||
limit: memory.limit_in_bytes as u64,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// get swap usage
|
||||
let memswap = memory_controller.memswap();
|
||||
|
||||
let swap_usage = SingularPtrField::some(MemoryData {
|
||||
let swap_usage = MessageField::some(MemoryData {
|
||||
usage: memswap.usage_in_bytes,
|
||||
max_usage: memswap.max_usage_in_bytes,
|
||||
failcnt: memswap.fail_cnt,
|
||||
limit: memswap.limit_in_bytes as u64,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// get kernel usage
|
||||
let kmem_stat = memory_controller.kmem_stat();
|
||||
|
||||
let kernel_usage = SingularPtrField::some(MemoryData {
|
||||
let kernel_usage = MessageField::some(MemoryData {
|
||||
usage: kmem_stat.usage_in_bytes,
|
||||
max_usage: kmem_stat.max_usage_in_bytes,
|
||||
failcnt: kmem_stat.fail_cnt,
|
||||
limit: kmem_stat.limit_in_bytes as u64,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
SingularPtrField::some(MemoryStats {
|
||||
MessageField::some(MemoryStats {
|
||||
cache,
|
||||
usage,
|
||||
swap_usage,
|
||||
kernel_usage,
|
||||
use_hierarchy,
|
||||
stats: memory.stat.raw,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn get_pids_stats(cg: &cgroups::Cgroup) -> SingularPtrField<PidsStats> {
|
||||
fn get_pids_stats(cg: &cgroups::Cgroup) -> MessageField<PidsStats> {
|
||||
let pid_controller: &PidController = get_controller_or_return_singular_none!(cg);
|
||||
|
||||
let current = pid_controller.get_pid_current().unwrap_or(0);
|
||||
@@ -785,11 +776,10 @@ fn get_pids_stats(cg: &cgroups::Cgroup) -> SingularPtrField<PidsStats> {
|
||||
},
|
||||
} as u64;
|
||||
|
||||
SingularPtrField::some(PidsStats {
|
||||
MessageField::some(PidsStats {
|
||||
current,
|
||||
limit,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -825,8 +815,8 @@ https://github.com/opencontainers/runc/blob/a5847db387ae28c0ca4ebe4beee1a76900c8
|
||||
Total 0
|
||||
*/
|
||||
|
||||
fn get_blkio_stat_blkiodata(blkiodata: &[BlkIoData]) -> RepeatedField<BlkioStatsEntry> {
|
||||
let mut m = RepeatedField::new();
|
||||
fn get_blkio_stat_blkiodata(blkiodata: &[BlkIoData]) -> Vec<BlkioStatsEntry> {
|
||||
let mut m = Vec::new();
|
||||
if blkiodata.is_empty() {
|
||||
return m;
|
||||
}
|
||||
@@ -839,16 +829,15 @@ fn get_blkio_stat_blkiodata(blkiodata: &[BlkIoData]) -> RepeatedField<BlkioStats
|
||||
minor: d.minor as u64,
|
||||
op: op.clone(),
|
||||
value: d.data,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
m
|
||||
}
|
||||
|
||||
fn get_blkio_stat_ioservice(services: &[IoService]) -> RepeatedField<BlkioStatsEntry> {
|
||||
let mut m = RepeatedField::new();
|
||||
fn get_blkio_stat_ioservice(services: &[IoService]) -> Vec<BlkioStatsEntry> {
|
||||
let mut m = Vec::new();
|
||||
|
||||
if services.is_empty() {
|
||||
return m;
|
||||
@@ -872,17 +861,16 @@ fn build_blkio_stats_entry(major: i16, minor: i16, op: &str, value: u64) -> Blki
|
||||
minor: minor as u64,
|
||||
op: op.to_string(),
|
||||
value,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_blkio_stats_v2(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
|
||||
fn get_blkio_stats_v2(cg: &cgroups::Cgroup) -> MessageField<BlkioStats> {
|
||||
let blkio_controller: &BlkIoController = get_controller_or_return_singular_none!(cg);
|
||||
let blkio = blkio_controller.blkio();
|
||||
|
||||
let mut resp = BlkioStats::new();
|
||||
let mut blkio_stats = RepeatedField::new();
|
||||
let mut blkio_stats = Vec::new();
|
||||
|
||||
let stat = blkio.io_stat;
|
||||
for s in stat {
|
||||
@@ -898,10 +886,10 @@ fn get_blkio_stats_v2(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
|
||||
|
||||
resp.io_service_bytes_recursive = blkio_stats;
|
||||
|
||||
SingularPtrField::some(resp)
|
||||
MessageField::some(resp)
|
||||
}
|
||||
|
||||
fn get_blkio_stats(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
|
||||
fn get_blkio_stats(cg: &cgroups::Cgroup) -> MessageField<BlkioStats> {
|
||||
if cg.v2() {
|
||||
return get_blkio_stats_v2(cg);
|
||||
}
|
||||
@@ -934,7 +922,7 @@ fn get_blkio_stats(cg: &cgroups::Cgroup) -> SingularPtrField<BlkioStats> {
|
||||
m.sectors_recursive = get_blkio_stat_blkiodata(&blkio.sectors_recursive);
|
||||
}
|
||||
|
||||
SingularPtrField::some(m)
|
||||
MessageField::some(m)
|
||||
}
|
||||
|
||||
fn get_hugetlb_stats(cg: &cgroups::Cgroup) -> HashMap<String, HugetlbStats> {
|
||||
@@ -958,8 +946,7 @@ fn get_hugetlb_stats(cg: &cgroups::Cgroup) -> HashMap<String, HugetlbStats> {
|
||||
usage,
|
||||
max_usage,
|
||||
failcnt,
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use protobuf::{CachedSize, SingularPtrField, UnknownFields};
|
||||
use protobuf::MessageField;
|
||||
|
||||
use crate::cgroups::Manager as CgroupManager;
|
||||
use crate::protocols::agent::{BlkioStats, CgroupStats, CpuStats, MemoryStats, PidsStats};
|
||||
@@ -33,13 +33,12 @@ impl CgroupManager for Manager {
|
||||
|
||||
fn get_stats(&self) -> Result<CgroupStats> {
|
||||
Ok(CgroupStats {
|
||||
cpu_stats: SingularPtrField::some(CpuStats::default()),
|
||||
memory_stats: SingularPtrField::some(MemoryStats::new()),
|
||||
pids_stats: SingularPtrField::some(PidsStats::new()),
|
||||
blkio_stats: SingularPtrField::some(BlkioStats::new()),
|
||||
cpu_stats: MessageField::some(CpuStats::default()),
|
||||
memory_stats: MessageField::some(MemoryStats::new()),
|
||||
pids_stats: MessageField::some(PidsStats::new()),
|
||||
blkio_stats: MessageField::some(BlkioStats::new()),
|
||||
hugetlb_stats: HashMap::new(),
|
||||
unknown_fields: UnknownFields::default(),
|
||||
cached_size: CachedSize::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ use nix::unistd::{self, fork, ForkResult, Gid, Pid, Uid, User};
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
use protobuf::SingularPtrField;
|
||||
use protobuf::MessageField;
|
||||
|
||||
use oci::State as OCIState;
|
||||
use regex::Regex;
|
||||
@@ -374,13 +374,18 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
let buf = read_sync(crfd)?;
|
||||
let spec_str = std::str::from_utf8(&buf)?;
|
||||
let spec: oci::Spec = serde_json::from_str(spec_str)?;
|
||||
|
||||
log_child!(cfd_log, "notify parent to send oci process");
|
||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
||||
|
||||
let buf = read_sync(crfd)?;
|
||||
let process_str = std::str::from_utf8(&buf)?;
|
||||
let oci_process: oci::Process = serde_json::from_str(process_str)?;
|
||||
log_child!(cfd_log, "notify parent to send oci state");
|
||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
||||
|
||||
let buf = read_sync(crfd)?;
|
||||
let state_str = std::str::from_utf8(&buf)?;
|
||||
let mut state: oci::State = serde_json::from_str(state_str)?;
|
||||
log_child!(cfd_log, "notify parent to send cgroup manager");
|
||||
write_sync(cwfd, SYNC_SUCCESS, "")?;
|
||||
|
||||
@@ -743,6 +748,19 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
unistd::read(fd, buf)?;
|
||||
}
|
||||
|
||||
if init {
|
||||
// StartContainer Hooks:
|
||||
// * should be run in container namespace
|
||||
// * should be run after container is created and before container is started (before user-specific command is executed)
|
||||
// * spec details: https://github.com/opencontainers/runtime-spec/blob/c1662686cff159595277b79322d0272f5182941b/config.md#startcontainer-hooks
|
||||
state.pid = std::process::id() as i32;
|
||||
state.status = oci::ContainerState::Created;
|
||||
if let Some(hooks) = spec.hooks.as_ref() {
|
||||
let mut start_container_states = HookStates::new();
|
||||
start_container_states.execute_hooks(&hooks.start_container, Some(state))?;
|
||||
}
|
||||
}
|
||||
|
||||
// With NoNewPrivileges, we should set seccomp as close to
|
||||
// do_exec as possible in order to reduce the amount of
|
||||
// system calls in the seccomp profiles.
|
||||
@@ -857,7 +875,7 @@ impl BaseContainer for LinuxContainer {
|
||||
// what about network interface stats?
|
||||
|
||||
Ok(StatsContainerResponse {
|
||||
cgroup_stats: SingularPtrField::some(self.cgroup_manager.as_ref().get_stats()?),
|
||||
cgroup_stats: MessageField::some(self.cgroup_manager.as_ref().get_stats()?),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
@@ -1323,7 +1341,6 @@ async fn join_namespaces(
|
||||
write_async(pipe_w, SYNC_DATA, spec_str.as_str()).await?;
|
||||
|
||||
info!(logger, "wait child received oci spec");
|
||||
|
||||
read_async(pipe_r).await?;
|
||||
|
||||
info!(logger, "send oci process from parent to child");
|
||||
@@ -1333,6 +1350,13 @@ async fn join_namespaces(
|
||||
info!(logger, "wait child received oci process");
|
||||
read_async(pipe_r).await?;
|
||||
|
||||
info!(logger, "try to send state from parent to child");
|
||||
let state_str = serde_json::to_string(st)?;
|
||||
write_async(pipe_w, SYNC_DATA, state_str.as_str()).await?;
|
||||
|
||||
info!(logger, "wait child received oci state");
|
||||
read_async(pipe_r).await?;
|
||||
|
||||
let cm_str = if use_systemd_cgroup {
|
||||
serde_json::to_string(cm.as_any()?.downcast_ref::<SystemdManager>().unwrap())
|
||||
} else {
|
||||
|
||||
@@ -82,11 +82,11 @@ pub fn process_grpc_to_oci(p: &grpc::Process) -> oci::Process {
|
||||
let cap = p.Capabilities.as_ref().unwrap();
|
||||
|
||||
Some(oci::LinuxCapabilities {
|
||||
bounding: cap.Bounding.clone().into_vec(),
|
||||
effective: cap.Effective.clone().into_vec(),
|
||||
inheritable: cap.Inheritable.clone().into_vec(),
|
||||
permitted: cap.Permitted.clone().into_vec(),
|
||||
ambient: cap.Ambient.clone().into_vec(),
|
||||
bounding: cap.Bounding.clone(),
|
||||
effective: cap.Effective.clone(),
|
||||
inheritable: cap.Inheritable.clone(),
|
||||
permitted: cap.Permitted.clone(),
|
||||
ambient: cap.Ambient.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@@ -108,8 +108,8 @@ pub fn process_grpc_to_oci(p: &grpc::Process) -> oci::Process {
|
||||
terminal: p.Terminal,
|
||||
console_size,
|
||||
user,
|
||||
args: p.Args.clone().into_vec(),
|
||||
env: p.Env.clone().into_vec(),
|
||||
args: p.Args.clone(),
|
||||
env: p.Env.clone(),
|
||||
cwd: p.Cwd.clone(),
|
||||
capabilities,
|
||||
rlimits,
|
||||
@@ -130,9 +130,9 @@ fn root_grpc_to_oci(root: &grpc::Root) -> oci::Root {
|
||||
fn mount_grpc_to_oci(m: &grpc::Mount) -> oci::Mount {
|
||||
oci::Mount {
|
||||
destination: m.destination.clone(),
|
||||
r#type: m.field_type.clone(),
|
||||
r#type: m.type_.clone(),
|
||||
source: m.source.clone(),
|
||||
options: m.options.clone().into_vec(),
|
||||
options: m.options.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ fn hook_grpc_to_oci(h: &[grpcHook]) -> Vec<oci::Hook> {
|
||||
for e in h.iter() {
|
||||
r.push(oci::Hook {
|
||||
path: e.Path.clone(),
|
||||
args: e.Args.clone().into_vec(),
|
||||
env: e.Env.clone().into_vec(),
|
||||
args: e.Args.clone(),
|
||||
env: e.Env.clone(),
|
||||
timeout: Some(e.Timeout as i32),
|
||||
});
|
||||
}
|
||||
@@ -153,13 +153,17 @@ fn hook_grpc_to_oci(h: &[grpcHook]) -> Vec<oci::Hook> {
|
||||
|
||||
fn hooks_grpc_to_oci(h: &grpc::Hooks) -> oci::Hooks {
|
||||
let prestart = hook_grpc_to_oci(h.Prestart.as_ref());
|
||||
|
||||
let create_runtime = hook_grpc_to_oci(h.CreateRuntime.as_ref());
|
||||
let create_container = hook_grpc_to_oci(h.CreateContainer.as_ref());
|
||||
let start_container = hook_grpc_to_oci(h.StartContainer.as_ref());
|
||||
let poststart = hook_grpc_to_oci(h.Poststart.as_ref());
|
||||
|
||||
let poststop = hook_grpc_to_oci(h.Poststop.as_ref());
|
||||
|
||||
oci::Hooks {
|
||||
prestart,
|
||||
create_runtime,
|
||||
create_container,
|
||||
start_container,
|
||||
poststart,
|
||||
poststop,
|
||||
}
|
||||
@@ -355,7 +359,7 @@ fn seccomp_grpc_to_oci(sec: &grpc::LinuxSeccomp) -> oci::LinuxSeccomp {
|
||||
let mut args = Vec::new();
|
||||
|
||||
let errno_ret: u32 = if sys.has_errnoret() {
|
||||
sys.get_errnoret()
|
||||
sys.errnoret()
|
||||
} else {
|
||||
libc::EPERM as u32
|
||||
};
|
||||
@@ -370,7 +374,7 @@ fn seccomp_grpc_to_oci(sec: &grpc::LinuxSeccomp) -> oci::LinuxSeccomp {
|
||||
}
|
||||
|
||||
r.push(oci::LinuxSyscall {
|
||||
names: sys.Names.clone().into_vec(),
|
||||
names: sys.Names.clone(),
|
||||
action: sys.Action.clone(),
|
||||
errno_ret,
|
||||
args,
|
||||
@@ -381,8 +385,8 @@ fn seccomp_grpc_to_oci(sec: &grpc::LinuxSeccomp) -> oci::LinuxSeccomp {
|
||||
|
||||
oci::LinuxSeccomp {
|
||||
default_action: sec.DefaultAction.clone(),
|
||||
architectures: sec.Architectures.clone().into_vec(),
|
||||
flags: sec.Flags.clone().into_vec(),
|
||||
architectures: sec.Architectures.clone(),
|
||||
flags: sec.Flags.clone(),
|
||||
syscalls,
|
||||
}
|
||||
}
|
||||
@@ -452,8 +456,8 @@ fn linux_grpc_to_oci(l: &grpc::Linux) -> oci::Linux {
|
||||
devices,
|
||||
seccomp,
|
||||
rootfs_propagation: l.RootfsPropagation.clone(),
|
||||
masked_paths: l.MaskedPaths.clone().into_vec(),
|
||||
readonly_paths: l.ReadonlyPaths.clone().into_vec(),
|
||||
masked_paths: l.MaskedPaths.clone(),
|
||||
readonly_paths: l.ReadonlyPaths.clone(),
|
||||
mount_label: l.MountLabel.clone(),
|
||||
intel_rdt,
|
||||
}
|
||||
@@ -554,35 +558,30 @@ mod tests {
|
||||
// All fields specified
|
||||
grpcproc: grpc::Process {
|
||||
Terminal: true,
|
||||
ConsoleSize: protobuf::SingularPtrField::<grpc::Box>::some(grpc::Box {
|
||||
ConsoleSize: protobuf::MessageField::<grpc::Box>::some(grpc::Box {
|
||||
Height: 123,
|
||||
Width: 456,
|
||||
..Default::default()
|
||||
}),
|
||||
User: protobuf::SingularPtrField::<grpc::User>::some(grpc::User {
|
||||
User: protobuf::MessageField::<grpc::User>::some(grpc::User {
|
||||
UID: 1234,
|
||||
GID: 5678,
|
||||
AdditionalGids: Vec::from([910, 1112]),
|
||||
Username: String::from("username"),
|
||||
..Default::default()
|
||||
}),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([String::from("env")])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env")]),
|
||||
Cwd: String::from("cwd"),
|
||||
Capabilities: protobuf::SingularPtrField::some(grpc::LinuxCapabilities {
|
||||
Bounding: protobuf::RepeatedField::from(Vec::from([String::from("bnd")])),
|
||||
Effective: protobuf::RepeatedField::from(Vec::from([String::from("eff")])),
|
||||
Inheritable: protobuf::RepeatedField::from(Vec::from([String::from(
|
||||
"inher",
|
||||
)])),
|
||||
Permitted: protobuf::RepeatedField::from(Vec::from([String::from("perm")])),
|
||||
Ambient: protobuf::RepeatedField::from(Vec::from([String::from("amb")])),
|
||||
Capabilities: protobuf::MessageField::some(grpc::LinuxCapabilities {
|
||||
Bounding: Vec::from([String::from("bnd")]),
|
||||
Effective: Vec::from([String::from("eff")]),
|
||||
Inheritable: Vec::from([String::from("inher")]),
|
||||
Permitted: Vec::from([String::from("perm")]),
|
||||
Ambient: Vec::from([String::from("amb")]),
|
||||
..Default::default()
|
||||
}),
|
||||
Rlimits: protobuf::RepeatedField::from(Vec::from([
|
||||
Rlimits: Vec::from([
|
||||
grpc::POSIXRlimit {
|
||||
Type: String::from("r#type"),
|
||||
Hard: 123,
|
||||
@@ -595,7 +594,7 @@ mod tests {
|
||||
Soft: 1011,
|
||||
..Default::default()
|
||||
},
|
||||
])),
|
||||
]),
|
||||
NoNewPrivileges: true,
|
||||
ApparmorProfile: String::from("apparmor profile"),
|
||||
OOMScoreAdj: 123456,
|
||||
@@ -645,7 +644,7 @@ mod tests {
|
||||
TestData {
|
||||
// None ConsoleSize
|
||||
grpcproc: grpc::Process {
|
||||
ConsoleSize: protobuf::SingularPtrField::<grpc::Box>::none(),
|
||||
ConsoleSize: protobuf::MessageField::<grpc::Box>::none(),
|
||||
OOMScoreAdj: 0,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -658,7 +657,7 @@ mod tests {
|
||||
TestData {
|
||||
// None User
|
||||
grpcproc: grpc::Process {
|
||||
User: protobuf::SingularPtrField::<grpc::User>::none(),
|
||||
User: protobuf::MessageField::<grpc::User>::none(),
|
||||
OOMScoreAdj: 0,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -676,7 +675,7 @@ mod tests {
|
||||
TestData {
|
||||
// None Capabilities
|
||||
grpcproc: grpc::Process {
|
||||
Capabilities: protobuf::SingularPtrField::none(),
|
||||
Capabilities: protobuf::MessageField::none(),
|
||||
OOMScoreAdj: 0,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -777,60 +776,57 @@ mod tests {
|
||||
TestData {
|
||||
// All specified
|
||||
grpchooks: grpc::Hooks {
|
||||
Prestart: protobuf::RepeatedField::from(Vec::from([
|
||||
Prestart: Vec::from([
|
||||
grpc::Hook {
|
||||
Path: String::from("prestartpath"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
},
|
||||
grpc::Hook {
|
||||
Path: String::from("prestartpath2"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg3"),
|
||||
String::from("arg4"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env3"),
|
||||
String::from("env4"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg3"), String::from("arg4")]),
|
||||
Env: Vec::from([String::from("env3"), String::from("env4")]),
|
||||
Timeout: 25,
|
||||
..Default::default()
|
||||
},
|
||||
])),
|
||||
Poststart: protobuf::RepeatedField::from(Vec::from([grpc::Hook {
|
||||
]),
|
||||
Poststart: Vec::from([grpc::Hook {
|
||||
Path: String::from("poststartpath"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}])),
|
||||
Poststop: protobuf::RepeatedField::from(Vec::from([grpc::Hook {
|
||||
}]),
|
||||
Poststop: Vec::from([grpc::Hook {
|
||||
Path: String::from("poststoppath"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}])),
|
||||
}]),
|
||||
CreateRuntime: Vec::from([grpc::Hook {
|
||||
Path: String::from("createruntimepath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
CreateContainer: Vec::from([grpc::Hook {
|
||||
Path: String::from("createcontainerpath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
StartContainer: Vec::from([grpc::Hook {
|
||||
Path: String::from("startcontainerpath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Hooks {
|
||||
@@ -860,38 +856,65 @@ mod tests {
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
create_runtime: Vec::from([oci::Hook {
|
||||
path: String::from("createruntimepath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
create_container: Vec::from([oci::Hook {
|
||||
path: String::from("createcontainerpath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
start_container: Vec::from([oci::Hook {
|
||||
path: String::from("startcontainerpath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
},
|
||||
},
|
||||
TestData {
|
||||
// Prestart empty
|
||||
grpchooks: grpc::Hooks {
|
||||
Prestart: protobuf::RepeatedField::from(Vec::from([])),
|
||||
Poststart: protobuf::RepeatedField::from(Vec::from([grpc::Hook {
|
||||
Prestart: Vec::from([]),
|
||||
Poststart: Vec::from([grpc::Hook {
|
||||
Path: String::from("poststartpath"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}])),
|
||||
Poststop: protobuf::RepeatedField::from(Vec::from([grpc::Hook {
|
||||
}]),
|
||||
Poststop: Vec::from([grpc::Hook {
|
||||
Path: String::from("poststoppath"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}])),
|
||||
}]),
|
||||
CreateRuntime: Vec::from([grpc::Hook {
|
||||
Path: String::from("createruntimepath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
CreateContainer: Vec::from([grpc::Hook {
|
||||
Path: String::from("createcontainerpath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
StartContainer: Vec::from([grpc::Hook {
|
||||
Path: String::from("startcontainerpath"),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
}]),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Hooks {
|
||||
@@ -908,6 +931,24 @@ mod tests {
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
create_runtime: Vec::from([oci::Hook {
|
||||
path: String::from("createruntimepath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
create_container: Vec::from([oci::Hook {
|
||||
path: String::from("createcontainerpath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
start_container: Vec::from([oci::Hook {
|
||||
path: String::from("startcontainerpath"),
|
||||
args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
timeout: Some(10),
|
||||
}]),
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -945,11 +986,8 @@ mod tests {
|
||||
grpcmount: grpc::Mount {
|
||||
destination: String::from("destination"),
|
||||
source: String::from("source"),
|
||||
field_type: String::from("fieldtype"),
|
||||
options: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("option1"),
|
||||
String::from("option2"),
|
||||
])),
|
||||
type_: String::from("fieldtype"),
|
||||
options: Vec::from([String::from("option1"), String::from("option2")]),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Mount {
|
||||
@@ -963,8 +1001,8 @@ mod tests {
|
||||
grpcmount: grpc::Mount {
|
||||
destination: String::from("destination"),
|
||||
source: String::from("source"),
|
||||
field_type: String::from("fieldtype"),
|
||||
options: protobuf::RepeatedField::from(Vec::new()),
|
||||
type_: String::from("fieldtype"),
|
||||
options: Vec::new(),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Mount {
|
||||
@@ -978,8 +1016,8 @@ mod tests {
|
||||
grpcmount: grpc::Mount {
|
||||
destination: String::new(),
|
||||
source: String::from("source"),
|
||||
field_type: String::from("fieldtype"),
|
||||
options: protobuf::RepeatedField::from(Vec::from([String::from("option1")])),
|
||||
type_: String::from("fieldtype"),
|
||||
options: Vec::from([String::from("option1")]),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Mount {
|
||||
@@ -993,8 +1031,8 @@ mod tests {
|
||||
grpcmount: grpc::Mount {
|
||||
destination: String::from("destination"),
|
||||
source: String::from("source"),
|
||||
field_type: String::new(),
|
||||
options: protobuf::RepeatedField::from(Vec::from([String::from("option1")])),
|
||||
type_: String::new(),
|
||||
options: Vec::from([String::from("option1")]),
|
||||
..Default::default()
|
||||
},
|
||||
result: oci::Mount {
|
||||
@@ -1054,27 +1092,15 @@ mod tests {
|
||||
grpchook: &[
|
||||
grpc::Hook {
|
||||
Path: String::from("path"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg1"),
|
||||
String::from("arg2"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env1"),
|
||||
String::from("env2"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg1"), String::from("arg2")]),
|
||||
Env: Vec::from([String::from("env1"), String::from("env2")]),
|
||||
Timeout: 10,
|
||||
..Default::default()
|
||||
},
|
||||
grpc::Hook {
|
||||
Path: String::from("path2"),
|
||||
Args: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("arg3"),
|
||||
String::from("arg4"),
|
||||
])),
|
||||
Env: protobuf::RepeatedField::from(Vec::from([
|
||||
String::from("env3"),
|
||||
String::from("env4"),
|
||||
])),
|
||||
Args: Vec::from([String::from("arg3"), String::from("arg4")]),
|
||||
Env: Vec::from([String::from("env3"), String::from("env4")]),
|
||||
Timeout: 20,
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::log_child;
|
||||
// struct is populated from the content in the /proc/<pid>/mountinfo file.
|
||||
#[derive(std::fmt::Debug, PartialEq)]
|
||||
pub struct Info {
|
||||
mount_point: String,
|
||||
pub mount_point: String,
|
||||
optional: String,
|
||||
fstype: String,
|
||||
}
|
||||
@@ -553,7 +553,7 @@ fn rootfs_parent_mount_private(path: &str) -> Result<()> {
|
||||
|
||||
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
|
||||
// bind mounts
|
||||
fn parse_mount_table(mountinfo_path: &str) -> Result<Vec<Info>> {
|
||||
pub fn parse_mount_table(mountinfo_path: &str) -> Result<Vec<Info>> {
|
||||
let file = File::open(mountinfo_path)?;
|
||||
let reader = BufReader::new(file);
|
||||
let mut infos = Vec::new();
|
||||
|
||||
79
src/agent/src/ap.rs
Normal file
79
src/agent/src/ap.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) IBM Corp. 2023
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
|
||||
// IBM Adjunct Processor (AP) is used for cryptographic operations
|
||||
// by IBM Crypto Express hardware security modules on IBM zSystem & LinuxONE (s390x).
|
||||
// In Linux, virtual cryptographic devices are called AP queues.
|
||||
// The name of an AP queue respects a format <xx>.<xxxx> in hexadecimal notation [1, p.467]:
|
||||
// - <xx> is an adapter ID
|
||||
// - <xxxx> is an adapter domain ID
|
||||
// [1] https://www.ibm.com/docs/en/linuxonibm/pdf/lku5dd05.pdf
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Address {
|
||||
pub adapter_id: u8,
|
||||
pub adapter_domain: u16,
|
||||
}
|
||||
|
||||
impl Address {
|
||||
pub fn new(adapter_id: u8, adapter_domain: u16) -> Address {
|
||||
Address {
|
||||
adapter_id,
|
||||
adapter_domain,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Address {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> anyhow::Result<Self> {
|
||||
let split: Vec<&str> = s.split('.').collect();
|
||||
if split.len() != 2 {
|
||||
return Err(anyhow!(
|
||||
"Wrong AP bus format. It needs to be in the form <xx>.<xxxx> (e.g. 0a.003f), got {:?}",
|
||||
s
|
||||
));
|
||||
}
|
||||
|
||||
let adapter_id = u8::from_str_radix(split[0], 16).context(format!(
|
||||
"Wrong AP bus format. AP ID needs to be in the form <xx> (e.g. 0a), got {:?}",
|
||||
split[0]
|
||||
))?;
|
||||
let adapter_domain = u16::from_str_radix(split[1], 16).context(format!(
|
||||
"Wrong AP bus format. AP domain needs to be in the form <xxxx> (e.g. 003f), got {:?}",
|
||||
split[1]
|
||||
))?;
|
||||
|
||||
Ok(Address::new(adapter_id, adapter_domain))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Address {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "{:02x}.{:04x}", self.adapter_id, self.adapter_domain)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
let device = Address::from_str("a.1").unwrap();
|
||||
assert_eq!(format!("{}", device), "0a.0001");
|
||||
|
||||
assert!(Address::from_str("").is_err());
|
||||
assert!(Address::from_str(".").is_err());
|
||||
assert!(Address::from_str("0.0.0").is_err());
|
||||
assert!(Address::from_str("0g.0000").is_err());
|
||||
assert!(Address::from_str("0a.10000").is_err());
|
||||
}
|
||||
}
|
||||
@@ -200,7 +200,7 @@ impl AgentConfig {
|
||||
let config_position = args.iter().position(|a| a == "--config" || a == "-c");
|
||||
if let Some(config_position) = config_position {
|
||||
if let Some(config_file) = args.get(config_position + 1) {
|
||||
return AgentConfig::from_config_file(config_file);
|
||||
return AgentConfig::from_config_file(config_file).context("AgentConfig from args");
|
||||
} else {
|
||||
panic!("The config argument wasn't formed properly: {:?}", args);
|
||||
}
|
||||
@@ -216,7 +216,8 @@ impl AgentConfig {
|
||||
// or if it can't be parsed properly.
|
||||
if param.starts_with(format!("{}=", CONFIG_FILE).as_str()) {
|
||||
let config_file = get_string_value(param)?;
|
||||
return AgentConfig::from_config_file(&config_file);
|
||||
return AgentConfig::from_config_file(&config_file)
|
||||
.context("AgentConfig from kernel cmdline");
|
||||
}
|
||||
|
||||
// parse cmdline flags
|
||||
@@ -304,7 +305,8 @@ impl AgentConfig {
|
||||
|
||||
#[instrument]
|
||||
pub fn from_config_file(file: &str) -> Result<AgentConfig> {
|
||||
let config = fs::read_to_string(file)?;
|
||||
let config = fs::read_to_string(file)
|
||||
.with_context(|| format!("Failed to read config file {}", file))?;
|
||||
AgentConfig::from_str(&config)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,12 @@ use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
use crate::ccw;
|
||||
use crate::linux_abi::*;
|
||||
use crate::pci;
|
||||
use crate::sandbox::Sandbox;
|
||||
use crate::uevent::{wait_for_uevent, Uevent, UeventMatcher};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use cfg_if::cfg_if;
|
||||
use oci::{LinuxDeviceCgroup, LinuxResources, Spec};
|
||||
use protocols::agent::Device;
|
||||
use tracing::instrument;
|
||||
@@ -46,14 +45,22 @@ pub const DRIVER_NVDIMM_TYPE: &str = "nvdimm";
|
||||
pub const DRIVER_EPHEMERAL_TYPE: &str = "ephemeral";
|
||||
pub const DRIVER_LOCAL_TYPE: &str = "local";
|
||||
pub const DRIVER_WATCHABLE_BIND_TYPE: &str = "watchable-bind";
|
||||
// VFIO device to be bound to a guest kernel driver
|
||||
pub const DRIVER_VFIO_GK_TYPE: &str = "vfio-gk";
|
||||
// VFIO device to be bound to vfio-pci and made available inside the
|
||||
// VFIO PCI device to be bound to a guest kernel driver
|
||||
pub const DRIVER_VFIO_PCI_GK_TYPE: &str = "vfio-pci-gk";
|
||||
// VFIO PCI device to be bound to vfio-pci and made available inside the
|
||||
// container as a VFIO device node
|
||||
pub const DRIVER_VFIO_TYPE: &str = "vfio";
|
||||
pub const DRIVER_VFIO_PCI_TYPE: &str = "vfio-pci";
|
||||
pub const DRIVER_VFIO_AP_TYPE: &str = "vfio-ap";
|
||||
pub const DRIVER_OVERLAYFS_TYPE: &str = "overlayfs";
|
||||
pub const FS_TYPE_HUGETLB: &str = "hugetlbfs";
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_arch = "s390x")] {
|
||||
use crate::ap;
|
||||
use crate::ccw;
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn online_device(path: &str) -> Result<()> {
|
||||
fs::write(path, "1")?;
|
||||
@@ -280,7 +287,7 @@ pub async fn get_virtio_blk_ccw_device_name(
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
device: &ccw::Device,
|
||||
) -> Result<String> {
|
||||
let matcher = VirtioBlkCCWMatcher::new(&create_ccw_root_bus_path(), device);
|
||||
let matcher = VirtioBlkCCWMatcher::new(CCW_ROOT_BUS_PATH, device);
|
||||
let uev = wait_for_uevent(sandbox, matcher).await?;
|
||||
let devname = uev.devname;
|
||||
return match Path::new(SYSTEM_DEV_PATH).join(&devname).to_str() {
|
||||
@@ -401,6 +408,39 @@ async fn get_vfio_device_name(sandbox: &Arc<Mutex<Sandbox>>, grp: IommuGroup) ->
|
||||
Ok(format!("{}/{}", SYSTEM_DEV_PATH, &uev.devname))
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[derive(Debug)]
|
||||
struct ApMatcher {
|
||||
syspath: String,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
impl ApMatcher {
|
||||
fn new(address: ap::Address) -> ApMatcher {
|
||||
ApMatcher {
|
||||
syspath: format!(
|
||||
"{}/card{:02x}/{}",
|
||||
AP_ROOT_BUS_PATH, address.adapter_id, address
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
impl UeventMatcher for ApMatcher {
|
||||
fn is_match(&self, uev: &Uevent) -> bool {
|
||||
uev.action == "add" && uev.devpath == self.syspath
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[instrument]
|
||||
async fn wait_for_ap_device(sandbox: &Arc<Mutex<Sandbox>>, address: ap::Address) -> Result<()> {
|
||||
let matcher = ApMatcher::new(address);
|
||||
wait_for_uevent(sandbox, matcher).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Scan SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
||||
#[instrument]
|
||||
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||
@@ -699,7 +739,7 @@ async fn virtio_nvdimm_device_handler(
|
||||
Ok(DevNumUpdate::from_vm_path(&device.vm_path)?.into())
|
||||
}
|
||||
|
||||
fn split_vfio_option(opt: &str) -> Option<(&str, &str)> {
|
||||
fn split_vfio_pci_option(opt: &str) -> Option<(&str, &str)> {
|
||||
let mut tokens = opt.split('=');
|
||||
let hostbdf = tokens.next()?;
|
||||
let path = tokens.next()?;
|
||||
@@ -714,14 +754,18 @@ fn split_vfio_option(opt: &str) -> Option<(&str, &str)> {
|
||||
// Each option should have the form "DDDD:BB:DD.F=<pcipath>"
|
||||
// DDDD:BB:DD.F is the device's PCI address in the host
|
||||
// <pcipath> is a PCI path to the device in the guest (see pci.rs)
|
||||
async fn vfio_device_handler(device: &Device, sandbox: &Arc<Mutex<Sandbox>>) -> Result<SpecUpdate> {
|
||||
let vfio_in_guest = device.field_type != DRIVER_VFIO_GK_TYPE;
|
||||
#[instrument]
|
||||
async fn vfio_pci_device_handler(
|
||||
device: &Device,
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
) -> Result<SpecUpdate> {
|
||||
let vfio_in_guest = device.type_ != DRIVER_VFIO_PCI_GK_TYPE;
|
||||
let mut pci_fixups = Vec::<(pci::Address, pci::Address)>::new();
|
||||
let mut group = None;
|
||||
|
||||
for opt in device.options.iter() {
|
||||
let (host, pcipath) =
|
||||
split_vfio_option(opt).ok_or_else(|| anyhow!("Malformed VFIO option {:?}", opt))?;
|
||||
let (host, pcipath) = split_vfio_pci_option(opt)
|
||||
.ok_or_else(|| anyhow!("Malformed VFIO PCI option {:?}", opt))?;
|
||||
let host =
|
||||
pci::Address::from_str(host).context("Bad host PCI address in VFIO option {:?}")?;
|
||||
let pcipath = pci::Path::from_str(pcipath)?;
|
||||
@@ -763,6 +807,28 @@ async fn vfio_device_handler(device: &Device, sandbox: &Arc<Mutex<Sandbox>>) ->
|
||||
})
|
||||
}
|
||||
|
||||
// The VFIO AP (Adjunct Processor) device handler takes all the APQNs provided as device options
|
||||
// and awaits them. It sets the minimum AP rescan time of 5 seconds and temporarily adds that
|
||||
// amount to the hotplug timeout.
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[instrument]
|
||||
async fn vfio_ap_device_handler(
|
||||
device: &Device,
|
||||
sandbox: &Arc<Mutex<Sandbox>>,
|
||||
) -> Result<SpecUpdate> {
|
||||
// Force AP bus rescan
|
||||
fs::write(AP_SCANS_PATH, "1")?;
|
||||
for apqn in device.options.iter() {
|
||||
wait_for_ap_device(sandbox, ap::Address::from_str(apqn)?).await?;
|
||||
}
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "s390x"))]
|
||||
async fn vfio_ap_device_handler(_: &Device, _: &Arc<Mutex<Sandbox>>) -> Result<SpecUpdate> {
|
||||
Err(anyhow!("AP is only supported on s390x"))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn add_devices(
|
||||
devices: &[Device],
|
||||
@@ -808,9 +874,9 @@ pub async fn add_devices(
|
||||
async fn add_device(device: &Device, sandbox: &Arc<Mutex<Sandbox>>) -> Result<SpecUpdate> {
|
||||
// log before validation to help with debugging gRPC protocol version differences.
|
||||
info!(sl!(), "device-id: {}, device-type: {}, device-vm-path: {}, device-container-path: {}, device-options: {:?}",
|
||||
device.id, device.field_type, device.vm_path, device.container_path, device.options);
|
||||
device.id, device.type_, device.vm_path, device.container_path, device.options);
|
||||
|
||||
if device.field_type.is_empty() {
|
||||
if device.type_.is_empty() {
|
||||
return Err(anyhow!("invalid type for device {:?}", device));
|
||||
}
|
||||
|
||||
@@ -822,14 +888,17 @@ async fn add_device(device: &Device, sandbox: &Arc<Mutex<Sandbox>>) -> Result<Sp
|
||||
return Err(anyhow!("invalid container path for device {:?}", device));
|
||||
}
|
||||
|
||||
match device.field_type.as_str() {
|
||||
match device.type_.as_str() {
|
||||
DRIVER_BLK_TYPE => virtio_blk_device_handler(device, sandbox).await,
|
||||
DRIVER_BLK_CCW_TYPE => virtio_blk_ccw_device_handler(device, sandbox).await,
|
||||
DRIVER_MMIO_BLK_TYPE => virtiommio_blk_device_handler(device, sandbox).await,
|
||||
DRIVER_NVDIMM_TYPE => virtio_nvdimm_device_handler(device, sandbox).await,
|
||||
DRIVER_SCSI_TYPE => virtio_scsi_device_handler(device, sandbox).await,
|
||||
DRIVER_VFIO_GK_TYPE | DRIVER_VFIO_TYPE => vfio_device_handler(device, sandbox).await,
|
||||
_ => Err(anyhow!("Unknown device type {}", device.field_type)),
|
||||
DRIVER_VFIO_PCI_GK_TYPE | DRIVER_VFIO_PCI_TYPE => {
|
||||
vfio_pci_device_handler(device, sandbox).await
|
||||
}
|
||||
DRIVER_VFIO_AP_TYPE => vfio_ap_device_handler(device, sandbox).await,
|
||||
_ => Err(anyhow!("Unknown device type {}", device.type_)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1378,7 +1447,7 @@ mod tests {
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[tokio::test]
|
||||
async fn test_virtio_blk_ccw_matcher() {
|
||||
let root_bus = create_ccw_root_bus_path();
|
||||
let root_bus = CCW_ROOT_BUS_PATH;
|
||||
let subsystem = "block";
|
||||
let devname = "vda";
|
||||
let relpath = "0.0.0002";
|
||||
@@ -1487,13 +1556,13 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_vfio_option() {
|
||||
fn test_split_vfio_pci_option() {
|
||||
assert_eq!(
|
||||
split_vfio_option("0000:01:00.0=02/01"),
|
||||
split_vfio_pci_option("0000:01:00.0=02/01"),
|
||||
Some(("0000:01:00.0", "02/01"))
|
||||
);
|
||||
assert_eq!(split_vfio_option("0000:01:00.0=02/01=rubbish"), None);
|
||||
assert_eq!(split_vfio_option("0000:01:00.0"), None);
|
||||
assert_eq!(split_vfio_pci_option("0000:01:00.0=02/01=rubbish"), None);
|
||||
assert_eq!(split_vfio_pci_option("0000:01:00.0"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1572,4 +1641,35 @@ mod tests {
|
||||
// Test dev2
|
||||
assert!(pci_iommu_group(&syspci, dev2).is_err());
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[tokio::test]
|
||||
async fn test_vfio_ap_matcher() {
|
||||
let subsystem = "ap";
|
||||
let card = "0a";
|
||||
let relpath = format!("{}.0001", card);
|
||||
|
||||
let mut uev = Uevent::default();
|
||||
uev.action = U_EVENT_ACTION_ADD.to_string();
|
||||
uev.subsystem = subsystem.to_string();
|
||||
uev.devpath = format!("{}/card{}/{}", AP_ROOT_BUS_PATH, card, relpath);
|
||||
|
||||
let ap_address = ap::Address::from_str(&relpath).unwrap();
|
||||
let matcher = ApMatcher::new(ap_address);
|
||||
|
||||
assert!(matcher.is_match(&uev));
|
||||
|
||||
let mut uev_remove = uev.clone();
|
||||
uev_remove.action = U_EVENT_ACTION_REMOVE.to_string();
|
||||
assert!(!matcher.is_match(&uev_remove));
|
||||
|
||||
let mut uev_other_device = uev.clone();
|
||||
uev_other_device.devpath = format!(
|
||||
"{}/card{}/{}",
|
||||
AP_ROOT_BUS_PATH,
|
||||
card,
|
||||
format!("{}.0002", card)
|
||||
);
|
||||
assert!(!matcher.is_match(&uev_other_device));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
/// Linux ABI related constants.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
@@ -64,10 +66,14 @@ pub fn create_pci_root_bus_path() -> String {
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
pub fn create_ccw_root_bus_path() -> String {
|
||||
String::from("/devices/css0")
|
||||
cfg_if! {
|
||||
if #[cfg(target_arch = "s390x")] {
|
||||
pub const CCW_ROOT_BUS_PATH: &str = "/devices/css0";
|
||||
pub const AP_ROOT_BUS_PATH: &str = "/devices/ap";
|
||||
pub const AP_SCANS_PATH: &str = "/sys/bus/ap/scans";
|
||||
}
|
||||
}
|
||||
|
||||
// From https://www.kernel.org/doc/Documentation/acpi/namespace.txt
|
||||
// The Linux kernel's core ACPI subsystem creates struct acpi_device
|
||||
// objects for ACPI namespace objects representing devices, power resources
|
||||
|
||||
@@ -20,6 +20,7 @@ extern crate scopeguard;
|
||||
extern crate slog;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use cfg_if::cfg_if;
|
||||
use clap::{AppSettings, Parser};
|
||||
use nix::fcntl::OFlag;
|
||||
use nix::sys::socket::{self, AddressFamily, SockFlag, SockType, VsockAddr};
|
||||
@@ -34,8 +35,6 @@ use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use tracing::{instrument, span};
|
||||
|
||||
#[cfg(target_arch = "s390x")]
|
||||
mod ccw;
|
||||
mod config;
|
||||
mod console;
|
||||
mod device;
|
||||
@@ -74,6 +73,13 @@ use tokio::{
|
||||
mod rpc;
|
||||
mod tracer;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_arch = "s390x")] {
|
||||
mod ap;
|
||||
mod ccw;
|
||||
}
|
||||
}
|
||||
|
||||
const NAME: &str = "kata-agent";
|
||||
|
||||
lazy_static! {
|
||||
|
||||
@@ -211,10 +211,10 @@ async fn ephemeral_storage_handler(
|
||||
// By now we only support one option field: "fsGroup" which
|
||||
// isn't an valid mount option, thus we should remove it when
|
||||
// do mount.
|
||||
if storage.options.len() > 0 {
|
||||
if !storage.options.is_empty() {
|
||||
// ephemeral_storage didn't support mount options except fsGroup.
|
||||
let mut new_storage = storage.clone();
|
||||
new_storage.options = protobuf::RepeatedField::default();
|
||||
new_storage.options = Default::default();
|
||||
common_storage_handler(logger, &new_storage)?;
|
||||
|
||||
let opts_vec: Vec<String> = storage.options.to_vec();
|
||||
@@ -240,6 +240,70 @@ async fn ephemeral_storage_handler(
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
// update_ephemeral_mounts takes a list of ephemeral mounts and remounts them
|
||||
// with mount options passed by the caller
|
||||
#[instrument]
|
||||
pub async fn update_ephemeral_mounts(
|
||||
logger: Logger,
|
||||
storages: Vec<Storage>,
|
||||
sandbox: Arc<Mutex<Sandbox>>,
|
||||
) -> Result<()> {
|
||||
for (_, storage) in storages.iter().enumerate() {
|
||||
let handler_name = storage.driver.clone();
|
||||
let logger = logger.new(o!(
|
||||
"msg" => "updating tmpfs storage",
|
||||
"subsystem" => "storage",
|
||||
"storage-type" => handler_name.to_owned()));
|
||||
|
||||
match handler_name.as_str() {
|
||||
DRIVER_EPHEMERAL_TYPE => {
|
||||
fs::create_dir_all(Path::new(&storage.mount_point))?;
|
||||
|
||||
if storage.options.is_empty() {
|
||||
continue;
|
||||
} else {
|
||||
// assume that fsGid has already been set
|
||||
let mut opts = Vec::<&str>::new();
|
||||
for (_, opt) in storage.options.iter().enumerate() {
|
||||
if opt.starts_with(FS_GID) {
|
||||
continue;
|
||||
}
|
||||
opts.push(opt)
|
||||
}
|
||||
let mount_path = Path::new(&storage.mount_point);
|
||||
let src_path = Path::new(&storage.source);
|
||||
|
||||
let (flags, options) = parse_mount_flags_and_options(opts);
|
||||
|
||||
info!(logger, "mounting storage";
|
||||
"mount-source" => src_path.display(),
|
||||
"mount-destination" => mount_path.display(),
|
||||
"mount-fstype" => storage.fstype.as_str(),
|
||||
"mount-options" => options.as_str(),
|
||||
);
|
||||
|
||||
return baremount(
|
||||
src_path,
|
||||
mount_path,
|
||||
storage.fstype.as_str(),
|
||||
flags,
|
||||
options.as_str(),
|
||||
&logger,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!(
|
||||
"Unsupported storage type for syncing mounts {}. Only ephemeral storage update is supported",
|
||||
storage.driver.to_owned()
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn overlayfs_storage_handler(
|
||||
logger: &Logger,
|
||||
@@ -590,7 +654,7 @@ pub fn set_ownership(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||
if storage.fs_group.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
let fs_group = storage.get_fs_group();
|
||||
let fs_group = storage.fs_group();
|
||||
|
||||
let mut read_only = false;
|
||||
let opts_vec: Vec<String> = storage.options.to_vec();
|
||||
@@ -607,7 +671,7 @@ pub fn set_ownership(logger: &Logger, storage: &Storage) -> Result<()> {
|
||||
err
|
||||
})?;
|
||||
|
||||
if fs_group.group_change_policy == FSGroupChangePolicy::OnRootMismatch
|
||||
if fs_group.group_change_policy == FSGroupChangePolicy::OnRootMismatch.into()
|
||||
&& metadata.gid() == fs_group.group_id
|
||||
{
|
||||
let mut mask = if read_only { RO_MASK } else { RW_MASK };
|
||||
@@ -1030,7 +1094,6 @@ fn parse_options(option_list: Vec<String>) -> HashMap<String, String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use protobuf::RepeatedField;
|
||||
use protocols::agent::FSGroup;
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
@@ -1951,9 +2014,8 @@ mod tests {
|
||||
mount_path: "rw_mount",
|
||||
fs_group: Some(FSGroup {
|
||||
group_id: 3000,
|
||||
group_change_policy: FSGroupChangePolicy::Always,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
group_change_policy: FSGroupChangePolicy::Always.into(),
|
||||
..Default::default()
|
||||
}),
|
||||
read_only: false,
|
||||
expected_group_id: 3000,
|
||||
@@ -1963,9 +2025,8 @@ mod tests {
|
||||
mount_path: "ro_mount",
|
||||
fs_group: Some(FSGroup {
|
||||
group_id: 3000,
|
||||
group_change_policy: FSGroupChangePolicy::OnRootMismatch,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
group_change_policy: FSGroupChangePolicy::OnRootMismatch.into(),
|
||||
..Default::default()
|
||||
}),
|
||||
read_only: true,
|
||||
expected_group_id: 3000,
|
||||
@@ -1985,10 +2046,7 @@ mod tests {
|
||||
let directory_mode = mount_dir.as_path().metadata().unwrap().permissions().mode();
|
||||
let mut storage_data = Storage::new();
|
||||
if d.read_only {
|
||||
storage_data.set_options(RepeatedField::from_slice(&[
|
||||
"foo".to_string(),
|
||||
"ro".to_string(),
|
||||
]));
|
||||
storage_data.set_options(vec!["foo".to_string(), "ro".to_string()]);
|
||||
}
|
||||
if let Some(fs_group) = d.fs_group.clone() {
|
||||
storage_data.set_fs_group(fs_group);
|
||||
|
||||
@@ -7,7 +7,6 @@ use anyhow::{anyhow, Context, Result};
|
||||
use futures::{future, StreamExt, TryStreamExt};
|
||||
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
|
||||
use nix::errno::Errno;
|
||||
use protobuf::RepeatedField;
|
||||
use protocols::types::{ARPNeighbor, IPAddress, IPFamily, Interface, Route};
|
||||
use rtnetlink::{new_connection, packet, IpVersion};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
@@ -83,8 +82,8 @@ impl Handle {
|
||||
|
||||
// Add new ip addresses from request
|
||||
for ip_address in &iface.IPAddresses {
|
||||
let ip = IpAddr::from_str(ip_address.get_address())?;
|
||||
let mask = ip_address.get_mask().parse::<u8>()?;
|
||||
let ip = IpAddr::from_str(ip_address.address())?;
|
||||
let mask = ip_address.mask().parse::<u8>()?;
|
||||
|
||||
self.add_addresses(link.index(), std::iter::once(IpNetwork::new(ip, mask)?))
|
||||
.await?;
|
||||
@@ -152,7 +151,7 @@ impl Handle {
|
||||
.map(|p| p.try_into())
|
||||
.collect::<Result<Vec<IPAddress>>>()?;
|
||||
|
||||
iface.IPAddresses = RepeatedField::from_vec(ips);
|
||||
iface.IPAddresses = ips;
|
||||
|
||||
list.push(iface);
|
||||
}
|
||||
@@ -334,7 +333,7 @@ impl Handle {
|
||||
|
||||
// `rtnetlink` offers a separate request builders for different IP versions (IP v4 and v6).
|
||||
// This if branch is a bit clumsy because it does almost the same.
|
||||
if route.get_family() == IPFamily::v6 {
|
||||
if route.family() == IPFamily::v6 {
|
||||
let dest_addr = if !route.dest.is_empty() {
|
||||
Ipv6Network::from_str(&route.dest)?
|
||||
} else {
|
||||
@@ -368,9 +367,9 @@ impl Handle {
|
||||
if Errno::from_i32(message.code.abs()) != Errno::EEXIST {
|
||||
return Err(anyhow!(
|
||||
"Failed to add IP v6 route (src: {}, dst: {}, gtw: {},Err: {})",
|
||||
route.get_source(),
|
||||
route.get_dest(),
|
||||
route.get_gateway(),
|
||||
route.source(),
|
||||
route.dest(),
|
||||
route.gateway(),
|
||||
message
|
||||
));
|
||||
}
|
||||
@@ -409,9 +408,9 @@ impl Handle {
|
||||
if Errno::from_i32(message.code.abs()) != Errno::EEXIST {
|
||||
return Err(anyhow!(
|
||||
"Failed to add IP v4 route (src: {}, dst: {}, gtw: {},Err: {})",
|
||||
route.get_source(),
|
||||
route.get_dest(),
|
||||
route.get_gateway(),
|
||||
route.source(),
|
||||
route.dest(),
|
||||
route.gateway(),
|
||||
message
|
||||
));
|
||||
}
|
||||
@@ -506,7 +505,7 @@ impl Handle {
|
||||
self.add_arp_neighbor(&neigh).await.map_err(|err| {
|
||||
anyhow!(
|
||||
"Failed to add ARP neighbor {}: {:?}",
|
||||
neigh.get_toIPAddress().get_address(),
|
||||
neigh.toIPAddress().address(),
|
||||
err
|
||||
)
|
||||
})?;
|
||||
@@ -725,7 +724,7 @@ impl TryFrom<Address> for IPAddress {
|
||||
let mask = format!("{}", value.0.header.prefix_len);
|
||||
|
||||
Ok(IPAddress {
|
||||
family,
|
||||
family: family.into(),
|
||||
address,
|
||||
mask,
|
||||
..Default::default()
|
||||
|
||||
@@ -7,6 +7,7 @@ use anyhow::{anyhow, Result};
|
||||
use nix::mount::{self, MsFlags};
|
||||
use slog::Logger;
|
||||
use std::fs;
|
||||
use std::path;
|
||||
|
||||
const KATA_GUEST_SANDBOX_DNS_FILE: &str = "/run/kata-containers/sandbox/resolv.conf";
|
||||
const GUEST_DNS_FILE: &str = "/etc/resolv.conf";
|
||||
@@ -64,6 +65,12 @@ fn do_setup_guest_dns(logger: Logger, dns_list: Vec<String>, src: &str, dst: &st
|
||||
.map(|x| x.trim())
|
||||
.collect::<Vec<&str>>()
|
||||
.join("\n");
|
||||
|
||||
// make sure the src file's parent path exist.
|
||||
let file_path = path::Path::new(src);
|
||||
if let Some(p) = file_path.parent() {
|
||||
fs::create_dir_all(p)?;
|
||||
}
|
||||
fs::write(src, content)?;
|
||||
|
||||
// bind mount to /etc/resolv.conf
|
||||
|
||||
@@ -21,22 +21,26 @@ use ttrpc::{
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use cgroups::freezer::FreezerState;
|
||||
use oci::{LinuxNamespace, Root, Spec};
|
||||
use protobuf::{Message, RepeatedField, SingularPtrField};
|
||||
use protobuf::{MessageDyn, MessageField};
|
||||
use protocols::agent::{
|
||||
AddSwapRequest, AgentDetails, CopyFileRequest, GetIPTablesRequest, GetIPTablesResponse,
|
||||
GuestDetailsResponse, Interfaces, Metrics, OOMEvent, ReadStreamResponse, Routes,
|
||||
SetIPTablesRequest, SetIPTablesResponse, StatsContainerResponse, VolumeStatsRequest,
|
||||
WaitProcessResponse, WriteStreamResponse,
|
||||
};
|
||||
use protocols::csi::{VolumeCondition, VolumeStatsResponse, VolumeUsage, VolumeUsage_Unit};
|
||||
use protocols::csi::{
|
||||
volume_usage::Unit as VolumeUsage_Unit, VolumeCondition, VolumeStatsResponse, VolumeUsage,
|
||||
};
|
||||
use protocols::empty::Empty;
|
||||
use protocols::health::{
|
||||
HealthCheckResponse, HealthCheckResponse_ServingStatus, VersionCheckResponse,
|
||||
health_check_response::ServingStatus as HealthCheckResponse_ServingStatus, HealthCheckResponse,
|
||||
VersionCheckResponse,
|
||||
};
|
||||
use protocols::types::Interface;
|
||||
use protocols::{agent_ttrpc_async as agent_ttrpc, health_ttrpc_async as health_ttrpc};
|
||||
use rustjail::cgroups::notifier;
|
||||
use rustjail::container::{BaseContainer, Container, LinuxContainer, SYSTEMD_CGROUP_PATH_FORMAT};
|
||||
use rustjail::mount::parse_mount_table;
|
||||
use rustjail::process::Process;
|
||||
use rustjail::specconv::CreateOpts;
|
||||
|
||||
@@ -51,7 +55,7 @@ use crate::device::{
|
||||
};
|
||||
use crate::linux_abi::*;
|
||||
use crate::metrics::get_metrics;
|
||||
use crate::mount::{add_storages, baremount, STORAGE_HANDLER_LIST};
|
||||
use crate::mount::{add_storages, baremount, update_ephemeral_mounts, STORAGE_HANDLER_LIST};
|
||||
use crate::namespace::{NSTYPEIPC, NSTYPEPID, NSTYPEUTS};
|
||||
use crate::network::setup_guest_dns;
|
||||
use crate::pci;
|
||||
@@ -93,6 +97,7 @@ const USR_IP6TABLES_SAVE: &str = "/usr/sbin/ip6tables-save";
|
||||
const IP6TABLES_SAVE: &str = "/sbin/ip6tables-save";
|
||||
const USR_IP6TABLES_RESTORE: &str = "/usr/sbin/ip6tables-save";
|
||||
const IP6TABLES_RESTORE: &str = "/sbin/ip6tables-restore";
|
||||
const KATA_GUEST_SHARE_DIR: &str = "/run/kata-containers/shared/containers/";
|
||||
|
||||
const ERR_CANNOT_GET_WRITER: &str = "Cannot get writer";
|
||||
const ERR_INVALID_BLOCK_SIZE: &str = "Invalid block size";
|
||||
@@ -124,11 +129,11 @@ macro_rules! is_allowed {
|
||||
if !AGENT_CONFIG
|
||||
.read()
|
||||
.await
|
||||
.is_allowed_endpoint($req.descriptor().name())
|
||||
.is_allowed_endpoint($req.descriptor_dyn().name())
|
||||
{
|
||||
return Err(ttrpc_error!(
|
||||
ttrpc::Code::UNIMPLEMENTED,
|
||||
format!("{} is blocked", $req.descriptor().name()),
|
||||
format!("{} is blocked", $req.descriptor_dyn().name()),
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -151,7 +156,7 @@ impl AgentService {
|
||||
kata_sys_util::validate::verify_id(&cid)?;
|
||||
|
||||
let mut oci_spec = req.OCI.clone();
|
||||
let use_sandbox_pidns = req.get_sandbox_pidns();
|
||||
let use_sandbox_pidns = req.sandbox_pidns();
|
||||
|
||||
let sandbox;
|
||||
let mut s;
|
||||
@@ -785,7 +790,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
) -> ttrpc::Result<protocols::empty::Empty> {
|
||||
trace_rpc_call!(ctx, "pause_container", req);
|
||||
is_allowed!(req);
|
||||
let cid = req.get_container_id();
|
||||
let cid = req.container_id();
|
||||
let s = Arc::clone(&self.sandbox);
|
||||
let mut sandbox = s.lock().await;
|
||||
|
||||
@@ -809,7 +814,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
) -> ttrpc::Result<protocols::empty::Empty> {
|
||||
trace_rpc_call!(ctx, "resume_container", req);
|
||||
is_allowed!(req);
|
||||
let cid = req.get_container_id();
|
||||
let cid = req.container_id();
|
||||
let s = Arc::clone(&self.sandbox);
|
||||
let mut sandbox = s.lock().await;
|
||||
|
||||
@@ -826,6 +831,29 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
Ok(Empty::new())
|
||||
}
|
||||
|
||||
async fn remove_stale_virtiofs_share_mounts(
|
||||
&self,
|
||||
ctx: &TtrpcContext,
|
||||
req: protocols::agent::RemoveStaleVirtiofsShareMountsRequest,
|
||||
) -> ttrpc::Result<Empty> {
|
||||
trace_rpc_call!(ctx, "remove_stale_virtiofs_share_mounts", req);
|
||||
is_allowed!(req);
|
||||
let mount_infos = parse_mount_table("/proc/self/mountinfo")
|
||||
.map_err(|e| ttrpc_error!(ttrpc::Code::INTERNAL, e))?;
|
||||
for m in &mount_infos {
|
||||
if m.mount_point.starts_with(KATA_GUEST_SHARE_DIR) {
|
||||
// stat the mount point, virtiofs daemon will remove the stale cache and release the fds if the mount point doesn't exist any more.
|
||||
// More details in https://github.com/kata-containers/kata-containers/issues/6455#issuecomment-1477137277
|
||||
match stat::stat(Path::new(&m.mount_point)) {
|
||||
Ok(_) => info!(sl!(), "stat {} success", m.mount_point),
|
||||
Err(e) => info!(sl!(), "stat {} failed: {}", m.mount_point, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Empty::new())
|
||||
}
|
||||
|
||||
async fn write_stdin(
|
||||
&self,
|
||||
_ctx: &TtrpcContext,
|
||||
@@ -964,16 +992,12 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
trace_rpc_call!(ctx, "update_routes", req);
|
||||
is_allowed!(req);
|
||||
|
||||
let new_routes = req
|
||||
.routes
|
||||
.into_option()
|
||||
.map(|r| r.Routes.into_vec())
|
||||
.ok_or_else(|| {
|
||||
ttrpc_error!(
|
||||
ttrpc::Code::INVALID_ARGUMENT,
|
||||
"empty update routes request".to_string(),
|
||||
)
|
||||
})?;
|
||||
let new_routes = req.routes.into_option().map(|r| r.Routes).ok_or_else(|| {
|
||||
ttrpc_error!(
|
||||
ttrpc::Code::INVALID_ARGUMENT,
|
||||
"empty update routes request".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut sandbox = self.sandbox.lock().await;
|
||||
|
||||
@@ -992,11 +1016,28 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
})?;
|
||||
|
||||
Ok(protocols::agent::Routes {
|
||||
Routes: RepeatedField::from_vec(list),
|
||||
Routes: list,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
async fn update_ephemeral_mounts(
|
||||
&self,
|
||||
ctx: &TtrpcContext,
|
||||
req: protocols::agent::UpdateEphemeralMountsRequest,
|
||||
) -> ttrpc::Result<Empty> {
|
||||
trace_rpc_call!(ctx, "update_mounts", req);
|
||||
is_allowed!(req);
|
||||
|
||||
match update_ephemeral_mounts(sl!(), req.storages.to_vec(), self.sandbox.clone()).await {
|
||||
Ok(_) => Ok(Empty::new()),
|
||||
Err(e) => Err(ttrpc_error!(
|
||||
ttrpc::Code::INTERNAL,
|
||||
format!("Failed to update mounts: {:?}", e),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_ip_tables(
|
||||
&self,
|
||||
ctx: &TtrpcContext,
|
||||
@@ -1174,7 +1215,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
})?;
|
||||
|
||||
Ok(protocols::agent::Interfaces {
|
||||
Interfaces: RepeatedField::from_vec(list),
|
||||
Interfaces: list,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
@@ -1197,7 +1238,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
.map_err(|e| ttrpc_error!(ttrpc::Code::INTERNAL, format!("list routes: {:?}", e)))?;
|
||||
|
||||
Ok(protocols::agent::Routes {
|
||||
Routes: RepeatedField::from_vec(list),
|
||||
Routes: list,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
@@ -1313,7 +1354,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
let neighs = req
|
||||
.neighbors
|
||||
.into_option()
|
||||
.map(|n| n.ARPNeighbors.into_vec())
|
||||
.map(|n| n.ARPNeighbors)
|
||||
.ok_or_else(|| {
|
||||
ttrpc_error!(
|
||||
ttrpc::Code::INVALID_ARGUMENT,
|
||||
@@ -1397,7 +1438,7 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
|
||||
// to get agent details
|
||||
let detail = get_agent_details();
|
||||
resp.agent_details = SingularPtrField::some(detail);
|
||||
resp.agent_details = MessageField::some(detail);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
@@ -1522,8 +1563,8 @@ impl agent_ttrpc::AgentService for AgentService {
|
||||
.map(|u| usage_vec.push(u))
|
||||
.map_err(|e| ttrpc_error!(ttrpc::Code::INTERNAL, e))?;
|
||||
|
||||
resp.usage = RepeatedField::from_vec(usage_vec);
|
||||
resp.volume_condition = SingularPtrField::some(condition);
|
||||
resp.usage = usage_vec;
|
||||
resp.volume_condition = MessageField::some(condition);
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@@ -1627,7 +1668,7 @@ fn get_volume_capacity_stats(path: &str) -> Result<VolumeUsage> {
|
||||
usage.total = stat.blocks() * block_size;
|
||||
usage.available = stat.blocks_free() * block_size;
|
||||
usage.used = usage.total - usage.available;
|
||||
usage.unit = VolumeUsage_Unit::BYTES;
|
||||
usage.unit = VolumeUsage_Unit::BYTES.into();
|
||||
|
||||
Ok(usage)
|
||||
}
|
||||
@@ -1639,7 +1680,7 @@ fn get_volume_inode_stats(path: &str) -> Result<VolumeUsage> {
|
||||
usage.total = stat.files();
|
||||
usage.available = stat.files_free();
|
||||
usage.used = usage.total - usage.available;
|
||||
usage.unit = VolumeUsage_Unit::INODES;
|
||||
usage.unit = VolumeUsage_Unit::INODES.into();
|
||||
|
||||
Ok(usage)
|
||||
}
|
||||
@@ -1659,14 +1700,12 @@ fn get_agent_details() -> AgentDetails {
|
||||
detail.set_supports_seccomp(have_seccomp());
|
||||
detail.init_daemon = unistd::getpid() == Pid::from_raw(1);
|
||||
|
||||
detail.device_handlers = RepeatedField::new();
|
||||
detail.storage_handlers = RepeatedField::from_vec(
|
||||
STORAGE_HANDLER_LIST
|
||||
.to_vec()
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect(),
|
||||
);
|
||||
detail.device_handlers = Vec::new();
|
||||
detail.storage_handlers = STORAGE_HANDLER_LIST
|
||||
.to_vec()
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect();
|
||||
|
||||
detail
|
||||
}
|
||||
@@ -1891,23 +1930,18 @@ fn do_copy_file(req: &CopyFileRequest) -> Result<()> {
|
||||
));
|
||||
}
|
||||
|
||||
let parent = path.parent();
|
||||
|
||||
let dir = if let Some(parent) = parent {
|
||||
parent.to_path_buf()
|
||||
} else {
|
||||
PathBuf::from("/")
|
||||
};
|
||||
|
||||
fs::create_dir_all(&dir).or_else(|e| {
|
||||
if e.kind() != std::io::ErrorKind::AlreadyExists {
|
||||
return Err(e);
|
||||
if let Some(parent) = path.parent() {
|
||||
if !parent.exists() {
|
||||
let dir = parent.to_path_buf();
|
||||
if let Err(e) = fs::create_dir_all(&dir) {
|
||||
if e.kind() != std::io::ErrorKind::AlreadyExists {
|
||||
return Err(e.into());
|
||||
}
|
||||
} else {
|
||||
std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(req.dir_mode))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(req.dir_mode))?;
|
||||
}
|
||||
|
||||
let mut tmpfile = path.clone();
|
||||
tmpfile.set_extension("tmp");
|
||||
@@ -2025,7 +2059,7 @@ fn load_kernel_module(module: &protocols::agent::KernelModule) -> Result<()> {
|
||||
|
||||
let mut args = vec!["-v".to_string(), module.name.clone()];
|
||||
|
||||
if module.parameters.len() > 0 {
|
||||
if !module.parameters.is_empty() {
|
||||
args.extend(module.parameters.to_vec())
|
||||
}
|
||||
|
||||
|
||||
864
src/dragonball/Cargo.lock
generated
864
src/dragonball/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,11 @@ dbs-boot = "0.3.0"
|
||||
dbs-device = "0.2.0"
|
||||
dbs-interrupt = { version = "0.2.0", features = ["kvm-irq"] }
|
||||
dbs-legacy-devices = "0.1.0"
|
||||
dbs-upcall = { version = "0.1.0", optional = true }
|
||||
dbs-upcall = { version = "0.2.0", optional = true }
|
||||
dbs-utils = "0.2.0"
|
||||
dbs-virtio-devices = { version = "0.1.0", optional = true, features = ["virtio-mmio"] }
|
||||
kvm-bindings = "0.5.0"
|
||||
kvm-ioctls = "0.11.0"
|
||||
dbs-virtio-devices = { version = "0.2.0", optional = true, features = ["virtio-mmio"] }
|
||||
kvm-bindings = "0.6.0"
|
||||
kvm-ioctls = "0.12.0"
|
||||
lazy_static = "1.2"
|
||||
libc = "0.2.39"
|
||||
linux-loader = "0.6.0"
|
||||
@@ -37,8 +37,9 @@ slog = "2.5.2"
|
||||
slog-scope = "4.4.0"
|
||||
thiserror = "1"
|
||||
vmm-sys-util = "0.11.0"
|
||||
virtio-queue = { version = "0.4.0", optional = true }
|
||||
virtio-queue = { version = "0.6.0", optional = true }
|
||||
vm-memory = { version = "0.9.0", features = ["backend-mmap"] }
|
||||
crossbeam-channel = "0.5.6"
|
||||
|
||||
[dev-dependencies]
|
||||
slog-term = "2.9.0"
|
||||
@@ -47,7 +48,7 @@ test-utils = { path = "../libs/test-utils" }
|
||||
|
||||
[features]
|
||||
acpi = []
|
||||
atomic-guest-memory = [ "vm-memory/backend-atomic" ]
|
||||
atomic-guest-memory = ["vm-memory/backend-atomic"]
|
||||
hotplug = ["virtio-vsock"]
|
||||
virtio-vsock = ["dbs-virtio-devices/virtio-vsock", "virtio-queue"]
|
||||
virtio-blk = ["dbs-virtio-devices/virtio-blk", "virtio-queue"]
|
||||
|
||||
@@ -50,6 +50,8 @@ pub struct InstanceInfo {
|
||||
pub vmm_version: String,
|
||||
/// The pid of the current VMM process.
|
||||
pub pid: u32,
|
||||
/// The tid of the current VMM master thread.
|
||||
pub master_tid: u32,
|
||||
/// The state of async actions.
|
||||
pub async_state: AsyncState,
|
||||
/// List of tids of vcpu threads (vcpu index, tid)
|
||||
@@ -66,6 +68,7 @@ impl InstanceInfo {
|
||||
state: InstanceState::Uninitialized,
|
||||
vmm_version,
|
||||
pid: std::process::id(),
|
||||
master_tid: 0,
|
||||
async_state: AsyncState::Uninitialized,
|
||||
tids: Vec::new(),
|
||||
last_instance_downtime: 0,
|
||||
@@ -80,6 +83,7 @@ impl Default for InstanceInfo {
|
||||
state: InstanceState::Uninitialized,
|
||||
vmm_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
pid: std::process::id(),
|
||||
master_tid: 0,
|
||||
async_state: AsyncState::Uninitialized,
|
||||
tids: Vec::new(),
|
||||
last_instance_downtime: 0,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
// found in the THIRD-PARTY file.
|
||||
|
||||
use std::fs::File;
|
||||
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
|
||||
|
||||
use crossbeam_channel::{Receiver, Sender, TryRecvError};
|
||||
use log::{debug, error, info, warn};
|
||||
|
||||
use crate::error::{Result, StartMicroVmError, StopMicrovmError};
|
||||
@@ -676,9 +676,9 @@ fn handle_cpu_topology(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::mpsc::channel;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crossbeam_channel::unbounded;
|
||||
use dbs_utils::epoll_manager::EpollManager;
|
||||
use test_utils::skip_if_not_root;
|
||||
use vmm_sys_util::tempfile::TempFile;
|
||||
@@ -702,8 +702,8 @@ mod tests {
|
||||
}
|
||||
|
||||
fn check_request(&mut self) {
|
||||
let (to_vmm, from_api) = channel();
|
||||
let (to_api, from_vmm) = channel();
|
||||
let (to_vmm, from_api) = unbounded();
|
||||
let (to_api, from_vmm) = unbounded();
|
||||
|
||||
let epoll_mgr = EpollManager::default();
|
||||
let vmm = Arc::new(Mutex::new(create_vmm_instance(epoll_mgr.clone())));
|
||||
@@ -728,8 +728,8 @@ mod tests {
|
||||
fn test_vmm_action_receive_unknown() {
|
||||
skip_if_not_root!();
|
||||
|
||||
let (_to_vmm, from_api) = channel();
|
||||
let (to_api, _from_vmm) = channel();
|
||||
let (_to_vmm, from_api) = unbounded();
|
||||
let (to_api, _from_vmm) = unbounded();
|
||||
let epoll_mgr = EpollManager::default();
|
||||
let vmm = Arc::new(Mutex::new(create_vmm_instance(epoll_mgr.clone())));
|
||||
let mut vservice = VmmService::new(from_api, to_api);
|
||||
@@ -742,8 +742,8 @@ mod tests {
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn test_vmm_action_disconnected() {
|
||||
let (to_vmm, from_api) = channel();
|
||||
let (to_api, _from_vmm) = channel();
|
||||
let (to_vmm, from_api) = unbounded();
|
||||
let (to_api, _from_vmm) = unbounded();
|
||||
let epoll_mgr = EpollManager::default();
|
||||
let vmm = Arc::new(Mutex::new(create_vmm_instance(epoll_mgr.clone())));
|
||||
let mut vservice = VmmService::new(from_api, to_api);
|
||||
|
||||
@@ -231,7 +231,7 @@ where
|
||||
info.config.check_conflicts(config)?;
|
||||
}
|
||||
}
|
||||
self.info_list[index] = device_info;
|
||||
self.info_list[index].config = config.clone();
|
||||
index
|
||||
}
|
||||
None => {
|
||||
|
||||
@@ -776,3 +776,587 @@ impl Default for BlockDeviceMgr {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_utils::skip_if_not_root;
|
||||
use vmm_sys_util::tempfile::TempFile;
|
||||
|
||||
use super::*;
|
||||
use crate::test_utils::tests::create_vm_for_test;
|
||||
|
||||
#[test]
|
||||
fn test_block_device_type() {
|
||||
let dev_type = BlockDeviceType::get_type("spool:/device1");
|
||||
assert_eq!(dev_type, BlockDeviceType::Spool);
|
||||
let dev_type = BlockDeviceType::get_type("/device1");
|
||||
assert_eq!(dev_type, BlockDeviceType::RawBlock);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_block_devices_configs() {
|
||||
let mgr = BlockDeviceMgr::default();
|
||||
assert!(!mgr.has_root_block_device());
|
||||
assert!(!mgr.has_part_uuid_root());
|
||||
assert!(!mgr.is_read_only_root());
|
||||
assert_eq!(mgr.get_index_of_drive_id(""), None);
|
||||
assert_eq!(mgr.info_list.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_non_root_block_device() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file = TempFile::new().unwrap();
|
||||
let dummy_path = dummy_file.as_path().to_owned();
|
||||
let dummy_id = String::from("1");
|
||||
let dummy_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path.clone(),
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: dummy_id.clone(),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
assert!(BlockDeviceMgr::insert_device(
|
||||
vm.device_manager_mut(),
|
||||
ctx,
|
||||
dummy_block_device.clone(),
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
|
||||
assert!(!vm.device_manager().block_manager.has_root_block_device());
|
||||
assert!(!vm.device_manager().block_manager.has_part_uuid_root());
|
||||
assert!(!vm.device_manager().block_manager.is_read_only_root());
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
|
||||
assert_eq!(
|
||||
vm.device_manager().block_manager.info_list[0]
|
||||
.config
|
||||
.device_type(),
|
||||
BlockDeviceType::RawBlock
|
||||
);
|
||||
assert_eq!(
|
||||
vm.device_manager().block_manager.info_list[0]
|
||||
.config
|
||||
.queue_sizes(),
|
||||
[128u16]
|
||||
);
|
||||
|
||||
let dev_config = vm.device_manager().block_manager.iter().next().unwrap();
|
||||
assert_eq!(dev_config.config, dummy_block_device);
|
||||
assert!(vm
|
||||
.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_path(&dummy_path)
|
||||
.is_some());
|
||||
assert!(vm
|
||||
.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_id(&dummy_id)
|
||||
.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_blk_device_ratelimiters() {
|
||||
skip_if_not_root!();
|
||||
//Init vm for test.
|
||||
let mut vm = create_vm_for_test();
|
||||
let device_op_ctx = DeviceOpContext::new(
|
||||
Some(vm.epoll_manager().clone()),
|
||||
vm.device_manager(),
|
||||
Some(vm.vm_as().unwrap().clone()),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
let dummy_file = TempFile::new().unwrap();
|
||||
let dummy_path = dummy_file.as_path().to_owned();
|
||||
|
||||
let dummy_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: true,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), device_op_ctx, dummy_block_device)
|
||||
.unwrap();
|
||||
|
||||
let cfg = BlockDeviceConfigUpdateInfo {
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
};
|
||||
|
||||
let mut device_op_ctx = DeviceOpContext::new(
|
||||
Some(vm.epoll_manager().clone()),
|
||||
vm.device_manager(),
|
||||
Some(vm.vm_as().unwrap().clone()),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
vm.device_manager_mut()
|
||||
.block_manager
|
||||
.attach_devices(&mut device_op_ctx)
|
||||
.unwrap();
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
|
||||
|
||||
//Patch while the epoll handler is invalid.
|
||||
let expected_error = "could not send patch message to the block epoll handler".to_string();
|
||||
|
||||
assert_eq!(
|
||||
BlockDeviceMgr::update_device_ratelimiters(vm.device_manager_mut(), cfg)
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
expected_error
|
||||
);
|
||||
|
||||
//Invalid drive id
|
||||
let cfg2 = BlockDeviceConfigUpdateInfo {
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
};
|
||||
|
||||
let expected_error = format!("invalid block device id '{0}'", cfg2.drive_id);
|
||||
|
||||
assert_eq!(
|
||||
BlockDeviceMgr::update_device_ratelimiters(vm.device_manager_mut(), cfg2)
|
||||
.unwrap_err()
|
||||
.to_string(),
|
||||
expected_error
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_one_root_block_device() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file = TempFile::new().unwrap();
|
||||
let dummy_path = dummy_file.as_path().to_owned();
|
||||
let dummy_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: true,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
assert!(BlockDeviceMgr::insert_device(
|
||||
vm.device_manager_mut(),
|
||||
ctx,
|
||||
dummy_block_device.clone(),
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
|
||||
assert!(vm.device_manager().block_manager.has_root_block);
|
||||
assert!(!vm.device_manager().block_manager.has_part_uuid_root);
|
||||
assert!(vm.device_manager().block_manager.read_only_root);
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
|
||||
|
||||
let dev_config = vm.device_manager().block_manager.iter().next().unwrap();
|
||||
assert_eq!(dev_config.config, dummy_block_device);
|
||||
assert!(vm.device_manager().block_manager.is_read_only_root());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_two_root_block_devices_configs() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file_1 = TempFile::new().unwrap();
|
||||
let dummy_path_1 = dummy_file_1.as_path().to_owned();
|
||||
let root_block_device_1 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_1,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_2 = TempFile::new().unwrap();
|
||||
let dummy_path_2 = dummy_file_2.as_path().to_owned();
|
||||
let root_block_device_2 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_2,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_1).unwrap();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
assert!(
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_2)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Test BlockDevicesConfigs::add when you first add the root device and then the other devices.
|
||||
fn test_add_root_block_device_first() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file_1 = TempFile::new().unwrap();
|
||||
let dummy_path_1 = dummy_file_1.as_path().to_owned();
|
||||
let root_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_1,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_2 = TempFile::new().unwrap();
|
||||
let dummy_path_2 = dummy_file_2.as_path().to_owned();
|
||||
let dummy_block_device_2 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_2,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_3 = TempFile::new().unwrap();
|
||||
let dummy_path_3 = dummy_file_3.as_path().to_owned();
|
||||
let dummy_block_device_3 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_3,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("3"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
vm.device_manager_mut()
|
||||
.block_manager
|
||||
.create(root_block_device.clone())
|
||||
.unwrap();
|
||||
vm.device_manager_mut()
|
||||
.block_manager
|
||||
.create(dummy_block_device_2.clone())
|
||||
.unwrap();
|
||||
vm.device_manager_mut()
|
||||
.block_manager
|
||||
.create(dummy_block_device_3.clone())
|
||||
.unwrap();
|
||||
|
||||
assert!(vm.device_manager().block_manager.has_root_block_device(),);
|
||||
assert!(!vm.device_manager().block_manager.has_part_uuid_root());
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 3);
|
||||
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device).unwrap();
|
||||
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2).unwrap();
|
||||
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_3).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Test BlockDevicesConfigs::add when you add other devices first and then the root device.
|
||||
fn test_root_block_device_add_last() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file_1 = TempFile::new().unwrap();
|
||||
let dummy_path_1 = dummy_file_1.as_path().to_owned();
|
||||
let root_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_1,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_2 = TempFile::new().unwrap();
|
||||
let dummy_path_2 = dummy_file_2.as_path().to_owned();
|
||||
let dummy_block_device_2 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_2,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_3 = TempFile::new().unwrap();
|
||||
let dummy_path_3 = dummy_file_3.as_path().to_owned();
|
||||
let dummy_block_device_3 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_3,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("3"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone())
|
||||
.unwrap();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_3.clone())
|
||||
.unwrap();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device.clone())
|
||||
.unwrap();
|
||||
|
||||
assert!(vm.device_manager().block_manager.has_root_block_device(),);
|
||||
assert!(!vm.device_manager().block_manager.has_part_uuid_root());
|
||||
assert_eq!(vm.device_manager().block_manager.info_list.len(), 3);
|
||||
|
||||
let mut block_dev_iter = vm.device_manager().block_manager.iter();
|
||||
// The root device should be first in the list no matter of the order in
|
||||
// which the devices were added.
|
||||
assert_eq!(
|
||||
block_dev_iter.next().unwrap().config.drive_id,
|
||||
root_block_device.drive_id
|
||||
);
|
||||
assert_eq!(
|
||||
block_dev_iter.next().unwrap().config.drive_id,
|
||||
dummy_block_device_2.drive_id
|
||||
);
|
||||
assert_eq!(
|
||||
block_dev_iter.next().unwrap().config.drive_id,
|
||||
dummy_block_device_3.drive_id
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_device_update() {
|
||||
skip_if_not_root!();
|
||||
let dummy_file_1 = TempFile::new().unwrap();
|
||||
let dummy_path_1 = dummy_file_1.as_path().to_owned();
|
||||
let root_block_device = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_1.clone(),
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let dummy_file_2 = TempFile::new().unwrap();
|
||||
let dummy_path_2 = dummy_file_2.as_path().to_owned();
|
||||
let mut dummy_block_device_2 = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_2.clone(),
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
|
||||
let mut vm = crate::vm::tests::create_vm_instance();
|
||||
|
||||
// Add 2 block devices.
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device).unwrap();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone())
|
||||
.unwrap();
|
||||
|
||||
// Get index zero.
|
||||
assert_eq!(
|
||||
vm.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_id(&String::from("1"))
|
||||
.unwrap(),
|
||||
0
|
||||
);
|
||||
|
||||
// Get None.
|
||||
assert!(vm
|
||||
.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_id(&String::from("foo"))
|
||||
.is_none());
|
||||
|
||||
// Test several update cases using dummy_block_device_2.
|
||||
// Validate `dummy_block_device_2` is already in the list
|
||||
assert!(vm
|
||||
.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_id(&dummy_block_device_2.drive_id)
|
||||
.is_some());
|
||||
// Update OK.
|
||||
dummy_block_device_2.is_read_only = true;
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone())
|
||||
.unwrap();
|
||||
|
||||
let index = vm
|
||||
.device_manager()
|
||||
.block_manager
|
||||
.get_index_of_drive_id(&dummy_block_device_2.drive_id)
|
||||
.unwrap();
|
||||
// Validate update was successful.
|
||||
assert!(
|
||||
vm.device_manager().block_manager.info_list[index]
|
||||
.config
|
||||
.is_read_only
|
||||
);
|
||||
|
||||
// Update with invalid path.
|
||||
let dummy_filename_3 = String::from("test_update_3");
|
||||
let dummy_path_3 = PathBuf::from(dummy_filename_3);
|
||||
dummy_block_device_2.path_on_host = dummy_path_3;
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
assert!(BlockDeviceMgr::insert_device(
|
||||
vm.device_manager_mut(),
|
||||
ctx,
|
||||
dummy_block_device_2.clone(),
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Update with 2 root block devices.
|
||||
dummy_block_device_2.path_on_host = dummy_path_2.clone();
|
||||
dummy_block_device_2.is_root_device = true;
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
assert!(
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2,)
|
||||
.is_err(),
|
||||
);
|
||||
|
||||
// Switch roots and add a PARTUUID for the new one.
|
||||
let root_block_device_old = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_1,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: false,
|
||||
part_uuid: None,
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("1"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
let root_block_device_new = BlockDeviceConfigInfo {
|
||||
path_on_host: dummy_path_2,
|
||||
device_type: BlockDeviceType::RawBlock,
|
||||
is_root_device: true,
|
||||
part_uuid: Some("0eaa91a0-01".to_string()),
|
||||
is_read_only: false,
|
||||
is_direct: false,
|
||||
no_drop: false,
|
||||
drive_id: String::from("2"),
|
||||
rate_limiter: None,
|
||||
num_queues: BlockDeviceConfigInfo::default_num_queues(),
|
||||
queue_size: 128,
|
||||
use_shared_irq: None,
|
||||
use_generic_irq: None,
|
||||
};
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_old).unwrap();
|
||||
let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
|
||||
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_new).unwrap();
|
||||
assert!(vm.device_manager().block_manager.has_part_uuid_root);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,17 +147,13 @@ pub type Result<T> = ::std::result::Result<T, DeviceMgrError>;
|
||||
/// Type of the dragonball virtio devices.
|
||||
#[cfg(feature = "dbs-virtio-devices")]
|
||||
pub type DbsVirtioDevice = Box<
|
||||
dyn VirtioDevice<
|
||||
GuestAddressSpaceImpl,
|
||||
virtio_queue::QueueStateSync,
|
||||
vm_memory::GuestRegionMmap,
|
||||
>,
|
||||
dyn VirtioDevice<GuestAddressSpaceImpl, virtio_queue::QueueSync, vm_memory::GuestRegionMmap>,
|
||||
>;
|
||||
|
||||
/// Type of the dragonball virtio mmio devices.
|
||||
#[cfg(feature = "dbs-virtio-devices")]
|
||||
pub type DbsMmioV2Device =
|
||||
MmioV2Device<GuestAddressSpaceImpl, virtio_queue::QueueStateSync, vm_memory::GuestRegionMmap>;
|
||||
MmioV2Device<GuestAddressSpaceImpl, virtio_queue::QueueSync, vm_memory::GuestRegionMmap>;
|
||||
|
||||
/// Struct to support transactional operations for device management.
|
||||
pub struct DeviceManagerTx {
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
//! Error codes for the virtual machine monitor subsystem.
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use dbs_arch::pmu::PmuError;
|
||||
#[cfg(feature = "dbs-virtio-devices")]
|
||||
use dbs_virtio_devices::Error as VirtIoError;
|
||||
|
||||
@@ -61,6 +63,11 @@ pub enum Error {
|
||||
#[error("failed to write MP table to guest memory: {0}")]
|
||||
MpTableSetup(#[source] dbs_boot::mptable::Error),
|
||||
|
||||
/// Create pmu device error
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[error("Create pmu device error: {0}")]
|
||||
PmuDeviceError(#[source] PmuError),
|
||||
|
||||
/// Fail to boot system
|
||||
#[error("failed to boot system: {0}")]
|
||||
BootSystem(#[source] dbs_boot::Error),
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::sync::mpsc::{channel, Sender};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::IoManagerCached;
|
||||
use dbs_arch::regs;
|
||||
use dbs_arch::{regs, VpmuFeatureLevel};
|
||||
use dbs_boot::get_fdt_addr;
|
||||
use dbs_utils::time::TimestampUs;
|
||||
use kvm_ioctls::{VcpuFd, VmFd};
|
||||
@@ -81,7 +81,7 @@ impl Vcpu {
|
||||
/// * `_pgtable_addr` - pgtable address for ap vcpu (not used in aarch64)
|
||||
pub fn configure(
|
||||
&mut self,
|
||||
_vcpu_config: &VcpuConfig,
|
||||
vcpu_config: &VcpuConfig,
|
||||
vm_fd: &VmFd,
|
||||
vm_as: &GuestAddressSpaceImpl,
|
||||
kernel_load_addr: Option<GuestAddress>,
|
||||
@@ -99,6 +99,9 @@ impl Vcpu {
|
||||
if self.id > 0 {
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
|
||||
}
|
||||
if vcpu_config.vpmu_feature == VpmuFeatureLevel::FullyEnabled {
|
||||
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PMU_V3;
|
||||
}
|
||||
|
||||
self.fd.vcpu_init(&kvi).map_err(VcpuError::VcpuArmInit)?;
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ mod sm;
|
||||
mod vcpu_impl;
|
||||
mod vcpu_manager;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use dbs_arch::cpuid::VpmuFeatureLevel;
|
||||
|
||||
use dbs_arch::VpmuFeatureLevel;
|
||||
pub use vcpu_manager::{VcpuManager, VcpuManagerError, VcpuResizeInfo};
|
||||
|
||||
#[cfg(feature = "hotplug")]
|
||||
@@ -32,6 +30,6 @@ pub struct VcpuConfig {
|
||||
/// if vpmu feature is Disabled, it means vpmu feature is off (by default)
|
||||
/// if vpmu feature is LimitedlyEnabled, it means minimal vpmu counters are supported (cycles and instructions)
|
||||
/// if vpmu feature is FullyEnabled, it means all vpmu counters are supported
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
/// For aarch64, VpmuFeatureLevel only supports Disabled and FullyEnabled.
|
||||
pub vpmu_feature: VpmuFeatureLevel,
|
||||
}
|
||||
|
||||
@@ -441,75 +441,77 @@ impl Vcpu {
|
||||
/// Returns error or enum specifying whether emulation was handled or interrupted.
|
||||
fn run_emulation(&mut self) -> Result<VcpuEmulation> {
|
||||
match Vcpu::emulate(&self.fd) {
|
||||
Ok(run) => match run {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
VcpuExit::IoIn(addr, data) => {
|
||||
let _ = self.io_mgr.pio_read(addr, data);
|
||||
METRICS.vcpu.exit_io_in.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
VcpuExit::IoOut(addr, data) => {
|
||||
if !self.check_io_port_info(addr, data)? {
|
||||
let _ = self.io_mgr.pio_write(addr, data);
|
||||
Ok(run) => {
|
||||
match run {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
VcpuExit::IoIn(addr, data) => {
|
||||
let _ = self.io_mgr.pio_read(addr, data);
|
||||
METRICS.vcpu.exit_io_in.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
METRICS.vcpu.exit_io_out.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
VcpuExit::MmioRead(addr, data) => {
|
||||
let _ = self.io_mgr.mmio_read(addr, data);
|
||||
METRICS.vcpu.exit_mmio_read.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
VcpuExit::MmioWrite(addr, data) => {
|
||||
let _ = self.io_mgr.mmio_write(addr, data);
|
||||
METRICS.vcpu.exit_mmio_write.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
VcpuExit::Hlt => {
|
||||
info!("Received KVM_EXIT_HLT signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::Shutdown => {
|
||||
info!("Received KVM_EXIT_SHUTDOWN signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
// Documentation specifies that below kvm exits are considered errors.
|
||||
VcpuExit::FailEntry => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!("Received KVM_EXIT_FAIL_ENTRY signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::InternalError => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!("Received KVM_EXIT_INTERNAL_ERROR signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::SystemEvent(event_type, event_flags) => match event_type {
|
||||
KVM_SYSTEM_EVENT_RESET | KVM_SYSTEM_EVENT_SHUTDOWN => {
|
||||
info!(
|
||||
"Received KVM_SYSTEM_EVENT: type: {}, event: {}",
|
||||
event_type, event_flags
|
||||
);
|
||||
Ok(VcpuEmulation::Stopped)
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
VcpuExit::IoOut(addr, data) => {
|
||||
if !self.check_io_port_info(addr, data)? {
|
||||
let _ = self.io_mgr.pio_write(addr, data);
|
||||
}
|
||||
METRICS.vcpu.exit_io_out.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
_ => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!(
|
||||
"Received KVM_SYSTEM_EVENT signal type: {}, flag: {}",
|
||||
event_type, event_flags
|
||||
);
|
||||
VcpuExit::MmioRead(addr, data) => {
|
||||
let _ = self.io_mgr.mmio_read(addr, data);
|
||||
METRICS.vcpu.exit_mmio_read.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
VcpuExit::MmioWrite(addr, data) => {
|
||||
let _ = self.io_mgr.mmio_write(addr, data);
|
||||
METRICS.vcpu.exit_mmio_write.inc();
|
||||
Ok(VcpuEmulation::Handled)
|
||||
}
|
||||
VcpuExit::Hlt => {
|
||||
info!("Received KVM_EXIT_HLT signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::Shutdown => {
|
||||
info!("Received KVM_EXIT_SHUTDOWN signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
// Documentation specifies that below kvm exits are considered errors.
|
||||
VcpuExit::FailEntry(reason, cpu) => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!("Received KVM_EXIT_FAIL_ENTRY signal, reason {reason}, cpu number {cpu}");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::InternalError => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!("Received KVM_EXIT_INTERNAL_ERROR signal");
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
VcpuExit::SystemEvent(event_type, event_flags) => match event_type {
|
||||
KVM_SYSTEM_EVENT_RESET | KVM_SYSTEM_EVENT_SHUTDOWN => {
|
||||
info!(
|
||||
"Received KVM_SYSTEM_EVENT: type: {}, event: {}",
|
||||
event_type, event_flags
|
||||
);
|
||||
Ok(VcpuEmulation::Stopped)
|
||||
}
|
||||
_ => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
error!(
|
||||
"Received KVM_SYSTEM_EVENT signal type: {}, flag: {}",
|
||||
event_type, event_flags
|
||||
);
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
},
|
||||
r => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
// TODO: Are we sure we want to finish running a vcpu upon
|
||||
// receiving a vm exit that is not necessarily an error?
|
||||
error!("Unexpected exit reason on vcpu run: {:?}", r);
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
},
|
||||
r => {
|
||||
METRICS.vcpu.failures.inc();
|
||||
// TODO: Are we sure we want to finish running a vcpu upon
|
||||
// receiving a vm exit that is not necessarily an error?
|
||||
error!("Unexpected exit reason on vcpu run: {:?}", r);
|
||||
Err(VcpuError::VcpuUnhandledKvmExit)
|
||||
}
|
||||
},
|
||||
}
|
||||
// The unwrap on raw_os_error can only fail if we have a logic
|
||||
// error in our code in which case it is better to panic.
|
||||
Err(ref e) => {
|
||||
@@ -758,6 +760,11 @@ impl Vcpu {
|
||||
// State machine reached its end.
|
||||
StateMachine::finish(Self::exited)
|
||||
}
|
||||
|
||||
/// Get vcpu file descriptor.
|
||||
pub fn vcpu_fd(&self) -> &VcpuFd {
|
||||
self.fd.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Vcpu {
|
||||
@@ -786,7 +793,7 @@ pub mod tests {
|
||||
MmioWrite,
|
||||
Hlt,
|
||||
Shutdown,
|
||||
FailEntry,
|
||||
FailEntry(u64, u32),
|
||||
InternalError,
|
||||
Unknown,
|
||||
SystemEvent(u32, u64),
|
||||
@@ -807,7 +814,9 @@ pub mod tests {
|
||||
EmulationCase::MmioWrite => Ok(VcpuExit::MmioWrite(0, &[])),
|
||||
EmulationCase::Hlt => Ok(VcpuExit::Hlt),
|
||||
EmulationCase::Shutdown => Ok(VcpuExit::Shutdown),
|
||||
EmulationCase::FailEntry => Ok(VcpuExit::FailEntry),
|
||||
EmulationCase::FailEntry(error_type, cpu_num) => {
|
||||
Ok(VcpuExit::FailEntry(*error_type, *cpu_num))
|
||||
}
|
||||
EmulationCase::InternalError => Ok(VcpuExit::InternalError),
|
||||
EmulationCase::Unknown => Ok(VcpuExit::Unknown),
|
||||
EmulationCase::SystemEvent(event_type, event_flags) => {
|
||||
@@ -850,6 +859,8 @@ pub mod tests {
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn create_vcpu() -> (Vcpu, Receiver<VcpuStateEvent>) {
|
||||
use kvm_ioctls::Kvm;
|
||||
use std::os::fd::AsRawFd;
|
||||
// Call for kvm too frequently would cause error in some host kernel.
|
||||
std::thread::sleep(std::time::Duration::from_millis(5));
|
||||
|
||||
@@ -918,7 +929,7 @@ pub mod tests {
|
||||
assert!(matches!(res, Err(VcpuError::VcpuUnhandledKvmExit)));
|
||||
|
||||
// KVM_EXIT_FAIL_ENTRY signal
|
||||
*(EMULATE_RES.lock().unwrap()) = EmulationCase::FailEntry;
|
||||
*(EMULATE_RES.lock().unwrap()) = EmulationCase::FailEntry(0, 0);
|
||||
let res = vcpu.run_emulation();
|
||||
assert!(matches!(res, Err(VcpuError::VcpuUnhandledKvmExit)));
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ use std::sync::mpsc::{channel, Receiver, RecvError, RecvTimeoutError, Sender};
|
||||
use std::sync::{Arc, Barrier, Mutex, RwLock};
|
||||
use std::time::Duration;
|
||||
|
||||
use dbs_arch::VpmuFeatureLevel;
|
||||
#[cfg(all(feature = "hotplug", feature = "dbs-upcall"))]
|
||||
use dbs_upcall::{DevMgrService, UpcallClient};
|
||||
use dbs_utils::epoll_manager::{EpollManager, EventOps, EventSet, Events, MutEventSubscriber};
|
||||
@@ -281,11 +282,20 @@ impl VcpuManager {
|
||||
let supported_cpuid = kvm_context
|
||||
.supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES)
|
||||
.map_err(VcpuManagerError::Kvm)?;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
|
||||
let vpmu_feature_level = match vm_config_info.vpmu_feature {
|
||||
1 => dbs_arch::cpuid::VpmuFeatureLevel::LimitedlyEnabled,
|
||||
2 => dbs_arch::cpuid::VpmuFeatureLevel::FullyEnabled,
|
||||
_ => dbs_arch::cpuid::VpmuFeatureLevel::Disabled,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
1 => VpmuFeatureLevel::LimitedlyEnabled,
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
1 => {
|
||||
log::warn!(
|
||||
"Limitedly enabled vpmu feature isn't supported on aarch64 for now.\
|
||||
This will be supported in the future. The vpmu_feature will be set disabled!"
|
||||
);
|
||||
VpmuFeatureLevel::Disabled
|
||||
}
|
||||
2 => VpmuFeatureLevel::FullyEnabled,
|
||||
_ => VpmuFeatureLevel::Disabled,
|
||||
};
|
||||
|
||||
let vcpu_manager = Arc::new(Mutex::new(VcpuManager {
|
||||
@@ -297,7 +307,6 @@ impl VcpuManager {
|
||||
cores_per_die: vm_config_info.cpu_topology.cores_per_die,
|
||||
dies_per_socket: vm_config_info.cpu_topology.dies_per_socket,
|
||||
sockets: vm_config_info.cpu_topology.sockets,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
vpmu_feature: vpmu_feature_level,
|
||||
},
|
||||
vcpu_seccomp_filter,
|
||||
@@ -799,6 +808,11 @@ impl VcpuManager {
|
||||
)
|
||||
.map_err(VcpuManagerError::Vcpu)
|
||||
}
|
||||
|
||||
/// get vpmu_feature config
|
||||
pub fn vpmu_feature(&self) -> VpmuFeatureLevel {
|
||||
self.vcpu_config.vpmu_feature
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "hotplug")]
|
||||
@@ -887,7 +901,9 @@ mod hotplug {
|
||||
cpu_ids_array[..cpu_ids.len()].copy_from_slice(&cpu_ids[..cpu_ids.len()]);
|
||||
let req = DevMgrRequest::AddVcpu(CpuDevRequest {
|
||||
count: cpu_ids.len() as u8,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
apic_ids: cpu_ids_array,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
apic_ver: APIC_VERSION,
|
||||
});
|
||||
self.send_upcall_action(upcall_client, req)?;
|
||||
@@ -924,7 +940,9 @@ mod hotplug {
|
||||
cpu_ids_array[..cpu_ids.len()].copy_from_slice(&cpu_ids[..cpu_ids.len()]);
|
||||
let req = DevMgrRequest::DelVcpu(CpuDevRequest {
|
||||
count: cpu_num_to_be_del as u8,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
apic_ids: cpu_ids_array,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
apic_ver: APIC_VERSION,
|
||||
});
|
||||
self.send_upcall_action(upcall_client, req)?;
|
||||
@@ -969,7 +987,10 @@ mod hotplug {
|
||||
vcpu_state_sender
|
||||
.send(VcpuStateEvent::Hotplug((
|
||||
result,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
resp.info.apic_id_index,
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
resp.info.cpu_id,
|
||||
)))
|
||||
.unwrap();
|
||||
vcpu_state_event.write(1).unwrap();
|
||||
|
||||
@@ -11,7 +11,8 @@ use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
|
||||
use dbs_arch::gic::GICDevice;
|
||||
use dbs_arch::{DeviceInfoForFDT, DeviceType};
|
||||
use dbs_arch::pmu::initialize_pmu;
|
||||
use dbs_arch::{DeviceInfoForFDT, DeviceType, VpmuFeatureLevel};
|
||||
use dbs_boot::InitrdConfig;
|
||||
use dbs_utils::epoll_manager::EpollManager;
|
||||
use dbs_utils::time::TimestampUs;
|
||||
@@ -43,6 +44,7 @@ fn configure_system<T: DeviceInfoForFDT + Clone + Debug, M: GuestMemory>(
|
||||
device_info: Option<&HashMap<(DeviceType, String), T>>,
|
||||
gic_device: &Box<dyn GICDevice>,
|
||||
initrd: &Option<super::InitrdConfig>,
|
||||
vpmu_feature: &VpmuFeatureLevel,
|
||||
) -> super::Result<()> {
|
||||
dbs_boot::fdt::create_fdt(
|
||||
guest_mem,
|
||||
@@ -51,6 +53,7 @@ fn configure_system<T: DeviceInfoForFDT + Clone + Debug, M: GuestMemory>(
|
||||
device_info,
|
||||
gic_device,
|
||||
initrd,
|
||||
vpmu_feature,
|
||||
)
|
||||
.map_err(Error::BootSystem)?;
|
||||
Ok(())
|
||||
@@ -76,6 +79,23 @@ impl Vm {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Setup pmu devices for guest vm.
|
||||
pub fn setup_pmu_devices(&mut self) -> std::result::Result<(), StartMicroVmError> {
|
||||
let vm = self.vm_fd();
|
||||
let mut vcpu_manager = self.vcpu_manager().map_err(StartMicroVmError::Vcpu)?;
|
||||
let vpmu_feature = vcpu_manager.vpmu_feature();
|
||||
if vpmu_feature == VpmuFeatureLevel::Disabled {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for vcpu in vcpu_manager.vcpus_mut() {
|
||||
initialize_pmu(vm, vcpu.vcpu_fd())
|
||||
.map_err(|e| StartMicroVmError::ConfigureVm(VmError::SetupPmu(e)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialize the virtual machine instance.
|
||||
///
|
||||
/// It initialize the virtual machine instance by:
|
||||
@@ -113,6 +133,7 @@ impl Vm {
|
||||
.create_boot_vcpus(request_ts, kernel_loader_result.kernel_load)
|
||||
.map_err(StartMicroVmError::Vcpu)?;
|
||||
self.setup_interrupt_controller()?;
|
||||
self.setup_pmu_devices()?;
|
||||
self.init_devices(epoll_mgr)?;
|
||||
|
||||
Ok(())
|
||||
@@ -129,6 +150,7 @@ impl Vm {
|
||||
initrd: Option<InitrdConfig>,
|
||||
) -> std::result::Result<(), StartMicroVmError> {
|
||||
let vcpu_manager = self.vcpu_manager().map_err(StartMicroVmError::Vcpu)?;
|
||||
let vpmu_feature = vcpu_manager.vpmu_feature();
|
||||
let vcpu_mpidr = vcpu_manager
|
||||
.vcpus()
|
||||
.into_iter()
|
||||
@@ -143,6 +165,7 @@ impl Vm {
|
||||
self.device_manager.get_mmio_device_info(),
|
||||
self.get_irqchip(),
|
||||
&initrd,
|
||||
&vpmu_feature,
|
||||
)
|
||||
.map_err(StartMicroVmError::ConfigureSystem)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ use std::sync::{Arc, Mutex, RwLock};
|
||||
use dbs_address_space::AddressSpace;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use dbs_arch::gic::GICDevice;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use dbs_arch::pmu::PmuError;
|
||||
use dbs_boot::InitrdConfig;
|
||||
use dbs_utils::epoll_manager::EpollManager;
|
||||
use dbs_utils::time::TimestampUs;
|
||||
@@ -69,6 +71,11 @@ pub enum VmError {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[error("failed to configure GIC")]
|
||||
SetupGIC(GICError),
|
||||
|
||||
/// Cannot setup pmu device
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[error("failed to setup pmu device")]
|
||||
SetupPmu(#[source] PmuError),
|
||||
}
|
||||
|
||||
/// Configuration information for user defined NUMA nodes.
|
||||
@@ -1005,6 +1012,7 @@ pub mod tests {
|
||||
assert!(vm.remove_devices().is_ok());
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[test]
|
||||
fn test_run_code() {
|
||||
skip_if_not_root!();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// found in the THIRD-PARTY file.
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
|
||||
use dbs_address_space::AddressSpace;
|
||||
@@ -16,8 +15,9 @@ use dbs_utils::epoll_manager::EpollManager;
|
||||
use dbs_utils::time::TimestampUs;
|
||||
use kvm_bindings::{kvm_irqchip, kvm_pit_config, kvm_pit_state2, KVM_PIT_SPEAKER_DUMMY};
|
||||
use linux_loader::cmdline::Cmdline;
|
||||
use linux_loader::configurator::{linux::LinuxBootConfigurator, BootConfigurator, BootParams};
|
||||
use slog::info;
|
||||
use vm_memory::{Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory};
|
||||
use vm_memory::{Address, GuestAddress, GuestAddressSpace, GuestMemory};
|
||||
|
||||
use crate::address_space_manager::{GuestAddressSpaceImpl, GuestMemoryImpl};
|
||||
use crate::error::{Error, Result, StartMicroVmError};
|
||||
@@ -110,15 +110,11 @@ fn configure_system<M: GuestMemory>(
|
||||
}
|
||||
}
|
||||
|
||||
let zero_page_addr = GuestAddress(layout::ZERO_PAGE_START);
|
||||
guest_mem
|
||||
.checked_offset(zero_page_addr, mem::size_of::<bootparam::boot_params>())
|
||||
.ok_or(Error::ZeroPagePastRamEnd)?;
|
||||
guest_mem
|
||||
.write_obj(params, zero_page_addr)
|
||||
.map_err(|_| Error::ZeroPageSetup)?;
|
||||
|
||||
Ok(())
|
||||
LinuxBootConfigurator::write_bootparams(
|
||||
&BootParams::new(¶ms, GuestAddress(layout::ZERO_PAGE_START)),
|
||||
guest_mem,
|
||||
)
|
||||
.map_err(|_| Error::ZeroPageSetup)
|
||||
}
|
||||
|
||||
impl Vm {
|
||||
|
||||
85
src/libs/Cargo.lock
generated
85
src/libs/Cargo.lock
generated
@@ -703,9 +703,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.9.0"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
@@ -845,9 +845,16 @@ name = "protobuf"
|
||||
version = "2.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96"
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"once_cell",
|
||||
"protobuf-support",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -856,17 +863,47 @@ version = "2.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aec1632b7c8f2e620343439a7dfd1f3c47b18906c4be58982079911482b5d707"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf 2.27.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-codegen-pure"
|
||||
version = "2.27.1"
|
||||
name = "protobuf-codegen"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f8122fdb18e55190c796b088a16bdb70cd7acdcd48f7a8b796b58c62e532cc6"
|
||||
checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"anyhow",
|
||||
"once_cell",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-parse",
|
||||
"regex",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-parse"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"log",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-support",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-support"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -875,7 +912,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"oci",
|
||||
"protobuf",
|
||||
"protobuf 3.2.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ttrpc",
|
||||
@@ -1314,9 +1351,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc"
|
||||
version = "0.6.1"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ecfff459a859c6ba6668ff72b34c2f1d94d9d58f7088414c2674ad0f31cc7d8"
|
||||
checksum = "a35f22a2964bea14afee161665bb260b83cb48e665e0260ca06ec0e775c8b06c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"byteorder",
|
||||
@@ -1324,8 +1361,8 @@ dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.23.1",
|
||||
"protobuf",
|
||||
"protobuf-codegen-pure",
|
||||
"protobuf 3.2.0",
|
||||
"protobuf-codegen 3.2.0",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-vsock",
|
||||
@@ -1333,28 +1370,28 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc-codegen"
|
||||
version = "0.2.0"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809eda4e459820237104e4b61d6b41bbe6c9e1ce6adf4057955e6e6722a90408"
|
||||
checksum = "94d7f7631d7a9ebed715a47cd4cb6072cbc7ae1d4ec01598971bbec0024340c2"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"protobuf-codegen-pure",
|
||||
"protobuf 2.27.1",
|
||||
"protobuf-codegen 3.2.0",
|
||||
"protobuf-support",
|
||||
"ttrpc-compiler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttrpc-compiler"
|
||||
version = "0.4.1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2978ed3fa047d8fd55cbeb4d4a61d461fb3021a90c9618519c73ce7e5bb66c15"
|
||||
checksum = "ec3cb5dbf1f0865a34fe3f722290fe776cacb16f50428610b779467b76ddf647"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"protobuf 2.27.1",
|
||||
"protobuf-codegen 2.27.1",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
|
||||
@@ -308,6 +308,14 @@ pub const KATA_ANNO_CFG_DISABLE_NEW_NETNS: &str =
|
||||
/// A sandbox annotation to specify how attached VFIO devices should be treated.
|
||||
pub const KATA_ANNO_CFG_VFIO_MODE: &str = "io.katacontainers.config.runtime.vfio_mode";
|
||||
|
||||
/// A sandbox annotation used to specify prefetch_files.list host path container image
|
||||
/// being used,
|
||||
/// and runtime will pass it to Hypervisor to search for corresponding prefetch list file.
|
||||
/// "io.katacontainers.config.hypervisor.prefetch_files.list"
|
||||
/// = "/path/to/<uid>/xyz.com/fedora:36/prefetch_file.list"
|
||||
pub const KATA_ANNO_CFG_HYPERVISOR_PREFETCH_FILES_LIST: &str =
|
||||
"io.katacontainers.config.hypervisor.prefetch_files.list";
|
||||
|
||||
/// A helper structure to query configuration information by check annotations.
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct Annotation {
|
||||
@@ -409,10 +417,10 @@ impl Annotation {
|
||||
match self.get_value::<u32>(KATA_ANNO_CONTAINER_RES_SWAPPINESS) {
|
||||
Ok(r) => {
|
||||
if r.unwrap_or_default() > 100 {
|
||||
return Err(io::Error::new(
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("{} greater than 100", r.unwrap_or_default()),
|
||||
));
|
||||
))
|
||||
} else {
|
||||
Ok(r)
|
||||
}
|
||||
@@ -673,6 +681,9 @@ impl Annotation {
|
||||
hv.machine_info.validate_entropy_source(value)?;
|
||||
hv.machine_info.entropy_source = value.to_string();
|
||||
}
|
||||
KATA_ANNO_CFG_HYPERVISOR_PREFETCH_FILES_LIST => {
|
||||
hv.prefetch_list_path = value.to_string();
|
||||
}
|
||||
// Hypervisor Memory related annotations
|
||||
KATA_ANNO_CFG_HYPERVISOR_DEFAULT_MEMORY => {
|
||||
match byte_unit::Byte::from_str(value) {
|
||||
|
||||
@@ -9,14 +9,16 @@ use crate::config::{ConfigOps, TomlConfig};
|
||||
|
||||
pub use vendor::AgentVendor;
|
||||
|
||||
use super::default::{DEFAULT_AGENT_LOG_PORT, DEFAULT_AGENT_VSOCK_PORT};
|
||||
use super::default::{
|
||||
DEFAULT_AGENT_DIAL_TIMEOUT_MS, DEFAULT_AGENT_LOG_PORT, DEFAULT_AGENT_VSOCK_PORT,
|
||||
};
|
||||
use crate::eother;
|
||||
|
||||
/// agent name of Kata agent.
|
||||
pub const AGENT_NAME_KATA: &str = "kata";
|
||||
|
||||
/// Kata agent configuration information.
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Agent {
|
||||
/// If enabled, the agent will log additional debug messages to the system log.
|
||||
#[serde(default, rename = "enable_debug")]
|
||||
@@ -78,9 +80,28 @@ pub struct Agent {
|
||||
pub kernel_modules: Vec<String>,
|
||||
|
||||
/// container pipe size
|
||||
#[serde(default)]
|
||||
pub container_pipe_size: u32,
|
||||
}
|
||||
|
||||
impl std::default::Default for Agent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
debug: true,
|
||||
enable_tracing: false,
|
||||
debug_console_enabled: false,
|
||||
server_port: DEFAULT_AGENT_VSOCK_PORT,
|
||||
log_port: DEFAULT_AGENT_LOG_PORT,
|
||||
dial_timeout_ms: DEFAULT_AGENT_DIAL_TIMEOUT_MS,
|
||||
reconnect_timeout_ms: 3_000,
|
||||
request_timeout_ms: 30_000,
|
||||
health_check_request_timeout_ms: 90_000,
|
||||
kernel_modules: Default::default(),
|
||||
container_pipe_size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_server_port() -> u32 {
|
||||
DEFAULT_AGENT_VSOCK_PORT
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ lazy_static! {
|
||||
pub static ref DEFAULT_RUNTIME_CONFIGURATIONS: Vec::<&'static str> = vec![
|
||||
"/etc/kata-containers/configuration.toml",
|
||||
"/usr/share/defaults/kata-containers/configuration.toml",
|
||||
"/opt/kata/share/defaults/kata-containers/configuration.toml",
|
||||
];
|
||||
}
|
||||
|
||||
@@ -24,6 +25,7 @@ pub const DEFAULT_AGENT_VSOCK_PORT: u32 = 1024;
|
||||
pub const DEFAULT_AGENT_LOG_PORT: u32 = 1025;
|
||||
pub const DEFAULT_AGENT_DBG_CONSOLE_PORT: u32 = 1026;
|
||||
pub const DEFAULT_AGENT_TYPE_NAME: &str = AGENT_NAME_KATA;
|
||||
pub const DEFAULT_AGENT_DIAL_TIMEOUT_MS: u32 = 10;
|
||||
|
||||
pub const DEFAULT_RUNTIME_NAME: &str = RUNTIME_NAME_VIRTCONTAINER;
|
||||
pub const DEFAULT_HYPERVISOR: &str = HYPERVISOR_NAME_DRAGONBALL;
|
||||
@@ -42,6 +44,7 @@ pub const MIN_SHARED_9PFS_SIZE_MB: u32 = 4 * 1024;
|
||||
pub const MAX_SHARED_9PFS_SIZE_MB: u32 = 8 * 1024 * 1024;
|
||||
|
||||
pub const DEFAULT_GUEST_HOOK_PATH: &str = "/opt/kata/hooks";
|
||||
pub const DEFAULT_GUEST_DNS_FILE: &str = "/etc/resolv.conf";
|
||||
|
||||
pub const DEFAULT_GUEST_VCPUS: u32 = 1;
|
||||
|
||||
@@ -67,3 +70,18 @@ pub const DEFAULT_QEMU_PCI_BRIDGES: u32 = 2;
|
||||
pub const MAX_QEMU_PCI_BRIDGES: u32 = 5;
|
||||
pub const MAX_QEMU_VCPUS: u32 = 256;
|
||||
pub const MIN_QEMU_MEMORY_SIZE_MB: u32 = 64;
|
||||
|
||||
// Default configuration for Cloud Hypervisor (CH)
|
||||
pub const DEFAULT_CH_BINARY_PATH: &str = "/usr/bin/cloud-hypervisor";
|
||||
pub const DEFAULT_CH_ROOTFS_TYPE: &str = "ext4";
|
||||
pub const DEFAULT_CH_CONTROL_PATH: &str = "";
|
||||
pub const DEFAULT_CH_ENTROPY_SOURCE: &str = "/dev/urandom";
|
||||
pub const DEFAULT_CH_GUEST_KERNEL_IMAGE: &str = "vmlinuz";
|
||||
pub const DEFAULT_CH_GUEST_KERNEL_PARAMS: &str = "";
|
||||
pub const DEFAULT_CH_FIRMWARE_PATH: &str = "";
|
||||
pub const DEFAULT_CH_MEMORY_SIZE_MB: u32 = 128;
|
||||
pub const DEFAULT_CH_MEMORY_SLOTS: u32 = 128;
|
||||
pub const DEFAULT_CH_PCI_BRIDGES: u32 = 2;
|
||||
pub const MAX_CH_PCI_BRIDGES: u32 = 5;
|
||||
pub const MAX_CH_VCPUS: u32 = 256;
|
||||
pub const MIN_CH_MEMORY_SIZE_MB: u32 = 64;
|
||||
|
||||
146
src/libs/kata-types/src/config/hypervisor/ch.rs
Normal file
146
src/libs/kata-types/src/config/hypervisor/ch.rs
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright (c) 2019-2021 Alibaba Cloud
|
||||
// Copyright (c) 2022-2023 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::io::Result;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{default, register_hypervisor_plugin};
|
||||
|
||||
use crate::config::default::MAX_CH_VCPUS;
|
||||
use crate::config::default::MIN_CH_MEMORY_SIZE_MB;
|
||||
|
||||
use crate::config::hypervisor::VIRTIO_BLK_MMIO;
|
||||
use crate::config::{ConfigPlugin, TomlConfig};
|
||||
use crate::{eother, resolve_path, validate_path};
|
||||
|
||||
/// Hypervisor name for CH, used to index `TomlConfig::hypervisor`.
|
||||
pub const HYPERVISOR_NAME_CH: &str = "cloud-hypervisor";
|
||||
|
||||
/// Configuration information for CH.
|
||||
#[derive(Default, Debug)]
|
||||
pub struct CloudHypervisorConfig {}
|
||||
|
||||
impl CloudHypervisorConfig {
|
||||
/// Create a new instance of `CloudHypervisorConfig`.
|
||||
pub fn new() -> Self {
|
||||
CloudHypervisorConfig {}
|
||||
}
|
||||
|
||||
/// Register the CH plugin.
|
||||
pub fn register(self) {
|
||||
let plugin = Arc::new(self);
|
||||
register_hypervisor_plugin(HYPERVISOR_NAME_CH, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigPlugin for CloudHypervisorConfig {
|
||||
fn get_max_cpus(&self) -> u32 {
|
||||
MAX_CH_VCPUS
|
||||
}
|
||||
|
||||
fn get_min_memory(&self) -> u32 {
|
||||
MIN_CH_MEMORY_SIZE_MB
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
HYPERVISOR_NAME_CH
|
||||
}
|
||||
|
||||
/// Adjust the configuration information after loading from configuration file.
|
||||
fn adjust_config(&self, conf: &mut TomlConfig) -> Result<()> {
|
||||
if let Some(ch) = conf.hypervisor.get_mut(HYPERVISOR_NAME_CH) {
|
||||
if ch.path.is_empty() {
|
||||
ch.path = default::DEFAULT_CH_BINARY_PATH.to_string();
|
||||
}
|
||||
resolve_path!(ch.path, "CH binary path `{}` is invalid: {}")?;
|
||||
if ch.ctlpath.is_empty() {
|
||||
ch.ctlpath = default::DEFAULT_CH_CONTROL_PATH.to_string();
|
||||
}
|
||||
resolve_path!(ch.ctlpath, "CH ctlpath `{}` is invalid: {}")?;
|
||||
|
||||
if ch.boot_info.kernel.is_empty() {
|
||||
ch.boot_info.kernel = default::DEFAULT_CH_GUEST_KERNEL_IMAGE.to_string();
|
||||
}
|
||||
if ch.boot_info.kernel_params.is_empty() {
|
||||
ch.boot_info.kernel_params = default::DEFAULT_CH_GUEST_KERNEL_PARAMS.to_string();
|
||||
}
|
||||
if ch.boot_info.firmware.is_empty() {
|
||||
ch.boot_info.firmware = default::DEFAULT_CH_FIRMWARE_PATH.to_string();
|
||||
}
|
||||
|
||||
if ch.device_info.default_bridges == 0 {
|
||||
ch.device_info.default_bridges = default::DEFAULT_CH_PCI_BRIDGES;
|
||||
}
|
||||
|
||||
if ch.machine_info.entropy_source.is_empty() {
|
||||
ch.machine_info.entropy_source = default::DEFAULT_CH_ENTROPY_SOURCE.to_string();
|
||||
}
|
||||
|
||||
if ch.memory_info.default_memory == 0 {
|
||||
ch.memory_info.default_memory = default::DEFAULT_CH_MEMORY_SIZE_MB;
|
||||
}
|
||||
if ch.memory_info.memory_slots == 0 {
|
||||
ch.memory_info.memory_slots = default::DEFAULT_CH_MEMORY_SLOTS;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate the configuration information.
|
||||
fn validate(&self, conf: &TomlConfig) -> Result<()> {
|
||||
if let Some(ch) = conf.hypervisor.get(HYPERVISOR_NAME_CH) {
|
||||
validate_path!(ch.path, "CH binary path `{}` is invalid: {}")?;
|
||||
validate_path!(ch.ctlpath, "CH control path `{}` is invalid: {}")?;
|
||||
if !ch.jailer_path.is_empty() {
|
||||
return Err(eother!("Path for CH jailer should be empty"));
|
||||
}
|
||||
if !ch.valid_jailer_paths.is_empty() {
|
||||
return Err(eother!("Valid CH jailer path list should be empty"));
|
||||
}
|
||||
|
||||
if !ch.blockdev_info.disable_block_device_use
|
||||
&& ch.blockdev_info.block_device_driver == VIRTIO_BLK_MMIO
|
||||
{
|
||||
return Err(eother!("CH doesn't support virtio-blk-mmio"));
|
||||
}
|
||||
|
||||
if ch.boot_info.kernel.is_empty() {
|
||||
return Err(eother!("Guest kernel image for CH is empty"));
|
||||
}
|
||||
if ch.boot_info.image.is_empty() && ch.boot_info.initrd.is_empty() {
|
||||
return Err(eother!("Both guest boot image and initrd for CH are empty"));
|
||||
}
|
||||
|
||||
if (ch.cpu_info.default_vcpus > 0
|
||||
&& ch.cpu_info.default_vcpus as u32 > default::MAX_CH_VCPUS)
|
||||
|| ch.cpu_info.default_maxvcpus > default::MAX_CH_VCPUS
|
||||
{
|
||||
return Err(eother!(
|
||||
"CH hypervisor cannot support {} vCPUs",
|
||||
ch.cpu_info.default_maxvcpus
|
||||
));
|
||||
}
|
||||
|
||||
if ch.device_info.default_bridges > default::MAX_CH_PCI_BRIDGES {
|
||||
return Err(eother!(
|
||||
"CH hypervisor cannot support {} PCI bridges",
|
||||
ch.device_info.default_bridges
|
||||
));
|
||||
}
|
||||
|
||||
if ch.memory_info.default_memory < MIN_CH_MEMORY_SIZE_MB {
|
||||
return Err(eother!(
|
||||
"CH hypervisor has minimal memory limitation {}",
|
||||
MIN_CH_MEMORY_SIZE_MB
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,9 @@ pub use self::dragonball::{DragonballConfig, HYPERVISOR_NAME_DRAGONBALL};
|
||||
mod qemu;
|
||||
pub use self::qemu::{QemuConfig, HYPERVISOR_NAME_QEMU};
|
||||
|
||||
mod ch;
|
||||
pub use self::ch::{CloudHypervisorConfig, HYPERVISOR_NAME_CH};
|
||||
|
||||
const VIRTIO_BLK: &str = "virtio-blk";
|
||||
const VIRTIO_BLK_MMIO: &str = "virtio-mmio";
|
||||
const VIRTIO_BLK_CCW: &str = "virtio-blk-ccw";
|
||||
@@ -976,6 +979,13 @@ pub struct Hypervisor {
|
||||
#[serde(default, flatten)]
|
||||
pub shared_fs: SharedFsInfo,
|
||||
|
||||
/// A sandbox annotation used to specify prefetch_files.list host path container image
|
||||
/// being used, and runtime will pass it to Hypervisor to search for corresponding
|
||||
/// prefetch list file:
|
||||
/// prefetch_list_path = /path/to/<uid>/xyz.com/fedora:36/prefetch_file.list
|
||||
#[serde(default)]
|
||||
pub prefetch_list_path: String,
|
||||
|
||||
/// Vendor customized runtime configuration.
|
||||
#[serde(default, flatten)]
|
||||
pub vendor: HypervisorVendor,
|
||||
@@ -1019,6 +1029,10 @@ impl ConfigOps for Hypervisor {
|
||||
hv.network_info.adjust_config()?;
|
||||
hv.security_info.adjust_config()?;
|
||||
hv.shared_fs.adjust_config()?;
|
||||
resolve_path!(
|
||||
hv.prefetch_list_path,
|
||||
"prefetch_list_path `{}` is invalid: {}"
|
||||
)?;
|
||||
} else {
|
||||
return Err(eother!("Can not find plugin for hypervisor {}", hypervisor));
|
||||
}
|
||||
@@ -1053,6 +1067,10 @@ impl ConfigOps for Hypervisor {
|
||||
"Hypervisor control executable `{}` is invalid: {}"
|
||||
)?;
|
||||
validate_path!(hv.jailer_path, "Hypervisor jailer path `{}` is invalid: {}")?;
|
||||
validate_path!(
|
||||
hv.prefetch_list_path,
|
||||
"prefetch_files.list path `{}` is invalid: {}"
|
||||
)?;
|
||||
} else {
|
||||
return Err(eother!("Can not find plugin for hypervisor {}", hypervisor));
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ pub mod hypervisor;
|
||||
pub use self::agent::Agent;
|
||||
use self::default::DEFAULT_AGENT_DBG_CONSOLE_PORT;
|
||||
pub use self::hypervisor::{
|
||||
BootInfo, DragonballConfig, Hypervisor, QemuConfig, HYPERVISOR_NAME_DRAGONBALL,
|
||||
HYPERVISOR_NAME_QEMU,
|
||||
BootInfo, CloudHypervisorConfig, DragonballConfig, Hypervisor, QemuConfig,
|
||||
HYPERVISOR_NAME_DRAGONBALL, HYPERVISOR_NAME_QEMU,
|
||||
};
|
||||
|
||||
mod runtime;
|
||||
@@ -127,6 +127,14 @@ impl TomlConfig {
|
||||
result
|
||||
}
|
||||
|
||||
/// Load raw Kata configuration information from default configuration file.
|
||||
///
|
||||
/// Configuration file is probed according to the default configuration file list
|
||||
/// default::DEFAULT_RUNTIME_CONFIGURATIONS.
|
||||
pub fn load_from_default() -> Result<(TomlConfig, PathBuf)> {
|
||||
Self::load_raw_from_file("")
|
||||
}
|
||||
|
||||
/// Load raw Kata configuration information from configuration files.
|
||||
///
|
||||
/// If `config_file` is valid, it will used, otherwise a built-in default path list will be
|
||||
@@ -196,7 +204,7 @@ impl TomlConfig {
|
||||
}
|
||||
|
||||
/// Probe configuration file according to the default configuration file list.
|
||||
fn get_default_config_file() -> Result<PathBuf> {
|
||||
pub fn get_default_config_file() -> Result<PathBuf> {
|
||||
for f in default::DEFAULT_RUNTIME_CONFIGURATIONS.iter() {
|
||||
if let Ok(path) = fs::canonicalize(f) {
|
||||
return Ok(path);
|
||||
|
||||
@@ -103,8 +103,9 @@ pub struct Runtime {
|
||||
pub enable_pprof: bool,
|
||||
|
||||
/// If enabled, static resource management will calculate the vcpu and memory for the sandbox/container
|
||||
/// And pod configured this will not be able to further update its CPU/Memory resource
|
||||
#[serde(default)]
|
||||
pub static_resource_mgmt: bool,
|
||||
pub static_sandbox_resource_mgmt: bool,
|
||||
|
||||
/// Determines whether container seccomp profiles are passed to the virtual machine and
|
||||
/// applied by the kata agent. If set to true, seccomp is not applied within the guest.
|
||||
@@ -129,6 +130,12 @@ pub struct Runtime {
|
||||
/// Vendor customized runtime configuration.
|
||||
#[serde(default, flatten)]
|
||||
pub vendor: RuntimeVendor,
|
||||
|
||||
/// If keep_abnormal is enabled, it means that 1) if the runtime exits abnormally, the cleanup process
|
||||
/// will be skipped, and 2) the runtime will not exit even if the health check fails.
|
||||
/// This option is typically used to retain abnormal information for debugging.
|
||||
#[serde(default)]
|
||||
pub keep_abnormal: bool,
|
||||
}
|
||||
|
||||
impl ConfigOps for Runtime {
|
||||
|
||||
@@ -192,6 +192,24 @@ pub struct Hook {
|
||||
pub struct Hooks {
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub prestart: Vec<Hook>,
|
||||
#[serde(
|
||||
rename = "createRuntime",
|
||||
default,
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
pub create_runtime: Vec<Hook>,
|
||||
#[serde(
|
||||
rename = "createContainer",
|
||||
default,
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
pub create_container: Vec<Hook>,
|
||||
#[serde(
|
||||
rename = "startContainer",
|
||||
default,
|
||||
skip_serializing_if = "Vec::is_empty"
|
||||
)]
|
||||
pub start_container: Vec<Hook>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub poststart: Vec<Hook>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
@@ -831,6 +849,8 @@ pub struct State {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::vec;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@@ -1021,6 +1041,11 @@ mod tests {
|
||||
"path": "/usr/bin/setup-network"
|
||||
}
|
||||
],
|
||||
"createRuntime": [
|
||||
{
|
||||
"path": "/usr/local/bin/nerdctl"
|
||||
}
|
||||
],
|
||||
"poststart": [
|
||||
{
|
||||
"path": "/usr/bin/notify-start",
|
||||
@@ -1389,6 +1414,12 @@ mod tests {
|
||||
timeout: None,
|
||||
},
|
||||
],
|
||||
create_runtime: vec![crate::Hook {
|
||||
path: "/usr/local/bin/nerdctl".to_string(),
|
||||
args: vec![],
|
||||
env: vec![],
|
||||
timeout: None,
|
||||
}],
|
||||
poststart: vec![crate::Hook {
|
||||
path: "/usr/bin/notify-start".to_string(),
|
||||
args: vec![],
|
||||
@@ -1401,6 +1432,7 @@ mod tests {
|
||||
env: vec![],
|
||||
timeout: None,
|
||||
}],
|
||||
..Default::default()
|
||||
}),
|
||||
annotations: [
|
||||
("com.example.key1".to_string(), "value1".to_string()),
|
||||
|
||||
15
src/libs/protocols/.gitignore
vendored
15
src/libs/protocols/.gitignore
vendored
@@ -1,11 +1,6 @@
|
||||
Cargo.lock
|
||||
src/agent.rs
|
||||
src/agent_ttrpc.rs
|
||||
src/agent_ttrpc_async.rs
|
||||
src/csi.rs
|
||||
src/empty.rs
|
||||
src/health.rs
|
||||
src/health_ttrpc.rs
|
||||
src/health_ttrpc_async.rs
|
||||
src/oci.rs
|
||||
src/types.rs
|
||||
|
||||
src/*.rs
|
||||
!src/lib.rs
|
||||
!src/trans.rs
|
||||
!src/serde_config.rs
|
||||
|
||||
@@ -11,12 +11,13 @@ with-serde = [ "serde", "serde_json" ]
|
||||
async = ["ttrpc/async", "async-trait"]
|
||||
|
||||
[dependencies]
|
||||
ttrpc = { version = "0.6.0" }
|
||||
ttrpc = { version = "0.7.1" }
|
||||
async-trait = { version = "0.1.42", optional = true }
|
||||
protobuf = { version = "2.27.0", features = ["with-serde"] }
|
||||
protobuf = { version = "3.2.0" }
|
||||
serde = { version = "1.0.130", features = ["derive"], optional = true }
|
||||
serde_json = { version = "1.0.68", optional = true }
|
||||
oci = { path = "../oci" }
|
||||
|
||||
[build-dependencies]
|
||||
ttrpc-codegen = "0.2.0"
|
||||
ttrpc-codegen = "0.4.2"
|
||||
protobuf = { version = "3.2.0" }
|
||||
|
||||
@@ -7,7 +7,46 @@ use std::fs::{self, File};
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize};
|
||||
|
||||
use protobuf::{
|
||||
descriptor::field_descriptor_proto::Type,
|
||||
reflect::{EnumDescriptor, FieldDescriptor, MessageDescriptor, OneofDescriptor},
|
||||
};
|
||||
use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize, ProtobufCustomizeCallback};
|
||||
|
||||
struct GenSerde;
|
||||
|
||||
impl ProtobufCustomizeCallback for GenSerde {
|
||||
fn message(&self, _message: &MessageDescriptor) -> ProtobufCustomize {
|
||||
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||
}
|
||||
|
||||
fn enumeration(&self, _enum_type: &EnumDescriptor) -> ProtobufCustomize {
|
||||
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||
}
|
||||
|
||||
fn oneof(&self, _oneof: &OneofDescriptor) -> ProtobufCustomize {
|
||||
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", derive(::serde::Serialize, ::serde::Deserialize))]")
|
||||
}
|
||||
|
||||
fn field(&self, field: &FieldDescriptor) -> ProtobufCustomize {
|
||||
if field.proto().type_() == Type::TYPE_ENUM {
|
||||
ProtobufCustomize::default().before(
|
||||
"#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::serialize_enum_or_unknown\", deserialize_with = \"crate::deserialize_enum_or_unknown\"))]",
|
||||
)
|
||||
} else if field.proto().type_() == Type::TYPE_MESSAGE && field.is_singular() {
|
||||
ProtobufCustomize::default().before(
|
||||
"#[cfg_attr(feature = \"with-serde\", serde(serialize_with = \"crate::serialize_message_field\", deserialize_with = \"crate::deserialize_message_field\"))]",
|
||||
)
|
||||
} else {
|
||||
ProtobufCustomize::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn special_field(&self, _message: &MessageDescriptor, _field: &str) -> ProtobufCustomize {
|
||||
ProtobufCustomize::default().before("#[cfg_attr(feature = \"with-serde\", serde(skip))]")
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std::io::Error> {
|
||||
let mut src = File::open(file_name)?;
|
||||
@@ -103,10 +142,10 @@ fn codegen(path: &str, protos: &[&str], async_all: bool) -> Result<(), std::io::
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let protobuf_options = ProtobufCustomize {
|
||||
serde_derive: Some(true),
|
||||
..Default::default()
|
||||
};
|
||||
let protobuf_options = ProtobufCustomize::default()
|
||||
.gen_mod_rs(false)
|
||||
.generate_getter(true)
|
||||
.generate_accessors(true);
|
||||
|
||||
let out_dir = Path::new("src");
|
||||
|
||||
@@ -117,6 +156,7 @@ fn codegen(path: &str, protos: &[&str], async_all: bool) -> Result<(), std::io::
|
||||
.customize(ttrpc_options)
|
||||
.rust_protobuf()
|
||||
.rust_protobuf_customize(protobuf_options)
|
||||
.rust_protobuf_customize_callback(GenSerde)
|
||||
.run()?;
|
||||
|
||||
let autogen_comment = format!("\n//! Generated by {:?} ({:?})", file!(), module_path!());
|
||||
@@ -147,6 +187,7 @@ fn real_main() -> Result<(), std::io::Error> {
|
||||
"src",
|
||||
&[
|
||||
"protos/google/protobuf/empty.proto",
|
||||
"protos/gogo/protobuf/gogoproto/gogo.proto",
|
||||
"protos/oci.proto",
|
||||
"protos/types.proto",
|
||||
"protos/csi.proto",
|
||||
|
||||
@@ -34,9 +34,11 @@ service AgentService {
|
||||
rpc SignalProcess(SignalProcessRequest) returns (google.protobuf.Empty);
|
||||
rpc WaitProcess(WaitProcessRequest) returns (WaitProcessResponse); // wait & reap like waitpid(2)
|
||||
rpc UpdateContainer(UpdateContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc UpdateEphemeralMounts(UpdateEphemeralMountsRequest) returns (google.protobuf.Empty);
|
||||
rpc StatsContainer(StatsContainerRequest) returns (StatsContainerResponse);
|
||||
rpc PauseContainer(PauseContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc ResumeContainer(ResumeContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc RemoveStaleVirtiofsShareMounts(RemoveStaleVirtiofsShareMountsRequest) returns (google.protobuf.Empty);
|
||||
|
||||
// stdio
|
||||
rpc WriteStdin(WriteStreamRequest) returns (WriteStreamResponse);
|
||||
@@ -300,6 +302,8 @@ message CreateSandboxRequest {
|
||||
message DestroySandboxRequest {
|
||||
}
|
||||
|
||||
message RemoveStaleVirtiofsShareMountsRequest {}
|
||||
|
||||
message Interfaces {
|
||||
repeated types.Interface Interfaces = 1;
|
||||
}
|
||||
@@ -316,6 +320,10 @@ message UpdateRoutesRequest {
|
||||
Routes routes = 1;
|
||||
}
|
||||
|
||||
message UpdateEphemeralMountsRequest {
|
||||
repeated Storage storages = 1;
|
||||
}
|
||||
|
||||
message ListInterfacesRequest {
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,15 @@ message Hooks {
|
||||
|
||||
// Poststop is a list of hooks to be run after the container process exits.
|
||||
repeated Hook Poststop = 3 [(gogoproto.nullable) = false];
|
||||
|
||||
// Createruntime is a list of hooks to be run during the creation of runtime(sandbox).
|
||||
repeated Hook CreateRuntime = 4 [(gogoproto.nullable) = false];
|
||||
|
||||
// CreateContainer is a list of hooks to be run after VM is started, and before container is created.
|
||||
repeated Hook CreateContainer = 5 [(gogoproto.nullable) = false];
|
||||
|
||||
// StartContainer is a list of hooks to be run after container is created, but before it is started.
|
||||
repeated Hook StartContainer = 6 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
message Hook {
|
||||
|
||||
@@ -11,10 +11,19 @@ pub mod agent_ttrpc;
|
||||
pub mod agent_ttrpc_async;
|
||||
pub mod csi;
|
||||
pub mod empty;
|
||||
mod gogo;
|
||||
pub mod health;
|
||||
pub mod health_ttrpc;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod health_ttrpc_async;
|
||||
pub mod oci;
|
||||
#[cfg(feature = "with-serde")]
|
||||
mod serde_config;
|
||||
pub mod trans;
|
||||
pub mod types;
|
||||
|
||||
#[cfg(feature = "with-serde")]
|
||||
pub use serde_config::{
|
||||
deserialize_enum_or_unknown, deserialize_message_field, serialize_enum_or_unknown,
|
||||
serialize_message_field,
|
||||
};
|
||||
|
||||
68
src/libs/protocols/src/serde_config.rs
Normal file
68
src/libs/protocols/src/serde_config.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2023 Ant Group
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use protobuf::{EnumOrUnknown, MessageField};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(feature = "with-serde")]
|
||||
pub fn serialize_enum_or_unknown<E: protobuf::EnumFull, S: serde::Serializer>(
|
||||
e: &protobuf::EnumOrUnknown<E>,
|
||||
s: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
e.value().serialize(s)
|
||||
}
|
||||
|
||||
pub fn serialize_message_field<E: Serialize, S: serde::Serializer>(
|
||||
e: &protobuf::MessageField<E>,
|
||||
s: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
if e.is_some() {
|
||||
e.as_ref().unwrap().serialize(s)
|
||||
} else {
|
||||
s.serialize_unit()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize_enum_or_unknown<'de, E: Deserialize<'de>, D: serde::Deserializer<'de>>(
|
||||
d: D,
|
||||
) -> Result<protobuf::EnumOrUnknown<E>, D::Error> {
|
||||
i32::deserialize(d).map(EnumOrUnknown::from_i32)
|
||||
}
|
||||
|
||||
pub fn deserialize_message_field<'de, E: Deserialize<'de>, D: serde::Deserializer<'de>>(
|
||||
d: D,
|
||||
) -> Result<protobuf::MessageField<E>, D::Error> {
|
||||
Option::deserialize(d).map(MessageField::from_option)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::agent::{ExecProcessRequest, StringUser};
|
||||
use crate::health::{health_check_response::ServingStatus, HealthCheckResponse};
|
||||
|
||||
#[test]
|
||||
fn test_serde_for_enum_or_unknown() {
|
||||
let mut hc = HealthCheckResponse::new();
|
||||
hc.set_status(ServingStatus::SERVING);
|
||||
|
||||
let json = serde_json::to_string(&hc).unwrap();
|
||||
let from_json: HealthCheckResponse = serde_json::from_str(&json).unwrap();
|
||||
|
||||
assert_eq!(from_json, hc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_for_message_field() {
|
||||
let mut epr = ExecProcessRequest::new();
|
||||
let mut str_user = StringUser::new();
|
||||
str_user.uid = "Someone's id".to_string();
|
||||
epr.set_string_user(str_user);
|
||||
|
||||
let json = serde_json::to_string(&epr).unwrap();
|
||||
let from_json: ExecProcessRequest = serde_json::from_str(&json).unwrap();
|
||||
|
||||
assert_eq!(from_json, epr);
|
||||
}
|
||||
}
|
||||
@@ -15,19 +15,19 @@ use oci::{
|
||||
};
|
||||
|
||||
// translate from interface to ttprc tools
|
||||
fn from_option<F: Sized, T: From<F>>(from: Option<F>) -> ::protobuf::SingularPtrField<T> {
|
||||
fn from_option<F: Sized, T: From<F>>(from: Option<F>) -> protobuf::MessageField<T> {
|
||||
match from {
|
||||
Some(f) => ::protobuf::SingularPtrField::from_option(Some(T::from(f))),
|
||||
None => ::protobuf::SingularPtrField::none(),
|
||||
Some(f) => protobuf::MessageField::from_option(Some(f.into())),
|
||||
None => protobuf::MessageField::none(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_vec<F: Sized, T: From<F>>(from: Vec<F>) -> ::protobuf::RepeatedField<T> {
|
||||
fn from_vec<F: Sized, T: From<F>>(from: Vec<F>) -> Vec<T> {
|
||||
let mut to: Vec<T> = vec![];
|
||||
for data in from {
|
||||
to.push(T::from(data));
|
||||
to.push(data.into());
|
||||
}
|
||||
::protobuf::RepeatedField::from_vec(to)
|
||||
to
|
||||
}
|
||||
|
||||
impl From<oci::Box> for crate::oci::Box {
|
||||
@@ -35,8 +35,7 @@ impl From<oci::Box> for crate::oci::Box {
|
||||
crate::oci::Box {
|
||||
Height: from.height,
|
||||
Width: from.width,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,8 +47,7 @@ impl From<oci::User> for crate::oci::User {
|
||||
GID: from.gid,
|
||||
AdditionalGids: from.additional_gids,
|
||||
Username: from.username,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,13 +55,12 @@ impl From<oci::User> for crate::oci::User {
|
||||
impl From<oci::LinuxCapabilities> for crate::oci::LinuxCapabilities {
|
||||
fn from(from: LinuxCapabilities) -> Self {
|
||||
crate::oci::LinuxCapabilities {
|
||||
Bounding: from_vec(from.bounding),
|
||||
Effective: from_vec(from.effective),
|
||||
Inheritable: from_vec(from.inheritable),
|
||||
Permitted: from_vec(from.permitted),
|
||||
Ambient: from_vec(from.ambient),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
Bounding: from.bounding,
|
||||
Effective: from.effective,
|
||||
Inheritable: from.inheritable,
|
||||
Permitted: from.permitted,
|
||||
Ambient: from.ambient,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,8 +71,7 @@ impl From<oci::PosixRlimit> for crate::oci::POSIXRlimit {
|
||||
Type: from.r#type,
|
||||
Hard: from.hard,
|
||||
Soft: from.soft,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +82,8 @@ impl From<oci::Process> for crate::oci::Process {
|
||||
Terminal: from.terminal,
|
||||
ConsoleSize: from_option(from.console_size),
|
||||
User: from_option(Some(from.user)),
|
||||
Args: from_vec(from.args),
|
||||
Env: from_vec(from.env),
|
||||
Args: from.args,
|
||||
Env: from.env,
|
||||
Cwd: from.cwd,
|
||||
Capabilities: from_option(from.capabilities),
|
||||
Rlimits: from_vec(from.rlimits),
|
||||
@@ -95,8 +91,7 @@ impl From<oci::Process> for crate::oci::Process {
|
||||
ApparmorProfile: from.apparmor_profile,
|
||||
OOMScoreAdj: from.oom_score_adj.map_or(0, |t| t as i64),
|
||||
SelinuxLabel: from.selinux_label,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,8 +104,7 @@ impl From<oci::LinuxDeviceCgroup> for crate::oci::LinuxDeviceCgroup {
|
||||
Major: from.major.map_or(0, |t| t),
|
||||
Minor: from.minor.map_or(0, |t| t),
|
||||
Access: from.access,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,8 +119,7 @@ impl From<oci::LinuxMemory> for crate::oci::LinuxMemory {
|
||||
KernelTCP: from.kernel_tcp.map_or(0, |t| t),
|
||||
Swappiness: from.swappiness.map_or(0, |t| t),
|
||||
DisableOOMKiller: from.disable_oom_killer.map_or(false, |t| t),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,8 +134,7 @@ impl From<oci::LinuxCpu> for crate::oci::LinuxCPU {
|
||||
RealtimePeriod: from.realtime_period.map_or(0, |t| t),
|
||||
Cpus: from.cpus,
|
||||
Mems: from.mems,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,8 +143,7 @@ impl From<oci::LinuxPids> for crate::oci::LinuxPids {
|
||||
fn from(from: LinuxPids) -> Self {
|
||||
crate::oci::LinuxPids {
|
||||
Limit: from.limit,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,8 +156,7 @@ impl From<oci::LinuxWeightDevice> for crate::oci::LinuxWeightDevice {
|
||||
Minor: 0,
|
||||
Weight: from.weight.map_or(0, |t| t as u32),
|
||||
LeafWeight: from.leaf_weight.map_or(0, |t| t as u32),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,8 +168,7 @@ impl From<oci::LinuxThrottleDevice> for crate::oci::LinuxThrottleDevice {
|
||||
Major: 0,
|
||||
Minor: 0,
|
||||
Rate: from.rate,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,8 +183,7 @@ impl From<oci::LinuxBlockIo> for crate::oci::LinuxBlockIO {
|
||||
ThrottleWriteBpsDevice: from_vec(from.throttle_write_bps_device),
|
||||
ThrottleReadIOPSDevice: from_vec(from.throttle_read_iops_device),
|
||||
ThrottleWriteIOPSDevice: from_vec(from.throttle_write_iops_device),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,8 +193,7 @@ impl From<oci::LinuxHugepageLimit> for crate::oci::LinuxHugepageLimit {
|
||||
crate::oci::LinuxHugepageLimit {
|
||||
Pagesize: from.page_size,
|
||||
Limit: from.limit,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,8 +203,7 @@ impl From<oci::LinuxInterfacePriority> for crate::oci::LinuxInterfacePriority {
|
||||
crate::oci::LinuxInterfacePriority {
|
||||
Name: from.name,
|
||||
Priority: from.priority,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,8 +213,7 @@ impl From<oci::LinuxNetwork> for crate::oci::LinuxNetwork {
|
||||
crate::oci::LinuxNetwork {
|
||||
ClassID: from.class_id.map_or(0, |t| t),
|
||||
Priorities: from_vec(from.priorities),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,8 +228,7 @@ impl From<oci::LinuxResources> for crate::oci::LinuxResources {
|
||||
BlockIO: from_option(from.block_io),
|
||||
HugepageLimits: from_vec(from.hugepage_limits),
|
||||
Network: from_option(from.network),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,8 +238,7 @@ impl From<oci::Root> for crate::oci::Root {
|
||||
crate::oci::Root {
|
||||
Path: from.path,
|
||||
Readonly: from.readonly,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,10 +248,9 @@ impl From<oci::Mount> for crate::oci::Mount {
|
||||
crate::oci::Mount {
|
||||
destination: from.destination,
|
||||
source: from.source,
|
||||
field_type: from.r#type,
|
||||
options: from_vec(from.options),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
type_: from.r#type,
|
||||
options: from.options,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,11 +263,10 @@ impl From<oci::Hook> for crate::oci::Hook {
|
||||
}
|
||||
crate::oci::Hook {
|
||||
Path: from.path,
|
||||
Args: from_vec(from.args),
|
||||
Env: from_vec(from.env),
|
||||
Args: from.args,
|
||||
Env: from.env,
|
||||
Timeout: timeout,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,10 +275,12 @@ impl From<oci::Hooks> for crate::oci::Hooks {
|
||||
fn from(from: Hooks) -> Self {
|
||||
crate::oci::Hooks {
|
||||
Prestart: from_vec(from.prestart),
|
||||
CreateRuntime: from_vec(from.create_runtime),
|
||||
CreateContainer: from_vec(from.create_container),
|
||||
StartContainer: from_vec(from.start_container),
|
||||
Poststart: from_vec(from.poststart),
|
||||
Poststop: from_vec(from.poststop),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,8 +291,7 @@ impl From<oci::LinuxIdMapping> for crate::oci::LinuxIDMapping {
|
||||
HostID: from.host_id,
|
||||
ContainerID: from.container_id,
|
||||
Size: from.size,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,8 +301,7 @@ impl From<oci::LinuxNamespace> for crate::oci::LinuxNamespace {
|
||||
crate::oci::LinuxNamespace {
|
||||
Type: from.r#type,
|
||||
Path: from.path,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,8 +316,7 @@ impl From<oci::LinuxDevice> for crate::oci::LinuxDevice {
|
||||
FileMode: from.file_mode.map_or(0, |v| v),
|
||||
UID: from.uid.map_or(0, |v| v),
|
||||
GID: from.gid.map_or(0, |v| v),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,8 +328,7 @@ impl From<oci::LinuxSeccompArg> for crate::oci::LinuxSeccompArg {
|
||||
Value: from.value,
|
||||
ValueTwo: from.value_two,
|
||||
Op: from.op,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,14 +336,13 @@ impl From<oci::LinuxSeccompArg> for crate::oci::LinuxSeccompArg {
|
||||
impl From<oci::LinuxSyscall> for crate::oci::LinuxSyscall {
|
||||
fn from(from: LinuxSyscall) -> Self {
|
||||
crate::oci::LinuxSyscall {
|
||||
Names: from_vec(from.names),
|
||||
Names: from.names,
|
||||
Action: from.action,
|
||||
Args: from_vec(from.args),
|
||||
ErrnoRet: Some(crate::oci::LinuxSyscall_oneof_ErrnoRet::errnoret(
|
||||
ErrnoRet: Some(crate::oci::linux_syscall::ErrnoRet::Errnoret(
|
||||
from.errno_ret,
|
||||
)),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,11 +351,10 @@ impl From<oci::LinuxSeccomp> for crate::oci::LinuxSeccomp {
|
||||
fn from(from: LinuxSeccomp) -> Self {
|
||||
crate::oci::LinuxSeccomp {
|
||||
DefaultAction: from.default_action,
|
||||
Architectures: from_vec(from.architectures),
|
||||
Architectures: from.architectures,
|
||||
Syscalls: from_vec(from.syscalls),
|
||||
Flags: from_vec(from.flags),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
Flags: from.flags,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,8 +363,7 @@ impl From<oci::LinuxIntelRdt> for crate::oci::LinuxIntelRdt {
|
||||
fn from(from: LinuxIntelRdt) -> Self {
|
||||
crate::oci::LinuxIntelRdt {
|
||||
L3CacheSchema: from.l3_cache_schema,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,12 +380,11 @@ impl From<oci::Linux> for crate::oci::Linux {
|
||||
Devices: from_vec(from.devices),
|
||||
Seccomp: from_option(from.seccomp),
|
||||
RootfsPropagation: from.rootfs_propagation,
|
||||
MaskedPaths: from_vec(from.masked_paths),
|
||||
ReadonlyPaths: from_vec(from.readonly_paths),
|
||||
MaskedPaths: from.masked_paths,
|
||||
ReadonlyPaths: from.readonly_paths,
|
||||
MountLabel: from.mount_label,
|
||||
IntelRdt: from_option(from.intel_rdt),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,8 +402,7 @@ impl From<oci::Spec> for crate::oci::Spec {
|
||||
Linux: from_option(from.linux),
|
||||
Solaris: Default::default(),
|
||||
Windows: Default::default(),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +420,7 @@ impl From<crate::oci::Mount> for oci::Mount {
|
||||
fn from(mut from: crate::oci::Mount) -> Self {
|
||||
let options = from.take_options().to_vec();
|
||||
Self {
|
||||
r#type: from.take_field_type(),
|
||||
r#type: from.take_type_(),
|
||||
destination: from.take_destination(),
|
||||
source: from.take_source(),
|
||||
options,
|
||||
@@ -457,9 +431,9 @@ impl From<crate::oci::Mount> for oci::Mount {
|
||||
impl From<crate::oci::LinuxIDMapping> for oci::LinuxIdMapping {
|
||||
fn from(from: crate::oci::LinuxIDMapping) -> Self {
|
||||
LinuxIdMapping {
|
||||
container_id: from.get_ContainerID(),
|
||||
host_id: from.get_HostID(),
|
||||
size: from.get_Size(),
|
||||
container_id: from.ContainerID(),
|
||||
host_id: from.HostID(),
|
||||
size: from.Size(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,17 +441,17 @@ impl From<crate::oci::LinuxIDMapping> for oci::LinuxIdMapping {
|
||||
impl From<crate::oci::LinuxDeviceCgroup> for oci::LinuxDeviceCgroup {
|
||||
fn from(mut from: crate::oci::LinuxDeviceCgroup) -> Self {
|
||||
let mut major = None;
|
||||
if from.get_Major() > 0 {
|
||||
major = Some(from.get_Major());
|
||||
if from.Major() > 0 {
|
||||
major = Some(from.Major());
|
||||
}
|
||||
|
||||
let mut minor = None;
|
||||
if from.get_Minor() > 0 {
|
||||
minor = Some(from.get_Minor())
|
||||
if from.Minor() > 0 {
|
||||
minor = Some(from.Minor())
|
||||
}
|
||||
|
||||
oci::LinuxDeviceCgroup {
|
||||
allow: from.get_Allow(),
|
||||
allow: from.Allow(),
|
||||
r#type: from.take_Type(),
|
||||
major,
|
||||
minor,
|
||||
@@ -489,36 +463,36 @@ impl From<crate::oci::LinuxDeviceCgroup> for oci::LinuxDeviceCgroup {
|
||||
impl From<crate::oci::LinuxMemory> for oci::LinuxMemory {
|
||||
fn from(from: crate::oci::LinuxMemory) -> Self {
|
||||
let mut limit = None;
|
||||
if from.get_Limit() > 0 {
|
||||
limit = Some(from.get_Limit());
|
||||
if from.Limit() > 0 {
|
||||
limit = Some(from.Limit());
|
||||
}
|
||||
|
||||
let mut reservation = None;
|
||||
if from.get_Reservation() > 0 {
|
||||
reservation = Some(from.get_Reservation());
|
||||
if from.Reservation() > 0 {
|
||||
reservation = Some(from.Reservation());
|
||||
}
|
||||
|
||||
let mut swap = None;
|
||||
if from.get_Swap() > 0 {
|
||||
swap = Some(from.get_Swap());
|
||||
if from.Swap() > 0 {
|
||||
swap = Some(from.Swap());
|
||||
}
|
||||
|
||||
let mut kernel = None;
|
||||
if from.get_Kernel() > 0 {
|
||||
kernel = Some(from.get_Kernel());
|
||||
if from.Kernel() > 0 {
|
||||
kernel = Some(from.Kernel());
|
||||
}
|
||||
|
||||
let mut kernel_tcp = None;
|
||||
if from.get_KernelTCP() > 0 {
|
||||
kernel_tcp = Some(from.get_KernelTCP());
|
||||
if from.KernelTCP() > 0 {
|
||||
kernel_tcp = Some(from.KernelTCP());
|
||||
}
|
||||
|
||||
let mut swappiness = None;
|
||||
if from.get_Swappiness() > 0 {
|
||||
swappiness = Some(from.get_Swappiness());
|
||||
if from.Swappiness() > 0 {
|
||||
swappiness = Some(from.Swappiness());
|
||||
}
|
||||
|
||||
let disable_oom_killer = Some(from.get_DisableOOMKiller());
|
||||
let disable_oom_killer = Some(from.DisableOOMKiller());
|
||||
|
||||
oci::LinuxMemory {
|
||||
limit,
|
||||
@@ -535,28 +509,28 @@ impl From<crate::oci::LinuxMemory> for oci::LinuxMemory {
|
||||
impl From<crate::oci::LinuxCPU> for oci::LinuxCpu {
|
||||
fn from(mut from: crate::oci::LinuxCPU) -> Self {
|
||||
let mut shares = None;
|
||||
if from.get_Shares() > 0 {
|
||||
shares = Some(from.get_Shares());
|
||||
if from.Shares() > 0 {
|
||||
shares = Some(from.Shares());
|
||||
}
|
||||
|
||||
let mut quota = None;
|
||||
if from.get_Quota() > 0 {
|
||||
quota = Some(from.get_Quota());
|
||||
if from.Quota() > 0 {
|
||||
quota = Some(from.Quota());
|
||||
}
|
||||
|
||||
let mut period = None;
|
||||
if from.get_Period() > 0 {
|
||||
period = Some(from.get_Period());
|
||||
if from.Period() > 0 {
|
||||
period = Some(from.Period());
|
||||
}
|
||||
|
||||
let mut realtime_runtime = None;
|
||||
if from.get_RealtimeRuntime() > 0 {
|
||||
realtime_runtime = Some(from.get_RealtimeRuntime());
|
||||
if from.RealtimeRuntime() > 0 {
|
||||
realtime_runtime = Some(from.RealtimeRuntime());
|
||||
}
|
||||
|
||||
let mut realtime_period = None;
|
||||
if from.get_RealtimePeriod() > 0 {
|
||||
realtime_period = Some(from.get_RealtimePeriod());
|
||||
if from.RealtimePeriod() > 0 {
|
||||
realtime_period = Some(from.RealtimePeriod());
|
||||
}
|
||||
|
||||
let cpus = from.take_Cpus();
|
||||
@@ -577,7 +551,7 @@ impl From<crate::oci::LinuxCPU> for oci::LinuxCpu {
|
||||
impl From<crate::oci::LinuxPids> for oci::LinuxPids {
|
||||
fn from(from: crate::oci::LinuxPids) -> Self {
|
||||
oci::LinuxPids {
|
||||
limit: from.get_Limit(),
|
||||
limit: from.Limit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,35 +559,35 @@ impl From<crate::oci::LinuxPids> for oci::LinuxPids {
|
||||
impl From<crate::oci::LinuxBlockIO> for oci::LinuxBlockIo {
|
||||
fn from(from: crate::oci::LinuxBlockIO) -> Self {
|
||||
let mut weight = None;
|
||||
if from.get_Weight() > 0 {
|
||||
weight = Some(from.get_Weight() as u16);
|
||||
if from.Weight() > 0 {
|
||||
weight = Some(from.Weight() as u16);
|
||||
}
|
||||
let mut leaf_weight = None;
|
||||
if from.get_LeafWeight() > 0 {
|
||||
leaf_weight = Some(from.get_LeafWeight() as u16);
|
||||
if from.LeafWeight() > 0 {
|
||||
leaf_weight = Some(from.LeafWeight() as u16);
|
||||
}
|
||||
let mut weight_device = Vec::new();
|
||||
for wd in from.get_WeightDevice() {
|
||||
for wd in from.WeightDevice() {
|
||||
weight_device.push(wd.clone().into());
|
||||
}
|
||||
|
||||
let mut throttle_read_bps_device = Vec::new();
|
||||
for td in from.get_ThrottleReadBpsDevice() {
|
||||
for td in from.ThrottleReadBpsDevice() {
|
||||
throttle_read_bps_device.push(td.clone().into());
|
||||
}
|
||||
|
||||
let mut throttle_write_bps_device = Vec::new();
|
||||
for td in from.get_ThrottleWriteBpsDevice() {
|
||||
for td in from.ThrottleWriteBpsDevice() {
|
||||
throttle_write_bps_device.push(td.clone().into());
|
||||
}
|
||||
|
||||
let mut throttle_read_iops_device = Vec::new();
|
||||
for td in from.get_ThrottleReadIOPSDevice() {
|
||||
for td in from.ThrottleReadIOPSDevice() {
|
||||
throttle_read_iops_device.push(td.clone().into());
|
||||
}
|
||||
|
||||
let mut throttle_write_iops_device = Vec::new();
|
||||
for td in from.get_ThrottleWriteIOPSDevice() {
|
||||
for td in from.ThrottleWriteIOPSDevice() {
|
||||
throttle_write_iops_device.push(td.clone().into());
|
||||
}
|
||||
|
||||
@@ -658,7 +632,7 @@ impl From<crate::oci::LinuxInterfacePriority> for oci::LinuxInterfacePriority {
|
||||
fn from(mut from: crate::oci::LinuxInterfacePriority) -> Self {
|
||||
oci::LinuxInterfacePriority {
|
||||
name: from.take_Name(),
|
||||
priority: from.get_Priority(),
|
||||
priority: from.Priority(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,11 +640,11 @@ impl From<crate::oci::LinuxInterfacePriority> for oci::LinuxInterfacePriority {
|
||||
impl From<crate::oci::LinuxNetwork> for oci::LinuxNetwork {
|
||||
fn from(mut from: crate::oci::LinuxNetwork) -> Self {
|
||||
let mut class_id = None;
|
||||
if from.get_ClassID() > 0 {
|
||||
class_id = Some(from.get_ClassID());
|
||||
if from.ClassID() > 0 {
|
||||
class_id = Some(from.ClassID());
|
||||
}
|
||||
let mut priorities = Vec::new();
|
||||
for p in from.take_Priorities().to_vec() {
|
||||
for p in from.take_Priorities() {
|
||||
priorities.push(p.into())
|
||||
}
|
||||
|
||||
@@ -685,7 +659,7 @@ impl From<crate::oci::LinuxHugepageLimit> for oci::LinuxHugepageLimit {
|
||||
fn from(mut from: crate::oci::LinuxHugepageLimit) -> Self {
|
||||
oci::LinuxHugepageLimit {
|
||||
page_size: from.take_Pagesize(),
|
||||
limit: from.get_Limit(),
|
||||
limit: from.Limit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,7 +667,7 @@ impl From<crate::oci::LinuxHugepageLimit> for oci::LinuxHugepageLimit {
|
||||
impl From<crate::oci::LinuxResources> for oci::LinuxResources {
|
||||
fn from(mut from: crate::oci::LinuxResources) -> Self {
|
||||
let mut devices = Vec::new();
|
||||
for d in from.take_Devices().to_vec() {
|
||||
for d in from.take_Devices() {
|
||||
devices.push(d.into());
|
||||
}
|
||||
|
||||
@@ -709,16 +683,16 @@ impl From<crate::oci::LinuxResources> for oci::LinuxResources {
|
||||
|
||||
let mut pids = None;
|
||||
if from.has_Pids() {
|
||||
pids = Some(from.get_Pids().clone().into())
|
||||
pids = Some(from.Pids().clone().into())
|
||||
}
|
||||
|
||||
let mut block_io = None;
|
||||
if from.has_BlockIO() {
|
||||
block_io = Some(from.get_BlockIO().clone().into());
|
||||
block_io = Some(from.BlockIO().clone().into());
|
||||
}
|
||||
|
||||
let mut hugepage_limits = Vec::new();
|
||||
for hl in from.get_HugepageLimits() {
|
||||
for hl in from.HugepageLimits() {
|
||||
hugepage_limits.push(hl.clone().into());
|
||||
}
|
||||
|
||||
@@ -747,11 +721,11 @@ impl From<crate::oci::LinuxDevice> for oci::LinuxDevice {
|
||||
oci::LinuxDevice {
|
||||
path: from.take_Path(),
|
||||
r#type: from.take_Type(),
|
||||
major: from.get_Major(),
|
||||
minor: from.get_Minor(),
|
||||
file_mode: Some(from.get_FileMode()),
|
||||
uid: Some(from.get_UID()),
|
||||
gid: Some(from.get_GID()),
|
||||
major: from.Major(),
|
||||
minor: from.Minor(),
|
||||
file_mode: Some(from.FileMode()),
|
||||
uid: Some(from.UID()),
|
||||
gid: Some(from.GID()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,9 +733,9 @@ impl From<crate::oci::LinuxDevice> for oci::LinuxDevice {
|
||||
impl From<crate::oci::LinuxSeccompArg> for oci::LinuxSeccompArg {
|
||||
fn from(mut from: crate::oci::LinuxSeccompArg) -> Self {
|
||||
oci::LinuxSeccompArg {
|
||||
index: from.get_Index() as u32,
|
||||
value: from.get_Value(),
|
||||
value_two: from.get_ValueTwo(),
|
||||
index: from.Index() as u32,
|
||||
value: from.Value(),
|
||||
value_two: from.ValueTwo(),
|
||||
op: from.take_Op(),
|
||||
}
|
||||
}
|
||||
@@ -770,14 +744,14 @@ impl From<crate::oci::LinuxSeccompArg> for oci::LinuxSeccompArg {
|
||||
impl From<crate::oci::LinuxSyscall> for oci::LinuxSyscall {
|
||||
fn from(mut from: crate::oci::LinuxSyscall) -> Self {
|
||||
let mut args = Vec::new();
|
||||
for ag in from.take_Args().to_vec() {
|
||||
for ag in from.take_Args() {
|
||||
args.push(ag.into());
|
||||
}
|
||||
oci::LinuxSyscall {
|
||||
names: from.take_Names().to_vec(),
|
||||
action: from.take_Action(),
|
||||
args,
|
||||
errno_ret: from.get_errnoret(),
|
||||
errno_ret: from.errnoret(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +759,7 @@ impl From<crate::oci::LinuxSyscall> for oci::LinuxSyscall {
|
||||
impl From<crate::oci::LinuxSeccomp> for oci::LinuxSeccomp {
|
||||
fn from(mut from: crate::oci::LinuxSeccomp) -> Self {
|
||||
let mut syscalls = Vec::new();
|
||||
for s in from.take_Syscalls().to_vec() {
|
||||
for s in from.take_Syscalls() {
|
||||
syscalls.push(s.into());
|
||||
}
|
||||
|
||||
@@ -810,16 +784,16 @@ impl From<crate::oci::LinuxNamespace> for oci::LinuxNamespace {
|
||||
impl From<crate::oci::Linux> for oci::Linux {
|
||||
fn from(mut from: crate::oci::Linux) -> Self {
|
||||
let mut uid_mappings = Vec::new();
|
||||
for id_map in from.take_UIDMappings().to_vec() {
|
||||
for id_map in from.take_UIDMappings() {
|
||||
uid_mappings.push(id_map.into())
|
||||
}
|
||||
|
||||
let mut gid_mappings = Vec::new();
|
||||
for id_map in from.take_GIDMappings().to_vec() {
|
||||
for id_map in from.take_GIDMappings() {
|
||||
gid_mappings.push(id_map.into())
|
||||
}
|
||||
|
||||
let sysctl = from.get_Sysctl().clone();
|
||||
let sysctl = from.Sysctl().clone();
|
||||
let mut resources = None;
|
||||
if from.has_Resources() {
|
||||
resources = Some(from.take_Resources().into());
|
||||
@@ -827,12 +801,12 @@ impl From<crate::oci::Linux> for oci::Linux {
|
||||
|
||||
let cgroups_path = from.take_CgroupsPath();
|
||||
let mut namespaces = Vec::new();
|
||||
for ns in from.take_Namespaces().to_vec() {
|
||||
for ns in from.take_Namespaces() {
|
||||
namespaces.push(ns.into())
|
||||
}
|
||||
|
||||
let mut devices = Vec::new();
|
||||
for d in from.take_Devices().to_vec() {
|
||||
for d in from.take_Devices() {
|
||||
devices.push(d.into());
|
||||
}
|
||||
|
||||
@@ -871,8 +845,8 @@ impl From<crate::oci::POSIXRlimit> for oci::PosixRlimit {
|
||||
fn from(mut from: crate::oci::POSIXRlimit) -> Self {
|
||||
oci::PosixRlimit {
|
||||
r#type: from.take_Type(),
|
||||
hard: from.get_Hard(),
|
||||
soft: from.get_Soft(),
|
||||
hard: from.Hard(),
|
||||
soft: from.Soft(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -892,8 +866,8 @@ impl From<crate::oci::LinuxCapabilities> for oci::LinuxCapabilities {
|
||||
impl From<crate::oci::User> for oci::User {
|
||||
fn from(mut from: crate::oci::User) -> Self {
|
||||
oci::User {
|
||||
uid: from.get_UID(),
|
||||
gid: from.get_GID(),
|
||||
uid: from.UID(),
|
||||
gid: from.GID(),
|
||||
additional_gids: from.take_AdditionalGids().to_vec(),
|
||||
username: from.take_Username(),
|
||||
}
|
||||
@@ -903,8 +877,8 @@ impl From<crate::oci::User> for oci::User {
|
||||
impl From<crate::oci::Box> for oci::Box {
|
||||
fn from(from: crate::oci::Box) -> Self {
|
||||
oci::Box {
|
||||
height: from.get_Height(),
|
||||
width: from.get_Width(),
|
||||
height: from.Height(),
|
||||
width: from.Width(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -917,22 +891,22 @@ impl From<crate::oci::Process> for oci::Process {
|
||||
}
|
||||
|
||||
let user = from.take_User().into();
|
||||
let args = from.take_Args().into_vec();
|
||||
let env = from.take_Env().into_vec();
|
||||
let args = from.take_Args();
|
||||
let env = from.take_Env();
|
||||
let cwd = from.take_Cwd();
|
||||
let mut capabilities = None;
|
||||
if from.has_Capabilities() {
|
||||
capabilities = Some(from.take_Capabilities().into());
|
||||
}
|
||||
let mut rlimits = Vec::new();
|
||||
for rl in from.take_Rlimits().to_vec() {
|
||||
for rl in from.take_Rlimits() {
|
||||
rlimits.push(rl.into());
|
||||
}
|
||||
let no_new_privileges = from.get_NoNewPrivileges();
|
||||
let no_new_privileges = from.NoNewPrivileges();
|
||||
let apparmor_profile = from.take_ApparmorProfile();
|
||||
let mut oom_score_adj = None;
|
||||
if from.get_OOMScoreAdj() != 0 {
|
||||
oom_score_adj = Some(from.get_OOMScoreAdj() as i32);
|
||||
if from.OOMScoreAdj() != 0 {
|
||||
oom_score_adj = Some(from.OOMScoreAdj() as i32);
|
||||
}
|
||||
let selinux_label = from.take_SelinuxLabel();
|
||||
|
||||
@@ -956,8 +930,8 @@ impl From<crate::oci::Process> for oci::Process {
|
||||
impl From<crate::oci::Hook> for oci::Hook {
|
||||
fn from(mut from: crate::oci::Hook) -> Self {
|
||||
let mut timeout = None;
|
||||
if from.get_Timeout() > 0 {
|
||||
timeout = Some(from.get_Timeout() as i32);
|
||||
if from.Timeout() > 0 {
|
||||
timeout = Some(from.Timeout() as i32);
|
||||
}
|
||||
oci::Hook {
|
||||
path: from.take_Path(),
|
||||
@@ -970,20 +944,34 @@ impl From<crate::oci::Hook> for oci::Hook {
|
||||
|
||||
impl From<crate::oci::Hooks> for oci::Hooks {
|
||||
fn from(mut from: crate::oci::Hooks) -> Self {
|
||||
let mut prestart = Vec::new();
|
||||
for hook in from.take_Prestart().to_vec() {
|
||||
prestart.push(hook.into())
|
||||
}
|
||||
let mut poststart = Vec::new();
|
||||
for hook in from.take_Poststart().to_vec() {
|
||||
poststart.push(hook.into());
|
||||
}
|
||||
let mut poststop = Vec::new();
|
||||
for hook in from.take_Poststop().to_vec() {
|
||||
poststop.push(hook.into());
|
||||
}
|
||||
let prestart = from.take_Prestart().into_iter().map(|i| i.into()).collect();
|
||||
let create_runtime = from
|
||||
.take_CreateRuntime()
|
||||
.into_iter()
|
||||
.map(|i| i.into())
|
||||
.collect();
|
||||
let create_container = from
|
||||
.take_CreateContainer()
|
||||
.into_iter()
|
||||
.map(|i| i.into())
|
||||
.collect();
|
||||
let start_container = from
|
||||
.take_StartContainer()
|
||||
.into_iter()
|
||||
.map(|i| i.into())
|
||||
.collect();
|
||||
let poststart = from
|
||||
.take_Poststart()
|
||||
.into_iter()
|
||||
.map(|i| i.into())
|
||||
.collect();
|
||||
let poststop = from.take_Poststop().into_iter().map(|i| i.into()).collect();
|
||||
|
||||
oci::Hooks {
|
||||
prestart,
|
||||
create_runtime,
|
||||
create_container,
|
||||
start_container,
|
||||
poststart,
|
||||
poststop,
|
||||
}
|
||||
@@ -1003,7 +991,7 @@ impl From<crate::oci::Spec> for oci::Spec {
|
||||
}
|
||||
|
||||
let mut mounts = Vec::new();
|
||||
for m in from.take_Mounts().into_vec() {
|
||||
for m in from.take_Mounts() {
|
||||
mounts.push(m.into())
|
||||
}
|
||||
|
||||
@@ -1068,7 +1056,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_from_vec_len_0() {
|
||||
let from: Vec<TestA> = vec![];
|
||||
let to: ::protobuf::RepeatedField<TestB> = from_vec(from.clone());
|
||||
let to: Vec<TestB> = from_vec(from.clone());
|
||||
assert_eq!(from.len(), to.len());
|
||||
}
|
||||
|
||||
@@ -1077,7 +1065,7 @@ mod tests {
|
||||
let from: Vec<TestA> = vec![TestA {
|
||||
from: "a".to_string(),
|
||||
}];
|
||||
let to: ::protobuf::RepeatedField<TestB> = from_vec(from.clone());
|
||||
let to: Vec<TestB> = from_vec(from.clone());
|
||||
|
||||
assert_eq!(from.len(), to.len());
|
||||
assert_eq!(from[0].from, to[0].to);
|
||||
|
||||
@@ -53,7 +53,7 @@ impl MgmtClient {
|
||||
.method(Method::GET)
|
||||
.uri(url)
|
||||
.body(Body::empty())?;
|
||||
return self.send_request(req).await;
|
||||
self.send_request(req).await
|
||||
}
|
||||
|
||||
/// The HTTP Post method for client
|
||||
@@ -72,7 +72,7 @@ impl MgmtClient {
|
||||
.uri(url)
|
||||
.header("content-type", content_type)
|
||||
.body(body)?;
|
||||
return self.send_request(req).await;
|
||||
self.send_request(req).await
|
||||
}
|
||||
|
||||
/// The http PUT method for client
|
||||
@@ -82,7 +82,7 @@ impl MgmtClient {
|
||||
.method(Method::PUT)
|
||||
.uri(url)
|
||||
.body(Body::from(data))?;
|
||||
return self.send_request(req).await;
|
||||
self.send_request(req).await
|
||||
}
|
||||
|
||||
async fn send_request(&self, req: Request<Body>) -> Result<Response<Body>> {
|
||||
|
||||
1433
src/runtime-rs/Cargo.lock
generated
1433
src/runtime-rs/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,10 @@ CONTAINERD_RUNTIME_NAME = io.containerd.kata.v2
|
||||
|
||||
include ../../utils.mk
|
||||
|
||||
ifeq ($(ARCH), ppc64le)
|
||||
override ARCH = powerpc64le
|
||||
endif
|
||||
|
||||
ARCH_DIR = arch
|
||||
ARCH_FILE_SUFFIX = -options.mk
|
||||
ARCH_FILE = $(ARCH_DIR)/$(ARCH)$(ARCH_FILE_SUFFIX)
|
||||
@@ -203,7 +207,7 @@ ifneq (,$(DBCMD))
|
||||
DEFNETWORKMODEL_DB := tcfilter
|
||||
KERNELPARAMS = console=ttyS1 agent.log_vport=1025
|
||||
KERNELTYPE_DB = uncompressed
|
||||
KERNEL_NAME_DB = $(call MAKE_KERNEL_NAME,$(KERNELTYPE_DB))
|
||||
KERNEL_NAME_DB = $(call MAKE_KERNEL_NAME_DB,$(KERNELTYPE_DB))
|
||||
KERNELPATH_DB = $(KERNELDIR)/$(KERNEL_NAME_DB)
|
||||
DEFSANDBOXCGROUPONLY = true
|
||||
RUNTIMENAME := virt_container
|
||||
@@ -371,8 +375,8 @@ endef
|
||||
|
||||
# Returns the name of the kernel file to use based on the provided KERNELTYPE.
|
||||
# $1 : KERNELTYPE (compressed or uncompressed)
|
||||
define MAKE_KERNEL_NAME
|
||||
$(if $(findstring uncompressed,$1),vmlinux.container,vmlinuz.container)
|
||||
define MAKE_KERNEL_NAME_DB
|
||||
$(if $(findstring uncompressed,$1),vmlinux-dragonball-experimental.container,vmlinuz-dragonball-experimental.container)
|
||||
endef
|
||||
|
||||
.DEFAULT_GOAL := default
|
||||
|
||||
@@ -206,15 +206,22 @@ container_pipe_size=@PIPESIZE@
|
||||
#debug_console_enabled = true
|
||||
|
||||
# Agent connection dialing timeout value in seconds
|
||||
# (default: 30)
|
||||
#dial_timeout = 30
|
||||
# (default: 45)
|
||||
dial_timeout = 45
|
||||
|
||||
[runtime]
|
||||
# If enabled, the runtime will log additional debug messages to the
|
||||
# system log
|
||||
# (default: disabled)
|
||||
#enable_debug = true
|
||||
#
|
||||
|
||||
# If enabled, enabled, it means that 1) if the runtime exits abnormally,
|
||||
# the cleanup process will be skipped, and 2) the runtime will not exit
|
||||
# even if the health check fails.
|
||||
# This option is typically used to retain abnormal information for debugging.
|
||||
# (default: false)
|
||||
#keep_abnormal = true
|
||||
|
||||
# Internetworking model
|
||||
# Determines how the VM should be connected to the
|
||||
# the container network interface
|
||||
@@ -293,5 +300,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (default: false)
|
||||
# enable_pprof = true
|
||||
|
||||
static_resource_mgmt=@DEFSTATICRESOURCEMGMT_DB@
|
||||
# If enabled, the runtime will attempt to determine appropriate sandbox size (memory, CPU) before booting the virtual machine. In
|
||||
# this case, the runtime will not dynamically update the amount of memory and CPU in the virtual machine. This is generally helpful
|
||||
# when a hardware architecture or hypervisor solutions is utilized which does not support CPU and/or memory hotplug.
|
||||
# Compatibility for determining appropriate sandbox (VM) size:
|
||||
# - When running with pods, sandbox sizing information will only be available if using Kubernetes >= 1.23 and containerd >= 1.6. CRI-O
|
||||
# does not yet support sandbox sizing annotations.
|
||||
# - When running single containers using a tool like ctr, container sizing information will be available.
|
||||
static_sandbox_resource_mgmt=@DEFSTATICRESOURCEMGMT_DB@
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ futures = "0.1.27"
|
||||
anyhow = "1.0.26"
|
||||
async-trait = "0.1.48"
|
||||
log = "0.4.14"
|
||||
protobuf = "2.27.0"
|
||||
protobuf = "3.2.0"
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = ">=1.0.9"
|
||||
slog = "2.5.2"
|
||||
slog-scope = "4.4.0"
|
||||
ttrpc = { version = "0.6.1" }
|
||||
ttrpc = { version = "0.7.1" }
|
||||
tokio = { version = "1.28.1", features = ["fs", "rt"] }
|
||||
url = "2.2.2"
|
||||
nix = "0.24.2"
|
||||
|
||||
@@ -56,7 +56,7 @@ macro_rules! impl_health_service {
|
||||
impl HealthService for KataAgent {
|
||||
$(async fn $name(&self, req: $req) -> Result<$resp> {
|
||||
let r = req.into();
|
||||
let (mut client, timeout, _) = self.get_health_client().await.context("get health client")?;
|
||||
let (client, timeout, _) = self.get_health_client().await.context("get health client")?;
|
||||
let resp = client.$name(new_ttrpc_ctx(timeout * MILLISECOND_TO_NANOSECOND), &r).await?;
|
||||
Ok(resp.into())
|
||||
})*
|
||||
@@ -75,7 +75,7 @@ macro_rules! impl_agent {
|
||||
impl Agent for KataAgent {
|
||||
$(async fn $name(&self, req: $req) -> Result<$resp> {
|
||||
let r = req.into();
|
||||
let (mut client, mut timeout, _) = self.get_agent_client().await.context("get client")?;
|
||||
let (client, mut timeout, _) = self.get_agent_client().await.context("get client")?;
|
||||
|
||||
// update new timeout
|
||||
if let Some(v) = $new_timeout {
|
||||
@@ -115,5 +115,7 @@ impl_agent!(
|
||||
copy_file | crate::CopyFileRequest | crate::Empty | None,
|
||||
get_oom_event | crate::Empty | crate::OomEventResponse | Some(0),
|
||||
get_ip_tables | crate::GetIPTablesRequest | crate::GetIPTablesResponse | None,
|
||||
set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None
|
||||
set_ip_tables | crate::SetIPTablesRequest | crate::SetIPTablesResponse | None,
|
||||
get_volume_stats | crate::VolumeStatsRequest | crate::VolumeStatsResponse | None,
|
||||
resize_volume | crate::ResizeVolumeRequest | crate::Empty | None
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::convert::Into;
|
||||
|
||||
use protocols::{
|
||||
agent::{self, OOMEvent},
|
||||
empty, health, types,
|
||||
csi, empty, health, types,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -20,39 +20,28 @@ use crate::{
|
||||
GetIPTablesResponse, GuestDetailsResponse, HealthCheckResponse, HugetlbStats, IPAddress,
|
||||
IPFamily, Interface, Interfaces, KernelModule, MemHotplugByProbeRequest, MemoryData,
|
||||
MemoryStats, NetworkStats, OnlineCPUMemRequest, PidsStats, ReadStreamRequest,
|
||||
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, Route, Routes,
|
||||
SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest,
|
||||
StatsContainerResponse, Storage, StringUser, ThrottlingData, TtyWinResizeRequest,
|
||||
UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse,
|
||||
WaitProcessRequest, WriteStreamRequest,
|
||||
ReadStreamResponse, RemoveContainerRequest, ReseedRandomDevRequest, ResizeVolumeRequest,
|
||||
Route, Routes, SetGuestDateTimeRequest, SetIPTablesRequest, SetIPTablesResponse,
|
||||
SignalProcessRequest, StatsContainerResponse, Storage, StringUser, ThrottlingData,
|
||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
VersionCheckResponse, VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest,
|
||||
WriteStreamRequest,
|
||||
},
|
||||
OomEventResponse, WaitProcessResponse, WriteStreamResponse,
|
||||
};
|
||||
|
||||
fn from_vec<F: Into<T>, T: Sized>(from: Vec<F>) -> ::protobuf::RepeatedField<T> {
|
||||
let mut to: Vec<T> = vec![];
|
||||
for data in from {
|
||||
to.push(data.into());
|
||||
}
|
||||
::protobuf::RepeatedField::from_vec(to)
|
||||
fn trans_vec<F: Sized + Clone, T: From<F>>(from: Vec<F>) -> Vec<T> {
|
||||
from.into_iter().map(|f| f.into()).collect()
|
||||
}
|
||||
|
||||
fn into_vec<F: Sized + Clone, T: From<F>>(from: ::protobuf::RepeatedField<F>) -> Vec<T> {
|
||||
let mut to: Vec<T> = vec![];
|
||||
for data in from.to_vec() {
|
||||
to.push(data.into());
|
||||
}
|
||||
to
|
||||
}
|
||||
|
||||
fn from_option<F: Sized, T: From<F>>(from: Option<F>) -> ::protobuf::SingularPtrField<T> {
|
||||
fn from_option<F: Sized, T: From<F>>(from: Option<F>) -> protobuf::MessageField<T> {
|
||||
match from {
|
||||
Some(f) => ::protobuf::SingularPtrField::from_option(Some(T::from(f))),
|
||||
None => ::protobuf::SingularPtrField::none(),
|
||||
Some(f) => protobuf::MessageField::from_option(Some(T::from(f))),
|
||||
None => protobuf::MessageField::none(),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_option<F: Into<T>, T: Sized>(from: ::protobuf::SingularPtrField<F>) -> Option<T> {
|
||||
fn into_option<F: Into<T>, T: Sized>(from: protobuf::MessageField<F>) -> Option<T> {
|
||||
from.into_option().map(|f| f.into())
|
||||
}
|
||||
|
||||
@@ -83,9 +72,8 @@ impl From<FSGroup> for agent::FSGroup {
|
||||
|
||||
Self {
|
||||
group_id: from.group_id,
|
||||
group_change_policy: policy,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
group_change_policy: policy.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,9 +83,8 @@ impl From<StringUser> for agent::StringUser {
|
||||
Self {
|
||||
uid: from.uid,
|
||||
gid: from.gid,
|
||||
additionalGids: ::protobuf::RepeatedField::from_vec(from.additional_gids),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
additionalGids: from.additional_gids,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,12 +93,11 @@ impl From<Device> for agent::Device {
|
||||
fn from(from: Device) -> Self {
|
||||
Self {
|
||||
id: from.id,
|
||||
field_type: from.field_type,
|
||||
type_: from.field_type,
|
||||
vm_path: from.vm_path,
|
||||
container_path: from.container_path,
|
||||
options: from_vec(from.options),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
options: trans_vec(from.options),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,14 +106,13 @@ impl From<Storage> for agent::Storage {
|
||||
fn from(from: Storage) -> Self {
|
||||
Self {
|
||||
driver: from.driver,
|
||||
driver_options: from_vec(from.driver_options),
|
||||
driver_options: trans_vec(from.driver_options),
|
||||
source: from.source,
|
||||
fstype: from.fs_type,
|
||||
fs_group: from_option(from.fs_group),
|
||||
options: from_vec(from.options),
|
||||
options: trans_vec(from.options),
|
||||
mount_point: from.mount_point,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,9 +121,8 @@ impl From<KernelModule> for agent::KernelModule {
|
||||
fn from(from: KernelModule) -> Self {
|
||||
Self {
|
||||
name: from.name,
|
||||
parameters: from_vec(from.parameters),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
parameters: trans_vec(from.parameters),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,11 +149,10 @@ impl From<types::IPFamily> for IPFamily {
|
||||
impl From<IPAddress> for types::IPAddress {
|
||||
fn from(from: IPAddress) -> Self {
|
||||
Self {
|
||||
family: from.family.into(),
|
||||
family: protobuf::EnumOrUnknown::new(from.family.into()),
|
||||
address: from.address,
|
||||
mask: from.mask,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,7 +160,7 @@ impl From<IPAddress> for types::IPAddress {
|
||||
impl From<types::IPAddress> for IPAddress {
|
||||
fn from(src: types::IPAddress) -> Self {
|
||||
Self {
|
||||
family: src.family.into(),
|
||||
family: src.family.unwrap().into(),
|
||||
address: "".to_string(),
|
||||
mask: "".to_string(),
|
||||
}
|
||||
@@ -189,14 +172,13 @@ impl From<Interface> for types::Interface {
|
||||
Self {
|
||||
device: from.device,
|
||||
name: from.name,
|
||||
IPAddresses: from_vec(from.ip_addresses),
|
||||
IPAddresses: trans_vec(from.ip_addresses),
|
||||
mtu: from.mtu,
|
||||
hwAddr: from.hw_addr,
|
||||
pciPath: from.pci_addr,
|
||||
field_type: from.field_type,
|
||||
type_: from.field_type,
|
||||
raw_flags: from.raw_flags,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,11 +188,11 @@ impl From<types::Interface> for Interface {
|
||||
Self {
|
||||
device: src.device,
|
||||
name: src.name,
|
||||
ip_addresses: into_vec(src.IPAddresses),
|
||||
ip_addresses: trans_vec(src.IPAddresses),
|
||||
mtu: src.mtu,
|
||||
hw_addr: src.hwAddr,
|
||||
pci_addr: src.pciPath,
|
||||
field_type: src.field_type,
|
||||
field_type: src.type_,
|
||||
raw_flags: src.raw_flags,
|
||||
}
|
||||
}
|
||||
@@ -219,7 +201,7 @@ impl From<types::Interface> for Interface {
|
||||
impl From<agent::Interfaces> for Interfaces {
|
||||
fn from(src: agent::Interfaces) -> Self {
|
||||
Self {
|
||||
interfaces: into_vec(src.Interfaces),
|
||||
interfaces: trans_vec(src.Interfaces),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,9 +214,8 @@ impl From<Route> for types::Route {
|
||||
device: from.device,
|
||||
source: from.source,
|
||||
scope: from.scope,
|
||||
family: from.family.into(),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
family: protobuf::EnumOrUnknown::new(from.family.into()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,7 +228,7 @@ impl From<types::Route> for Route {
|
||||
device: src.device,
|
||||
source: src.source,
|
||||
scope: src.scope,
|
||||
family: src.family.into(),
|
||||
family: src.family.unwrap().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,9 +236,8 @@ impl From<types::Route> for Route {
|
||||
impl From<Routes> for agent::Routes {
|
||||
fn from(from: Routes) -> Self {
|
||||
Self {
|
||||
Routes: from_vec(from.routes),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
Routes: trans_vec(from.routes),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +245,7 @@ impl From<Routes> for agent::Routes {
|
||||
impl From<agent::Routes> for Routes {
|
||||
fn from(src: agent::Routes) -> Self {
|
||||
Self {
|
||||
routes: into_vec(src.Routes),
|
||||
routes: trans_vec(src.Routes),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,12 +256,11 @@ impl From<CreateContainerRequest> for agent::CreateContainerRequest {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
string_user: from_option(from.string_user),
|
||||
devices: from_vec(from.devices),
|
||||
storages: from_vec(from.storages),
|
||||
devices: trans_vec(from.devices),
|
||||
storages: trans_vec(from.storages),
|
||||
OCI: from_option(from.oci),
|
||||
sandbox_pidns: from.sandbox_pidns,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,8 +270,7 @@ impl From<RemoveContainerRequest> for agent::RemoveContainerRequest {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
timeout: from.timeout,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,8 +279,7 @@ impl From<ContainerID> for agent::StartContainerRequest {
|
||||
fn from(from: ContainerID) -> Self {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,8 +288,7 @@ impl From<ContainerID> for agent::StatsContainerRequest {
|
||||
fn from(from: ContainerID) -> Self {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,8 +297,7 @@ impl From<ContainerID> for agent::PauseContainerRequest {
|
||||
fn from(from: ContainerID) -> Self {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,8 +306,7 @@ impl From<ContainerID> for agent::ResumeContainerRequest {
|
||||
fn from(from: ContainerID) -> Self {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,8 +317,7 @@ impl From<SignalProcessRequest> for agent::SignalProcessRequest {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
signal: from.signal,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,8 +327,7 @@ impl From<WaitProcessRequest> for agent::WaitProcessRequest {
|
||||
Self {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,8 +337,7 @@ impl From<UpdateContainerRequest> for agent::UpdateContainerRequest {
|
||||
Self {
|
||||
container_id: from.container_id,
|
||||
resources: from_option(Some(from.resources)),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,8 +348,7 @@ impl From<WriteStreamRequest> for agent::WriteStreamRequest {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
data: from.data,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,7 +371,7 @@ impl From<GetIPTablesRequest> for agent::GetIPTablesRequest {
|
||||
impl From<agent::GetIPTablesResponse> for GetIPTablesResponse {
|
||||
fn from(from: agent::GetIPTablesResponse) -> Self {
|
||||
Self {
|
||||
data: from.get_data().to_vec(),
|
||||
data: from.data().to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,7 +389,7 @@ impl From<SetIPTablesRequest> for agent::SetIPTablesRequest {
|
||||
impl From<agent::SetIPTablesResponse> for SetIPTablesResponse {
|
||||
fn from(from: agent::SetIPTablesResponse) -> Self {
|
||||
Self {
|
||||
data: from.get_data().to_vec(),
|
||||
data: from.data().to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,8 +401,7 @@ impl From<ExecProcessRequest> for agent::ExecProcessRequest {
|
||||
exec_id: from.process_id.exec_id(),
|
||||
string_user: from_option(from.string_user),
|
||||
process: from_option(from.process),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,14 +483,14 @@ impl From<agent::BlkioStatsEntry> for BlkioStatsEntry {
|
||||
impl From<agent::BlkioStats> for BlkioStats {
|
||||
fn from(src: agent::BlkioStats) -> Self {
|
||||
Self {
|
||||
io_service_bytes_recursive: into_vec(src.io_service_bytes_recursive),
|
||||
io_serviced_recursive: into_vec(src.io_serviced_recursive),
|
||||
io_queued_recursive: into_vec(src.io_queued_recursive),
|
||||
io_service_time_recursive: into_vec(src.io_service_time_recursive),
|
||||
io_wait_time_recursive: into_vec(src.io_wait_time_recursive),
|
||||
io_merged_recursive: into_vec(src.io_merged_recursive),
|
||||
io_time_recursive: into_vec(src.io_time_recursive),
|
||||
sectors_recursive: into_vec(src.sectors_recursive),
|
||||
io_service_bytes_recursive: trans_vec(src.io_service_bytes_recursive),
|
||||
io_serviced_recursive: trans_vec(src.io_serviced_recursive),
|
||||
io_queued_recursive: trans_vec(src.io_queued_recursive),
|
||||
io_service_time_recursive: trans_vec(src.io_service_time_recursive),
|
||||
io_wait_time_recursive: trans_vec(src.io_wait_time_recursive),
|
||||
io_merged_recursive: trans_vec(src.io_merged_recursive),
|
||||
io_time_recursive: trans_vec(src.io_time_recursive),
|
||||
sectors_recursive: trans_vec(src.sectors_recursive),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,7 +538,7 @@ impl From<agent::StatsContainerResponse> for StatsContainerResponse {
|
||||
fn from(src: agent::StatsContainerResponse) -> Self {
|
||||
Self {
|
||||
cgroup_stats: into_option(src.cgroup_stats),
|
||||
network_stats: into_vec(src.network_stats),
|
||||
network_stats: trans_vec(src.network_stats),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,8 +549,7 @@ impl From<ReadStreamRequest> for agent::ReadStreamRequest {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
len: from.len,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -597,8 +565,7 @@ impl From<CloseStdinRequest> for agent::CloseStdinRequest {
|
||||
Self {
|
||||
container_id: from.process_id.container_id(),
|
||||
exec_id: from.process_id.exec_id(),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,8 +577,7 @@ impl From<TtyWinResizeRequest> for agent::TtyWinResizeRequest {
|
||||
exec_id: from.process_id.exec_id(),
|
||||
row: from.row,
|
||||
column: from.column,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,8 +586,7 @@ impl From<UpdateInterfaceRequest> for agent::UpdateInterfaceRequest {
|
||||
fn from(from: UpdateInterfaceRequest) -> Self {
|
||||
Self {
|
||||
interface: from_option(from.interface),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -629,8 +594,7 @@ impl From<UpdateInterfaceRequest> for agent::UpdateInterfaceRequest {
|
||||
impl From<Empty> for agent::ListInterfacesRequest {
|
||||
fn from(_: Empty) -> Self {
|
||||
Self {
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -639,8 +603,7 @@ impl From<UpdateRoutesRequest> for agent::UpdateRoutesRequest {
|
||||
fn from(from: UpdateRoutesRequest) -> Self {
|
||||
Self {
|
||||
routes: from_option(from.route),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -648,8 +611,7 @@ impl From<UpdateRoutesRequest> for agent::UpdateRoutesRequest {
|
||||
impl From<Empty> for agent::ListRoutesRequest {
|
||||
fn from(_: Empty) -> Self {
|
||||
Self {
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -662,8 +624,7 @@ impl From<ARPNeighbor> for types::ARPNeighbor {
|
||||
lladdr: from.ll_addr,
|
||||
state: from.state,
|
||||
flags: from.flags,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,9 +632,8 @@ impl From<ARPNeighbor> for types::ARPNeighbor {
|
||||
impl From<ARPNeighbors> for agent::ARPNeighbors {
|
||||
fn from(from: ARPNeighbors) -> Self {
|
||||
Self {
|
||||
ARPNeighbors: from_vec(from.neighbors),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
ARPNeighbors: trans_vec(from.neighbors),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -682,8 +642,7 @@ impl From<AddArpNeighborRequest> for agent::AddARPNeighborsRequest {
|
||||
fn from(from: AddArpNeighborRequest) -> Self {
|
||||
Self {
|
||||
neighbors: from_option(from.neighbors),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -692,14 +651,13 @@ impl From<CreateSandboxRequest> for agent::CreateSandboxRequest {
|
||||
fn from(from: CreateSandboxRequest) -> Self {
|
||||
Self {
|
||||
hostname: from.hostname,
|
||||
dns: from_vec(from.dns),
|
||||
storages: from_vec(from.storages),
|
||||
dns: trans_vec(from.dns),
|
||||
storages: trans_vec(from.storages),
|
||||
sandbox_pidns: from.sandbox_pidns,
|
||||
sandbox_id: from.sandbox_id,
|
||||
guest_hook_path: from.guest_hook_path,
|
||||
kernel_modules: from_vec(from.kernel_modules),
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
kernel_modules: trans_vec(from.kernel_modules),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -707,8 +665,7 @@ impl From<CreateSandboxRequest> for agent::CreateSandboxRequest {
|
||||
impl From<Empty> for agent::DestroySandboxRequest {
|
||||
fn from(_: Empty) -> Self {
|
||||
Self {
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -719,8 +676,7 @@ impl From<OnlineCPUMemRequest> for agent::OnlineCPUMemRequest {
|
||||
wait: from.wait,
|
||||
nb_cpus: from.nb_cpus,
|
||||
cpu_only: from.cpu_only,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,8 +685,7 @@ impl From<ReseedRandomDevRequest> for agent::ReseedRandomDevRequest {
|
||||
fn from(from: ReseedRandomDevRequest) -> Self {
|
||||
Self {
|
||||
data: from.data,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -739,8 +694,7 @@ impl From<MemHotplugByProbeRequest> for agent::MemHotplugByProbeRequest {
|
||||
fn from(from: MemHotplugByProbeRequest) -> Self {
|
||||
Self {
|
||||
memHotplugProbeAddr: from.mem_hotplug_probe_addr,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -750,8 +704,7 @@ impl From<SetGuestDateTimeRequest> for agent::SetGuestDateTimeRequest {
|
||||
Self {
|
||||
Sec: from.sec,
|
||||
Usec: from.usec,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -761,8 +714,8 @@ impl From<agent::AgentDetails> for AgentDetails {
|
||||
Self {
|
||||
version: src.version,
|
||||
init_daemon: src.init_daemon,
|
||||
device_handlers: into_vec(src.device_handlers),
|
||||
storage_handlers: into_vec(src.storage_handlers),
|
||||
device_handlers: trans_vec(src.device_handlers),
|
||||
storage_handlers: trans_vec(src.storage_handlers),
|
||||
supports_seccomp: src.supports_seccomp,
|
||||
}
|
||||
}
|
||||
@@ -789,8 +742,7 @@ impl From<CopyFileRequest> for agent::CopyFileRequest {
|
||||
gid: from.gid,
|
||||
offset: from.offset,
|
||||
data: from.data,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -806,8 +758,7 @@ impl From<agent::WaitProcessResponse> for WaitProcessResponse {
|
||||
impl From<Empty> for agent::GetOOMEventRequest {
|
||||
fn from(_: Empty) -> Self {
|
||||
Self {
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -816,8 +767,7 @@ impl From<CheckRequest> for health::CheckRequest {
|
||||
fn from(from: CheckRequest) -> Self {
|
||||
Self {
|
||||
service: from.service,
|
||||
unknown_fields: Default::default(),
|
||||
cached_size: Default::default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -825,7 +775,7 @@ impl From<CheckRequest> for health::CheckRequest {
|
||||
impl From<health::HealthCheckResponse> for HealthCheckResponse {
|
||||
fn from(from: health::HealthCheckResponse) -> Self {
|
||||
Self {
|
||||
status: from.status as u32,
|
||||
status: from.status.value() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -846,3 +796,33 @@ impl From<agent::OOMEvent> for OomEventResponse {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VolumeStatsRequest> for agent::VolumeStatsRequest {
|
||||
fn from(from: VolumeStatsRequest) -> Self {
|
||||
Self {
|
||||
volume_guest_path: from.volume_guest_path,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<csi::VolumeStatsResponse> for VolumeStatsResponse {
|
||||
fn from(from: csi::VolumeStatsResponse) -> Self {
|
||||
let result: String = format!(
|
||||
"Usage: {:?} Volume Condition: {:?}",
|
||||
from.usage(),
|
||||
from.volume_condition()
|
||||
);
|
||||
Self { data: result }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResizeVolumeRequest> for agent::ResizeVolumeRequest {
|
||||
fn from(from: ResizeVolumeRequest) -> Self {
|
||||
Self {
|
||||
volume_guest_path: from.volume_guest_path,
|
||||
size: from.size,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ pub use types::{
|
||||
ReseedRandomDevRequest, ResizeVolumeRequest, Route, Routes, SetGuestDateTimeRequest,
|
||||
SetIPTablesRequest, SetIPTablesResponse, SignalProcessRequest, StatsContainerResponse, Storage,
|
||||
TtyWinResizeRequest, UpdateContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
VersionCheckResponse, WaitProcessRequest, WaitProcessResponse, WriteStreamRequest,
|
||||
WriteStreamResponse,
|
||||
VersionCheckResponse, VolumeStatsRequest, VolumeStatsResponse, WaitProcessRequest,
|
||||
WaitProcessResponse, WriteStreamRequest, WriteStreamResponse,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -88,4 +88,6 @@ pub trait Agent: AgentManager + HealthService + Send + Sync {
|
||||
async fn get_oom_event(&self, req: Empty) -> Result<OomEventResponse>;
|
||||
async fn get_ip_tables(&self, req: GetIPTablesRequest) -> Result<GetIPTablesResponse>;
|
||||
async fn set_ip_tables(&self, req: SetIPTablesRequest) -> Result<SetIPTablesResponse>;
|
||||
async fn get_volume_stats(&self, req: VolumeStatsRequest) -> Result<VolumeStatsResponse>;
|
||||
async fn resize_volume(&self, req: ResizeVolumeRequest) -> Result<Empty>;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@ use tokio::{
|
||||
|
||||
use super::{ConnectConfig, Sock, Stream};
|
||||
|
||||
unsafe impl Send for HybridVsock {}
|
||||
unsafe impl Sync for HybridVsock {}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct HybridVsock {
|
||||
uds: String,
|
||||
|
||||
@@ -16,9 +16,6 @@ use tokio::net::UnixStream;
|
||||
|
||||
use super::{ConnectConfig, Sock, Stream};
|
||||
|
||||
unsafe impl Send for Vsock {}
|
||||
unsafe impl Sync for Vsock {}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Vsock {
|
||||
vsock_cid: u32,
|
||||
|
||||
@@ -9,6 +9,8 @@ use std::convert::TryFrom;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const DEFAULT_REMOVE_CONTAINER_REQUEST_TIMEOUT: u32 = 10;
|
||||
|
||||
#[derive(PartialEq, Clone, Default)]
|
||||
pub struct Empty {}
|
||||
|
||||
@@ -18,14 +20,9 @@ impl Empty {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FSGroupChangePolicy {
|
||||
fn default() -> Self {
|
||||
FSGroupChangePolicy::Always
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Clone, PartialEq)]
|
||||
pub enum FSGroupChangePolicy {
|
||||
#[default]
|
||||
Always = 0,
|
||||
OnRootMismatch = 1,
|
||||
}
|
||||
@@ -63,18 +60,13 @@ pub struct Storage {
|
||||
pub mount_point: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Deserialize, Default, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum IPFamily {
|
||||
#[default]
|
||||
V4 = 0,
|
||||
V6 = 1,
|
||||
}
|
||||
|
||||
impl ::std::default::Default for IPFamily {
|
||||
fn default() -> Self {
|
||||
IPFamily::V4
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Clone, Default)]
|
||||
pub struct IPAddress {
|
||||
pub family: IPFamily,
|
||||
@@ -124,7 +116,6 @@ pub struct CreateContainerRequest {
|
||||
pub devices: Vec<Device>,
|
||||
pub storages: Vec<Storage>,
|
||||
pub oci: Option<oci::Spec>,
|
||||
pub guest_hooks: Option<oci::Hooks>,
|
||||
pub sandbox_pidns: bool,
|
||||
pub rootfs_mounts: Vec<oci::Mount>,
|
||||
}
|
||||
@@ -165,7 +156,7 @@ impl ContainerProcessID {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Default)]
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct RemoveContainerRequest {
|
||||
pub container_id: String,
|
||||
pub timeout: u32,
|
||||
@@ -180,6 +171,15 @@ impl RemoveContainerRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for RemoveContainerRequest {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
container_id: "".to_string(),
|
||||
timeout: DEFAULT_REMOVE_CONTAINER_REQUEST_TIMEOUT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default)]
|
||||
pub struct SignalProcessRequest {
|
||||
pub process_id: ContainerProcessID,
|
||||
@@ -569,6 +569,16 @@ pub struct ResizeVolumeRequest {
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct VolumeStatsRequest {
|
||||
pub volume_guest_path: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Default, Debug)]
|
||||
pub struct VolumeStatsResponse {
|
||||
pub data: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user