mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-26 15:32:30 +00:00
genpolicy: add containerd pull method
Add optional toggle to use existing containerd installation to pull and manage container images. This adds support to a wider set of images that are currently not supported by standard pull method, such as those that use v1 manifest. Fixes: #9144 Signed-off-by: Saul Paredes <saulparedes@microsoft.com>
This commit is contained in:
parent
8b996b9307
commit
c96ebf237c
430
src/tools/genpolicy/Cargo.lock
generated
430
src/tools/genpolicy/Cargo.lock
generated
@ -64,6 +64,51 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"mime",
|
||||
"rustversion",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
@ -79,15 +124,6 @@ dependencies = [
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
@ -96,9 +132,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
@ -212,6 +248,20 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "containerd-client"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcbd55a5b186b60273ed7361d18d566ede8d66db962bafd702dd4db7fd30f23f"
|
||||
dependencies = [
|
||||
"prost 0.11.9",
|
||||
"prost-types 0.11.9",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tonic-build 0.9.2",
|
||||
"tower",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
@ -336,11 +386,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "docker_credential"
|
||||
version = "1.2.0"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f2821ba7f89de240e70f4af347ba5260512d0799a53556c10750805bad7c7fc"
|
||||
checksum = "8765d595e4f1c66eb5b94450209b316516366d403984664efda0d9b28a55ff9e"
|
||||
dependencies = [
|
||||
"base64 0.10.1",
|
||||
"base64 0.21.7",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@ -373,6 +423,12 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
@ -432,6 +488,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
@ -551,12 +613,14 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"base64 0.21.0",
|
||||
"base64 0.21.7",
|
||||
"clap",
|
||||
"containerd-client",
|
||||
"docker_credential",
|
||||
"env_logger",
|
||||
"flate2",
|
||||
"generic-array",
|
||||
"k8s-cri",
|
||||
"log",
|
||||
"oci",
|
||||
"oci-distribution",
|
||||
@ -572,9 +636,22 @@ dependencies = [
|
||||
"tarindex",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tower",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.0"
|
||||
@ -593,7 +670,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"indexmap 1.9.2",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@ -606,6 +683,12 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
@ -727,6 +810,18 @@ dependencies = [
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-timeout"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
|
||||
dependencies = [
|
||||
"hyper",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-io-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
@ -781,7 +876,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -860,6 +965,18 @@ dependencies = [
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "k8s-cri"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1ac03a0ee89d53fc350989682a56915a4f93fe7b51801a1066cb3caeb2a23f"
|
||||
dependencies = [
|
||||
"prost 0.11.9",
|
||||
"serde",
|
||||
"tonic",
|
||||
"tonic-build 0.8.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -921,6 +1038,12 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
@ -1142,8 +1265,38 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
"fixedbitset 0.2.0",
|
||||
"indexmap 1.9.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
|
||||
dependencies = [
|
||||
"fixedbitset 0.4.2",
|
||||
"indexmap 2.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1164,6 +1317,22 @@ version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
@ -1190,9 +1359,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -1204,7 +1373,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
"prost-derive 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.11.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1218,9 +1397,31 @@ dependencies = [
|
||||
"itertools",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"petgraph 0.5.1",
|
||||
"prost 0.8.0",
|
||||
"prost-types 0.8.0",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph 0.6.4",
|
||||
"prettyplease",
|
||||
"prost 0.11.9",
|
||||
"prost-types 0.11.9",
|
||||
"regex",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
@ -1238,6 +1439,19 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.8.0"
|
||||
@ -1245,7 +1459,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "603bbd6394701d13f3f25aada59c7de9d35a6a5887cfc156181234a44002771b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost",
|
||||
"prost 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
|
||||
dependencies = [
|
||||
"prost 0.11.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1296,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77d6fbd6697c9e531873e81cec565a85e226b99a0f10e1acc079be057fe2fcba"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"indexmap 1.9.2",
|
||||
"log",
|
||||
"protobuf 3.3.0",
|
||||
"protobuf-support",
|
||||
@ -1335,6 +1558,36 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@ -1376,7 +1629,7 @@ version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
@ -1456,6 +1709,12 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
@ -1561,7 +1820,7 @@ version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.2",
|
||||
"ryu",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
@ -1641,6 +1900,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.38"
|
||||
@ -1744,6 +2009,16 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io-timeout"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.1.0"
|
||||
@ -1765,6 +2040,17 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
@ -1779,6 +2065,86 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-timeout",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.11.9",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic-build"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4"
|
||||
dependencies = [
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"prost-build 0.11.9",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic-build"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07"
|
||||
dependencies = [
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"prost-build 0.11.9",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap 1.9.2",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
@ -1860,9 +2226,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0672eb06e5663ad190c7b93b2973f5d730259859b62e4e3381301a12a7441107"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"prost-types",
|
||||
"prost 0.8.0",
|
||||
"prost-build 0.8.0",
|
||||
"prost-types 0.8.0",
|
||||
"protobuf 2.28.0",
|
||||
"protobuf-codegen 2.28.0",
|
||||
"tempfile",
|
||||
|
@ -59,3 +59,7 @@ sha2 = "0.10.6"
|
||||
tarindex = { git = "https://github.com/kata-containers/tardev-snapshotter", rev = "06183a5" }
|
||||
tempfile = "3.5.0"
|
||||
zerocopy = "0.6.1"
|
||||
k8s-cri = "0.7.0"
|
||||
tonic = "0.9.2"
|
||||
tower = "0.4.13"
|
||||
containerd-client = "0.4.0"
|
||||
|
@ -10,6 +10,7 @@ use crate::obj_meta;
|
||||
use crate::pod;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -81,7 +82,7 @@ pub fn get_value(value_from: &pod::EnvVarSource, config_maps: &Vec<ConfigMap>) -
|
||||
impl yaml::K8sResource for ConfigMap {
|
||||
async fn init(
|
||||
&mut self,
|
||||
_use_cache: bool,
|
||||
_config: &Config,
|
||||
doc_mapping: &serde_yaml::Value,
|
||||
_silent_unsupported_fields: bool,
|
||||
) {
|
||||
|
@ -11,6 +11,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -72,11 +73,11 @@ struct RollingUpdateDaemonSet {
|
||||
impl yaml::K8sResource for DaemonSet {
|
||||
async fn init(
|
||||
&mut self,
|
||||
use_cache: bool,
|
||||
config: &Config,
|
||||
doc_mapping: &serde_yaml::Value,
|
||||
_silent_unsupported_fields: bool,
|
||||
) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -70,11 +71,11 @@ struct RollingUpdateDeployment {
|
||||
impl yaml::K8sResource for Deployment {
|
||||
async fn init(
|
||||
&mut self,
|
||||
use_cache: bool,
|
||||
config: &Config,
|
||||
doc_mapping: &serde_yaml::Value,
|
||||
_silent_unsupported_fields: bool,
|
||||
) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -44,11 +45,11 @@ pub struct JobSpec {
|
||||
impl yaml::K8sResource for Job {
|
||||
async fn init(
|
||||
&mut self,
|
||||
use_cache: bool,
|
||||
config: &Config,
|
||||
doc_mapping: &serde_yaml::Value,
|
||||
_silent_unsupported_fields: bool,
|
||||
) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
use crate::pod;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -39,12 +40,12 @@ impl Debug for dyn yaml::K8sResource + Send + Sync {
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for List {
|
||||
async fn init(&mut self, use_cache: bool, _doc_mapping: &serde_yaml::Value, silent: bool) {
|
||||
async fn init(&mut self, config: &Config, _doc_mapping: &serde_yaml::Value, silent: bool) {
|
||||
// Create K8sResource objects for each item in this List.
|
||||
for item in &self.items {
|
||||
let yaml_string = serde_yaml::to_string(&item).unwrap();
|
||||
let (mut resource, _kind) = yaml::new_k8s_resource(&yaml_string, silent).unwrap();
|
||||
resource.init(use_cache, item, silent).await;
|
||||
resource.init(config, item, silent).await;
|
||||
self.resources.push(resource);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ mod pod;
|
||||
mod pod_template;
|
||||
mod policy;
|
||||
mod registry;
|
||||
mod registry_containerd;
|
||||
mod replica_set;
|
||||
mod replication_controller;
|
||||
mod secret;
|
||||
|
@ -9,6 +9,7 @@
|
||||
use crate::pod;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -24,7 +25,7 @@ pub struct NoPolicyResource {
|
||||
impl yaml::K8sResource for NoPolicyResource {
|
||||
async fn init(
|
||||
&mut self,
|
||||
_use_cache: bool,
|
||||
_config: &Config,
|
||||
_doc_mapping: &serde_yaml::Value,
|
||||
_silent_unsupported_fields: bool,
|
||||
) {
|
||||
|
@ -12,6 +12,7 @@ use crate::policy;
|
||||
use crate::registry;
|
||||
use crate::secret;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::volume;
|
||||
use crate::yaml;
|
||||
|
||||
@ -480,11 +481,9 @@ struct PodDNSConfigOption {
|
||||
}
|
||||
|
||||
impl Container {
|
||||
pub async fn init(&mut self, use_cache: bool) {
|
||||
pub async fn init(&mut self, config: &Config) {
|
||||
// Load container image properties from the registry.
|
||||
self.registry = registry::get_container(use_cache, &self.image)
|
||||
.await
|
||||
.unwrap();
|
||||
self.registry = registry::get_container(config, &self.image).await.unwrap();
|
||||
}
|
||||
|
||||
pub fn get_env_variables(
|
||||
@ -691,8 +690,8 @@ impl EnvVar {
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for Pod {
|
||||
async fn init(&mut self, use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec, use_cache).await;
|
||||
async fn init(&mut self, config: &Config, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
@ -832,7 +831,7 @@ fn compress_capabilities(capabilities: &mut Vec<String>, defaults: &policy::Comm
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add_pause_container(containers: &mut Vec<Container>, use_cache: bool) {
|
||||
pub async fn add_pause_container(containers: &mut Vec<Container>, config: &Config) {
|
||||
debug!("Adding pause container...");
|
||||
let mut pause_container = Container {
|
||||
// TODO: load this path from the settings file.
|
||||
@ -849,7 +848,7 @@ pub async fn add_pause_container(containers: &mut Vec<Container>, use_cache: boo
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
pause_container.init(use_cache).await;
|
||||
pause_container.init(config).await;
|
||||
containers.insert(0, pause_container);
|
||||
debug!("pause container added.");
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ impl AgentPolicy {
|
||||
let yaml_string = serde_yaml::to_string(&doc_mapping)?;
|
||||
let silent = config.silent_unsupported_fields;
|
||||
let (mut resource, kind) = yaml::new_k8s_resource(&yaml_string, silent)?;
|
||||
resource.init(config.use_cache, &doc_mapping, silent).await;
|
||||
resource.init(config, &doc_mapping, silent).await;
|
||||
|
||||
// ConfigMap and Secret documents contain additional input for policy generation.
|
||||
if kind.eq("ConfigMap") {
|
||||
|
@ -10,6 +10,7 @@ use crate::containerd;
|
||||
use crate::policy;
|
||||
use crate::verity;
|
||||
|
||||
use crate::utils::Config;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use docker_credential::{CredentialRetrievalError, DockerCredential};
|
||||
use log::warn;
|
||||
@ -25,16 +26,16 @@ use tokio::{fs, io::AsyncWriteExt};
|
||||
/// Container image properties obtained from an OCI repository.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Container {
|
||||
config_layer: DockerConfigLayer,
|
||||
image_layers: Vec<ImageLayer>,
|
||||
pub config_layer: DockerConfigLayer,
|
||||
pub image_layers: Vec<ImageLayer>,
|
||||
}
|
||||
|
||||
/// Image config layer properties.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
struct DockerConfigLayer {
|
||||
pub struct DockerConfigLayer {
|
||||
architecture: String,
|
||||
config: DockerImageConfig,
|
||||
rootfs: DockerRootfs,
|
||||
pub rootfs: DockerRootfs,
|
||||
}
|
||||
|
||||
/// Image config properties.
|
||||
@ -50,9 +51,9 @@ struct DockerImageConfig {
|
||||
|
||||
/// Container rootfs information.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
struct DockerRootfs {
|
||||
pub struct DockerRootfs {
|
||||
r#type: String,
|
||||
diff_ids: Vec<String>,
|
||||
pub diff_ids: Vec<String>,
|
||||
}
|
||||
|
||||
/// This application's image layer properties.
|
||||
@ -260,25 +261,25 @@ async fn get_image_layers(
|
||||
Ok(layers)
|
||||
}
|
||||
|
||||
fn get_verity_path(base_dir: &Path, file_name: &str) -> PathBuf {
|
||||
pub fn get_verity_path(base_dir: &Path, file_name: &str) -> PathBuf {
|
||||
let mut verity_path: PathBuf = base_dir.join(file_name);
|
||||
verity_path.set_extension("verity");
|
||||
verity_path
|
||||
}
|
||||
|
||||
fn get_decompressed_path(verity_path: &Path) -> PathBuf {
|
||||
pub fn get_decompressed_path(verity_path: &Path) -> PathBuf {
|
||||
let mut decompressed_path = verity_path.to_path_buf().clone();
|
||||
decompressed_path.set_extension("tar");
|
||||
decompressed_path
|
||||
}
|
||||
|
||||
fn get_compressed_path(decompressed_path: &Path) -> PathBuf {
|
||||
pub fn get_compressed_path(decompressed_path: &Path) -> PathBuf {
|
||||
let mut compressed_path = decompressed_path.to_path_buf().clone();
|
||||
compressed_path.set_extension("gz");
|
||||
compressed_path
|
||||
}
|
||||
|
||||
async fn delete_files(base_dir: &Path, file_name: &str) {
|
||||
pub async fn delete_files(base_dir: &Path, file_name: &str) {
|
||||
let verity_path = get_verity_path(base_dir, file_name);
|
||||
let _ = fs::remove_file(&verity_path).await;
|
||||
|
||||
@ -399,7 +400,7 @@ async fn create_decompressed_layer_file(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_create_verity_hash_file(decompressed_path: &PathBuf) -> Result<()> {
|
||||
pub fn do_create_verity_hash_file(decompressed_path: &PathBuf) -> Result<()> {
|
||||
info!("Calculating dm-verity root hash");
|
||||
let mut file = std::fs::File::open(decompressed_path)?;
|
||||
let size = file.seek(std::io::SeekFrom::End(0))?;
|
||||
@ -425,9 +426,11 @@ fn do_create_verity_hash_file(decompressed_path: &PathBuf) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_container(use_cache: bool, image: &str) -> Result<Container> {
|
||||
Container::new(use_cache, image).await
|
||||
pub async fn get_container(config: &Config, image: &str) -> Result<Container> {
|
||||
if let Some(socket_path) = &config.containerd_socket_path {
|
||||
return Container::new_containerd_pull(config.use_cache, image, socket_path).await;
|
||||
}
|
||||
Container::new(config.use_cache, image).await
|
||||
}
|
||||
|
||||
fn build_auth(reference: &Reference) -> RegistryAuth {
|
||||
|
398
src/tools/genpolicy/src/registry_containerd.rs
Normal file
398
src/tools/genpolicy/src/registry_containerd.rs
Normal file
@ -0,0 +1,398 @@
|
||||
// Copyright (c) 2023 Microsoft Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
// Allow Docker image config field names.
|
||||
#![allow(non_snake_case)]
|
||||
use crate::registry::{
|
||||
delete_files, do_create_verity_hash_file, get_compressed_path, get_decompressed_path,
|
||||
get_verity_path, Container, DockerConfigLayer, ImageLayer,
|
||||
};
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use containerd_client::services::v1::GetImageRequest;
|
||||
use containerd_client::with_namespace;
|
||||
use docker_credential::{CredentialRetrievalError, DockerCredential};
|
||||
use k8s_cri::v1::{image_service_client::ImageServiceClient, AuthConfig};
|
||||
use log::warn;
|
||||
use log::{debug, info};
|
||||
use oci_distribution::Reference;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::{io::Seek, io::Write, path::Path, path::PathBuf};
|
||||
use tokio::io;
|
||||
use tokio::io::{AsyncSeekExt, AsyncWriteExt};
|
||||
use tokio::net::UnixStream;
|
||||
use tonic::transport::{Endpoint, Uri};
|
||||
use tonic::Request;
|
||||
use tower::service_fn;
|
||||
|
||||
impl Container {
|
||||
pub async fn new_containerd_pull(
|
||||
use_cached_files: bool,
|
||||
image: &str,
|
||||
containerd_socket_path: &str,
|
||||
) -> Result<Self> {
|
||||
info!("============================================");
|
||||
info!("Using containerd socket: {:?}", containerd_socket_path);
|
||||
|
||||
let ctrd_path = containerd_socket_path.to_string();
|
||||
let containerd_channel = Endpoint::try_from("http://[::]")
|
||||
.unwrap()
|
||||
.connect_with_connector(service_fn(move |_: Uri| {
|
||||
UnixStream::connect(ctrd_path.clone())
|
||||
}))
|
||||
.await?;
|
||||
|
||||
let ctrd_client = containerd_client::Client::from(containerd_channel.clone());
|
||||
let k8_cri_image_client = ImageServiceClient::new(containerd_channel);
|
||||
|
||||
let image_ref: Reference = image.to_string().parse().unwrap();
|
||||
|
||||
info!("Pulling image: {:?}", image_ref);
|
||||
|
||||
pull_image(&image_ref, k8_cri_image_client.clone()).await?;
|
||||
|
||||
let image_ref_str = &image_ref.to_string();
|
||||
|
||||
let manifest = get_image_manifest(image_ref_str, &ctrd_client).await?;
|
||||
let config_layer = get_config_layer(image_ref_str, k8_cri_image_client)
|
||||
.await
|
||||
.unwrap();
|
||||
let image_layers =
|
||||
get_image_layers(use_cached_files, &manifest, &config_layer, &ctrd_client).await?;
|
||||
|
||||
Ok(Container {
|
||||
config_layer,
|
||||
image_layers,
|
||||
})
|
||||
}
|
||||
}
|
||||
pub async fn get_content(
|
||||
digest: &str,
|
||||
client: &containerd_client::Client,
|
||||
) -> Result<serde_json::Value, anyhow::Error> {
|
||||
let req = containerd_client::services::v1::ReadContentRequest {
|
||||
digest: digest.to_string(),
|
||||
offset: 0,
|
||||
size: 0,
|
||||
};
|
||||
let req = with_namespace!(req, "k8s.io");
|
||||
let mut c = client.content();
|
||||
let resp = c.read(req).await?;
|
||||
let mut stream = resp.into_inner();
|
||||
|
||||
if let Some(chunk) = stream.message().await? {
|
||||
if chunk.offset < 0 {
|
||||
return Err(anyhow!("Negative offset in chunk"));
|
||||
}
|
||||
return Ok(serde_json::from_slice(&chunk.data)?);
|
||||
}
|
||||
|
||||
Err(anyhow!("Unable to find content for digest: {}", digest))
|
||||
}
|
||||
|
||||
pub async fn get_image_manifest(
|
||||
image_ref: &str,
|
||||
client: &containerd_client::Client,
|
||||
) -> Result<serde_json::Value> {
|
||||
let mut imageChannel = client.images();
|
||||
|
||||
let req = GetImageRequest {
|
||||
name: image_ref.to_string(),
|
||||
};
|
||||
let req = with_namespace!(req, "k8s.io");
|
||||
let resp = imageChannel.get(req).await?;
|
||||
|
||||
let image_digest = resp.into_inner().image.unwrap().target.unwrap().digest;
|
||||
|
||||
// content may be an image manifest (https://github.com/opencontainers/image-spec/blob/main/manifest.md)
|
||||
//or an image index (https://github.com/opencontainers/image-spec/blob/main/image-index.md)
|
||||
let content = get_content(&image_digest, client).await?;
|
||||
|
||||
let is_image_manifest = content.get("layers").is_some();
|
||||
|
||||
if is_image_manifest {
|
||||
return Ok(content);
|
||||
}
|
||||
|
||||
// else, content is an image index
|
||||
let image_index = content;
|
||||
|
||||
let manifests = image_index["manifests"].as_array().unwrap();
|
||||
|
||||
let mut manifestAmd64 = &serde_json::Value::Null;
|
||||
|
||||
for entry in manifests {
|
||||
let platform = entry["platform"].as_object().unwrap();
|
||||
let architecture = platform["architecture"].as_str().unwrap();
|
||||
let os = platform["os"].as_str().unwrap();
|
||||
if architecture == "amd64" && os == "linux" {
|
||||
manifestAmd64 = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let image_digest = manifestAmd64["digest"].as_str().unwrap();
|
||||
|
||||
get_content(image_digest, client).await
|
||||
}
|
||||
|
||||
pub async fn get_config_layer(
|
||||
image_ref: &str,
|
||||
mut client: ImageServiceClient<tonic::transport::Channel>,
|
||||
) -> Result<DockerConfigLayer> {
|
||||
let req = k8s_cri::v1::ImageStatusRequest {
|
||||
image: Some(k8s_cri::v1::ImageSpec {
|
||||
image: image_ref.to_string(),
|
||||
annotations: HashMap::new(),
|
||||
}),
|
||||
verbose: true,
|
||||
};
|
||||
|
||||
let resp = client.image_status(req).await?;
|
||||
let image_layers = resp.into_inner();
|
||||
|
||||
let status_info: serde_json::Value =
|
||||
serde_json::from_str(image_layers.info.get("info").unwrap())?;
|
||||
let image_spec = status_info["imageSpec"].as_object().unwrap();
|
||||
let docker_config_layer: DockerConfigLayer =
|
||||
serde_json::from_value(serde_json::to_value(image_spec)?)?;
|
||||
|
||||
Ok(docker_config_layer)
|
||||
}
|
||||
|
||||
pub async fn pull_image(
|
||||
image_ref: &Reference,
|
||||
mut client: ImageServiceClient<tonic::transport::Channel>,
|
||||
) -> Result<()> {
|
||||
let auth = build_auth(&image_ref);
|
||||
|
||||
debug!("cri auth: {:?}", auth);
|
||||
|
||||
let req = k8s_cri::v1::PullImageRequest {
|
||||
image: Some(k8s_cri::v1::ImageSpec {
|
||||
image: image_ref.to_string(),
|
||||
annotations: HashMap::new(),
|
||||
}),
|
||||
auth,
|
||||
sandbox_config: None,
|
||||
};
|
||||
|
||||
client.pull_image(req).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build_auth(reference: &Reference) -> Option<AuthConfig> {
|
||||
debug!("build_auth: {:?}", reference);
|
||||
|
||||
let server = reference
|
||||
.resolve_registry()
|
||||
.strip_suffix('/')
|
||||
.unwrap_or_else(|| reference.resolve_registry());
|
||||
|
||||
debug!("server: {:?}", server);
|
||||
|
||||
match docker_credential::get_credential(server) {
|
||||
Ok(DockerCredential::UsernamePassword(username, password)) => {
|
||||
debug!("build_auth: Found docker credentials");
|
||||
return Some(AuthConfig {
|
||||
username,
|
||||
password,
|
||||
auth: "".to_string(),
|
||||
server_address: "".to_string(),
|
||||
identity_token: "".to_string(),
|
||||
registry_token: "".to_string(),
|
||||
});
|
||||
}
|
||||
Ok(DockerCredential::IdentityToken(identity_token)) => {
|
||||
debug!("build_auth: Found identity token");
|
||||
return Some(AuthConfig {
|
||||
username: "".to_string(),
|
||||
password: "".to_string(),
|
||||
auth: "".to_string(),
|
||||
server_address: "".to_string(),
|
||||
identity_token,
|
||||
registry_token: "".to_string(),
|
||||
});
|
||||
}
|
||||
Err(CredentialRetrievalError::ConfigNotFound) => {
|
||||
debug!("build_auth: Docker config not found - using anonymous access.");
|
||||
}
|
||||
Err(CredentialRetrievalError::NoCredentialConfigured) => {
|
||||
debug!("build_auth: Docker credentials not configured - using anonymous access.");
|
||||
}
|
||||
Err(CredentialRetrievalError::ConfigReadError) => {
|
||||
debug!("build_auth: Cannot read docker credentials - using anonymous access.");
|
||||
}
|
||||
Err(CredentialRetrievalError::HelperFailure { stdout, stderr }) => {
|
||||
if stdout == "credentials not found in native keychain\n" {
|
||||
// On WSL, this error is generated when credentials are not
|
||||
// available in ~/.docker/config.json.
|
||||
debug!("build_auth: Docker credentials not found - using anonymous access.");
|
||||
} else {
|
||||
warn!("build_auth: Docker credentials not found - using anonymous access. stderr = {}, stdout = {}",
|
||||
&stderr, &stdout);
|
||||
}
|
||||
}
|
||||
Err(e) => panic!("Error handling docker configuration file: {}", e),
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub async fn get_image_layers(
|
||||
use_cached_files: bool,
|
||||
manifest: &serde_json::Value,
|
||||
config_layer: &DockerConfigLayer,
|
||||
client: &containerd_client::Client,
|
||||
) -> Result<Vec<ImageLayer>> {
|
||||
let mut layer_index = 0;
|
||||
let mut layersVec = Vec::new();
|
||||
|
||||
let layers = manifest["layers"].as_array().unwrap();
|
||||
|
||||
for layer in layers {
|
||||
let layer_media_type = layer["mediaType"].as_str().unwrap();
|
||||
if layer_media_type.eq("application/vnd.docker.image.rootfs.diff.tar.gzip")
|
||||
|| layer_media_type.eq("application/vnd.oci.image.layer.v1.tar+gzip")
|
||||
{
|
||||
if layer_index < config_layer.rootfs.diff_ids.len() {
|
||||
let imageLayer = ImageLayer {
|
||||
diff_id: config_layer.rootfs.diff_ids[layer_index].clone(),
|
||||
verity_hash: get_verity_hash(
|
||||
use_cached_files,
|
||||
client,
|
||||
layer["digest"].as_str().unwrap(),
|
||||
)
|
||||
.await?,
|
||||
};
|
||||
layersVec.push(imageLayer);
|
||||
} else {
|
||||
return Err(anyhow!("Too many Docker gzip layers"));
|
||||
}
|
||||
layer_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(layersVec)
|
||||
}
|
||||
|
||||
async fn get_verity_hash(
|
||||
use_cached_files: bool,
|
||||
client: &containerd_client::Client,
|
||||
layer_digest: &str,
|
||||
) -> Result<String> {
|
||||
// Use file names supported by both Linux and Windows.
|
||||
let file_name = str::replace(layer_digest, ":", "-");
|
||||
|
||||
let base_dir = std::path::Path::new("layers_cache");
|
||||
let verity_path = get_verity_path(base_dir, &file_name);
|
||||
|
||||
if use_cached_files && verity_path.exists() {
|
||||
info!("Using cache file");
|
||||
} else if let Err(e) = create_verity_hash_file(
|
||||
use_cached_files,
|
||||
layer_digest,
|
||||
base_dir,
|
||||
&get_decompressed_path(&verity_path),
|
||||
client,
|
||||
)
|
||||
.await
|
||||
{
|
||||
delete_files(base_dir, &file_name).await;
|
||||
bail!("{e}");
|
||||
}
|
||||
|
||||
match std::fs::read_to_string(&verity_path) {
|
||||
Err(e) => {
|
||||
delete_files(base_dir, &file_name).await;
|
||||
bail!("Failed to read {:?}, error {e}", &verity_path);
|
||||
}
|
||||
Ok(v) => {
|
||||
if !use_cached_files {
|
||||
let _ = std::fs::remove_dir_all(base_dir);
|
||||
}
|
||||
info!("dm-verity root hash: {v}");
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_verity_hash_file(
|
||||
use_cached_files: bool,
|
||||
layer_digest: &str,
|
||||
base_dir: &Path,
|
||||
decompressed_path: &PathBuf,
|
||||
client: &containerd_client::Client,
|
||||
) -> Result<()> {
|
||||
if use_cached_files && decompressed_path.exists() {
|
||||
info!("Using cached file {:?}", &decompressed_path);
|
||||
} else {
|
||||
std::fs::create_dir_all(base_dir)?;
|
||||
create_decompressed_layer_file(use_cached_files, layer_digest, decompressed_path, client)
|
||||
.await?;
|
||||
}
|
||||
|
||||
do_create_verity_hash_file(decompressed_path)
|
||||
}
|
||||
|
||||
async fn create_decompressed_layer_file(
|
||||
use_cached_files: bool,
|
||||
layer_digest: &str,
|
||||
decompressed_path: &PathBuf,
|
||||
client: &containerd_client::Client,
|
||||
) -> Result<()> {
|
||||
let compressed_path = get_compressed_path(decompressed_path);
|
||||
|
||||
if use_cached_files && compressed_path.exists() {
|
||||
info!("Using cached file {:?}", &compressed_path);
|
||||
} else {
|
||||
info!("Pulling layer {layer_digest}");
|
||||
let mut file = tokio::fs::File::create(&compressed_path)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
|
||||
info!("Decompressing layer");
|
||||
|
||||
let req = containerd_client::services::v1::ReadContentRequest {
|
||||
digest: layer_digest.to_string(),
|
||||
offset: 0,
|
||||
size: 0,
|
||||
};
|
||||
let req = with_namespace!(req, "k8s.io");
|
||||
let mut c = client.content();
|
||||
let resp = c.read(req).await?;
|
||||
let mut stream = resp.into_inner();
|
||||
|
||||
while let Some(chunk) = stream.message().await? {
|
||||
if chunk.offset < 0 {
|
||||
print!("oop")
|
||||
}
|
||||
file.seek(io::SeekFrom::Start(chunk.offset as u64)).await?;
|
||||
file.write_all(&chunk.data).await?;
|
||||
}
|
||||
|
||||
file.flush()
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))
|
||||
.expect("Failed to flush file");
|
||||
}
|
||||
let compressed_file = std::fs::File::open(compressed_path).map_err(|e| anyhow!(e))?;
|
||||
let mut decompressed_file = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(decompressed_path)?;
|
||||
let mut gz_decoder = flate2::read::GzDecoder::new(compressed_file);
|
||||
std::io::copy(&mut gz_decoder, &mut decompressed_file).map_err(|e| anyhow!(e))?;
|
||||
|
||||
info!("Adding tarfs index to layer");
|
||||
decompressed_file.seek(std::io::SeekFrom::Start(0))?;
|
||||
tarindex::append_index(&mut decompressed_file).map_err(|e| anyhow!(e))?;
|
||||
decompressed_file.flush().map_err(|e| anyhow!(e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -11,6 +11,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -45,8 +46,8 @@ struct ReplicaSetSpec {
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for ReplicaSet {
|
||||
async fn init(&mut self, use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
async fn init(&mut self, config: &Config, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -47,8 +48,8 @@ struct ReplicationControllerSpec {
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for ReplicationController {
|
||||
async fn init(&mut self, use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
async fn init(&mut self, config: &Config, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use crate::obj_meta;
|
||||
use crate::pod;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -73,7 +74,7 @@ pub fn get_value(value_from: &pod::EnvVarSource, secrets: &Vec<Secret>) -> Optio
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for Secret {
|
||||
async fn init(&mut self, _use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
async fn init(&mut self, _config: &Config, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ use crate::pod;
|
||||
use crate::pod_template;
|
||||
use crate::policy;
|
||||
use crate::settings;
|
||||
use crate::utils::Config;
|
||||
use crate::yaml;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -95,8 +96,8 @@ struct RollingUpdateStatefulSetStrategy {
|
||||
|
||||
#[async_trait]
|
||||
impl yaml::K8sResource for StatefulSet {
|
||||
async fn init(&mut self, use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, use_cache).await;
|
||||
async fn init(&mut self, config: &Config, doc_mapping: &serde_yaml::Value, _silent: bool) {
|
||||
yaml::k8s_resource_init(&mut self.spec.template.spec, config).await;
|
||||
self.doc_mapping = doc_mapping.clone();
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,17 @@ struct CommandLineOptions {
|
||||
help = "Ignore unsupported input Kubernetes YAML fields. This is not recommeded unless you understand exactly how genpolicy works!"
|
||||
)]
|
||||
silent_unsupported_fields: bool,
|
||||
|
||||
#[clap(
|
||||
short = 'd',
|
||||
long,
|
||||
help = "If specified, will use existing containerd service to pull container images. This option is only supported on Linux",
|
||||
// from https://docs.rs/clap/4.1.8/clap/struct.Arg.html#method.default_missing_value
|
||||
default_missing_value = "/var/run/containerd/containerd.sock", // used if flag is present but no value is given
|
||||
num_args = 0..=1,
|
||||
require_equals= true
|
||||
)]
|
||||
containerd_socket_path: Option<String>,
|
||||
}
|
||||
|
||||
/// Application configuration, derived from on command line parameters.
|
||||
@ -79,6 +90,7 @@ pub struct Config {
|
||||
pub silent_unsupported_fields: bool,
|
||||
pub raw_out: bool,
|
||||
pub base64_out: bool,
|
||||
pub containerd_socket_path: Option<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@ -105,6 +117,7 @@ impl Config {
|
||||
silent_unsupported_fields: args.silent_unsupported_fields,
|
||||
raw_out: args.raw_out,
|
||||
base64_out: args.base64_out,
|
||||
containerd_socket_path: args.containerd_socket_path,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use crate::replication_controller;
|
||||
use crate::secret;
|
||||
use crate::settings;
|
||||
use crate::stateful_set;
|
||||
use crate::utils::Config;
|
||||
use crate::volume;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@ -43,7 +44,7 @@ pub struct YamlHeader {
|
||||
pub trait K8sResource {
|
||||
async fn init(
|
||||
&mut self,
|
||||
use_cache: bool,
|
||||
config: &Config,
|
||||
doc_mapping: &serde_yaml::Value,
|
||||
silent_unsupported_fields: bool,
|
||||
);
|
||||
@ -216,17 +217,17 @@ pub fn get_yaml_header(yaml: &str) -> anyhow::Result<YamlHeader> {
|
||||
Ok(serde_yaml::from_str(yaml)?)
|
||||
}
|
||||
|
||||
pub async fn k8s_resource_init(spec: &mut pod::PodSpec, use_cache: bool) {
|
||||
pub async fn k8s_resource_init(spec: &mut pod::PodSpec, config: &Config) {
|
||||
for container in &mut spec.containers {
|
||||
container.init(use_cache).await;
|
||||
container.init(config).await;
|
||||
}
|
||||
|
||||
pod::add_pause_container(&mut spec.containers, use_cache).await;
|
||||
pod::add_pause_container(&mut spec.containers, config).await;
|
||||
|
||||
if let Some(init_containers) = &spec.initContainers {
|
||||
for container in init_containers {
|
||||
let mut new_container = container.clone();
|
||||
new_container.init(use_cache).await;
|
||||
new_container.init(config).await;
|
||||
spec.containers.insert(1, new_container);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user