diff --git a/KubeOS-Rust/Cargo.lock b/KubeOS-Rust/Cargo.lock index 08ad969e1521f7947ded4b4c8e7f7f85cd4c6867..bc0b38b1900924b15a26301215c83724a243cf9d 100644 --- a/KubeOS-Rust/Cargo.lock +++ b/KubeOS-Rust/Cargo.lock @@ -51,7 +51,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -77,6 +77,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "bitflags" version = "1.3.2" @@ -89,6 +95,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" version = "0.2.17" @@ -104,22 +119,6 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - [[package]] name = "bytes" version = "1.5.0" @@ -135,12 +134,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -174,15 +167,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -200,51 +184,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] -name = "crossbeam-deque" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "crossbeam-utils", - "lazy_static", - "maybe-uninit", - "memoffset 0.5.6", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" +name = "cpufeatures" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils", - "maybe-uninit", + "libc", ] [[package]] -name = "crossbeam-utils" -version = "0.7.2" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "lazy_static", + "generic-array", + "typenum", ] [[package]] @@ -288,7 +243,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "num_cpus", ] @@ -309,13 +264,23 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dirs-next" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -327,7 +292,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -354,7 +319,7 @@ version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -445,28 +410,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures" version = "0.3.29" @@ -556,13 +499,23 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -573,7 +526,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -597,7 +550,7 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" dependencies = [ - "bytes 1.5.0", + "bytes", "fnv", "futures-core", "futures-sink", @@ -605,7 +558,7 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.14.0", + "tokio", "tokio-util 0.7.2", "tracing", ] @@ -637,7 +590,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.5.0", + "bytes", "fnv", "itoa", ] @@ -648,7 +601,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.5.0", + "bytes", "http", "pin-project-lite", ] @@ -683,7 +636,7 @@ version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -695,12 +648,25 @@ dependencies = [ "itoa", "pin-project-lite", "socket2", - "tokio 1.14.0", + "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +dependencies = [ + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-timeout" version = "0.4.1" @@ -709,7 +675,7 @@ checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ "hyper", "pin-project-lite", - "tokio 1.14.0", + "tokio", "tokio-io-timeout", ] @@ -719,10 +685,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.5.0", + "bytes", "hyper", "native-tls", - "tokio 1.14.0", + "tokio", "tokio-native-tls", ] @@ -781,7 +747,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -795,15 +761,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.9.0" @@ -862,18 +819,20 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" dependencies = [ - "base64", + "base64 0.13.1", "serde", "serde_json", ] [[package]] name = "jsonrpc-core" -version = "15.1.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0745a6379e3edc893c84ec203589790774e4247420033e71a76d3ab4687991fa" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" dependencies = [ - "futures 0.1.31", + "futures", + "futures-executor", + "futures-util", "log", "serde", "serde_derive", @@ -882,9 +841,9 @@ dependencies = [ [[package]] name = "jsonrpc-derive" -version = "15.1.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99a847f9ec7bb52149b2786a17c9cb260d6effc6b8eeb8c16b343a487a7563a3" +checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -894,31 +853,34 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "15.1.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf50e53e4eea8f421a7316c5f63e395f7bc7c4e786a6dc54d76fab6ff7aa7ce7" +checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845" dependencies = [ + "futures", "jsonrpc-core", "jsonrpc-server-utils", "log", "parity-tokio-ipc", - "parking_lot 0.10.2", - "tokio-service", + "parking_lot", + "tower-service", ] [[package]] name = "jsonrpc-server-utils" -version = "15.1.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f1f3990650c033bd8f6bd46deac76d990f9bbfb5f8dc8c4767bf0a00392176" +checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" dependencies = [ - "bytes 0.4.12", + "bytes", + "futures", "globset", "jsonrpc-core", "lazy_static", "log", - "tokio 0.1.22", - "tokio-codec", + "tokio", + "tokio-stream", + "tokio-util 0.6.10", "unicase", ] @@ -928,8 +890,8 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f8de9873b904e74b3533f77493731ee26742418077503683db44e1b3c54aa5c" dependencies = [ - "base64", - "bytes 1.5.0", + "base64 0.13.1", + "bytes", "chrono", "http", "percent-encoding", @@ -939,16 +901,6 @@ dependencies = [ "url", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "kube" version = "0.66.0" @@ -968,12 +920,12 @@ version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "232db1af3d3680f9289cf0b4db51b2b9fee22550fc65d25869e39b23e0aaa696" dependencies = [ - "base64", - "bytes 1.5.0", + "base64 0.13.1", + "bytes", "chrono", "dirs-next", "either", - "futures 0.3.29", + "futures", "http", "http-body", "hyper", @@ -990,7 +942,7 @@ dependencies = [ "serde_json", "serde_yaml", "thiserror", - "tokio 1.14.0", + "tokio", "tokio-native-tls", "tokio-util 0.6.10", "tower", @@ -1038,16 +990,16 @@ dependencies = [ "backoff", "dashmap", "derivative", - "futures 0.3.29", + "futures", "json-patch", "k8s-openapi", "kube-client", "pin-project", "serde", "serde_json", - "smallvec 1.11.1", + "smallvec", "thiserror", - "tokio 1.14.0", + "tokio", "tokio-util 0.6.10", "tracing", ] @@ -1060,9 +1012,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libredox" @@ -1089,10 +1041,11 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.3.4" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ + "autocfg", "scopeguard", ] @@ -1102,7 +1055,7 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c4dcd960cc540667f619483fc99102f88d6118b87730e24e8fbe8054b7445e4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1117,32 +1070,19 @@ dependencies = [ "nix", "predicates", "regex", + "reqwest", "serde", "serde_json", + "sha2", "tempfile", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.7.1" @@ -1158,25 +1098,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow 0.2.2", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.7.14" @@ -1185,44 +1106,9 @@ checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", - "miow 0.3.7", + "miow", "ntapi", - "winapi 0.3.9", -] - -[[package]] -name = "mio-named-pipes" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" -dependencies = [ - "log", - "mio 0.6.23", - "miow 0.3.7", - "winapi 0.3.9", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio 0.6.23", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "winapi", ] [[package]] @@ -1231,7 +1117,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1240,7 +1126,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "downcast", "fragile", "lazy_static", @@ -1255,7 +1141,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "proc-macro2", "quote", "syn 1.0.109", @@ -1279,17 +1165,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "net2" -version = "0.2.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - [[package]] name = "nix" version = "0.26.4" @@ -1297,9 +1172,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", ] @@ -1315,7 +1190,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1350,7 +1225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ "bitflags 2.4.0", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -1415,71 +1290,41 @@ dependencies = [ [[package]] name = "parity-tokio-ipc" -version = "0.4.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf" +checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", + "futures", "libc", "log", - "mio-named-pipes", - "miow 0.3.7", "rand 0.7.3", - "tokio 0.1.22", - "tokio-named-pipes", - "tokio-uds", - "winapi 0.3.9", -] - -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api", - "parking_lot_core 0.6.3", - "rustc_version", + "tokio", + "winapi", ] [[package]] name = "parking_lot" -version = "0.10.2" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ + "instant", "lock_api", - "parking_lot_core 0.7.3", + "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.6.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version", - "smallvec 0.6.14", - "winapi 0.3.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93f386bb233083c799e6e642a9d73db98c24a5deeb95ffc85bf281255dffc98" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "cfg-if", + "instant", "libc", - "redox_syscall 0.1.57", - "smallvec 1.11.1", - "winapi 0.3.9", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -1488,7 +1333,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] @@ -1598,7 +1443,7 @@ dependencies = [ "chrono", "cli", "env_logger", - "futures 0.3.29", + "futures", "h2", "k8s-openapi", "kube", @@ -1612,7 +1457,7 @@ dependencies = [ "socket2", "thiserror", "thread_local", - "tokio 1.14.0", + "tokio", "tokio-retry", ] @@ -1698,9 +1543,12 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] [[package]] name = "redox_syscall" @@ -1750,12 +1598,12 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "reqwest" -version = "0.11.10" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64", - "bytes 1.5.0", + "base64 0.21.5", + "bytes", "encoding_rs", "futures-core", "futures-util", @@ -1763,31 +1611,46 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", - "lazy_static", "log", "mime", + "native-tls", + "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "tokio 1.14.0", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] [[package]] -name = "rustc_version" -version = "0.2.3" +name = "ring" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ - "semver", + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", ] [[package]] @@ -1804,6 +1667,37 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustls" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.15" @@ -1849,6 +1743,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "secrecy" version = "0.8.0" @@ -1882,21 +1786,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.188" @@ -1974,6 +1863,17 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1992,15 +1892,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.11.1" @@ -2014,9 +1905,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "strsim" version = "0.10.0" @@ -2052,7 +1949,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ "autocfg", - "cfg-if 1.0.0", + "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix", @@ -2118,30 +2015,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "mio 0.6.23", - "num_cpus", - "tokio-codec", - "tokio-current-thread", - "tokio-executor", - "tokio-fs", - "tokio-io", - "tokio-reactor", - "tokio-sync", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "tokio-udp", - "tokio-uds", -] - [[package]] name = "tokio" version = "1.14.0" @@ -2149,69 +2022,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" dependencies = [ "autocfg", - "bytes 1.5.0", + "bytes", "libc", "memchr", - "mio 0.7.14", + "mio", "num_cpus", "once_cell", "pin-project-lite", "signal-hook-registry", "tokio-macros", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "tokio-io", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" -dependencies = [ - "futures 0.1.31", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils", - "futures 0.1.31", -] - -[[package]] -name = "tokio-fs" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" -dependencies = [ - "futures 0.1.31", - "tokio-io", - "tokio-threadpool", -] - -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "log", + "winapi", ] [[package]] @@ -2221,7 +2041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ "pin-project-lite", - "tokio 1.14.0", + "tokio", ] [[package]] @@ -2235,19 +2055,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "tokio-named-pipes" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "mio 0.6.23", - "mio-named-pipes", - "tokio 0.1.22", -] - [[package]] name = "tokio-native-tls" version = "0.3.1" @@ -2255,26 +2062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.14.0", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils", - "futures 0.1.31", - "lazy_static", - "log", - "mio 0.6.23", - "num_cpus", - "parking_lot 0.9.0", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", + "tokio", ] [[package]] @@ -2285,102 +2073,28 @@ checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" dependencies = [ "pin-project", "rand 0.8.5", - "tokio 1.14.0", -] - -[[package]] -name = "tokio-service" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -dependencies = [ - "futures 0.1.31", -] - -[[package]] -name = "tokio-sync" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" -dependencies = [ - "fnv", - "futures 0.1.31", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "iovec", - "mio 0.6.23", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" -dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils", - "futures 0.1.31", - "lazy_static", - "log", - "num_cpus", - "slab", - "tokio-executor", + "tokio", ] [[package]] -name = "tokio-timer" -version = "0.2.13" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "crossbeam-utils", - "futures 0.1.31", - "slab", - "tokio-executor", + "rustls", + "tokio", ] [[package]] -name = "tokio-udp" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "log", - "mio 0.6.23", - "tokio-codec", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-uds" -version = "0.2.7" +name = "tokio-stream" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "iovec", - "libc", - "log", - "mio 0.6.23", - "mio-uds", - "tokio-codec", - "tokio-io", - "tokio-reactor", + "futures-core", + "pin-project-lite", + "tokio", ] [[package]] @@ -2389,13 +2103,13 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-core", "futures-sink", "log", "pin-project-lite", "slab", - "tokio 1.14.0", + "tokio", ] [[package]] @@ -2404,11 +2118,11 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-core", "futures-sink", "pin-project-lite", - "tokio 1.14.0", + "tokio", "tracing", ] @@ -2431,7 +2145,7 @@ dependencies = [ "futures-util", "pin-project", "pin-project-lite", - "tokio 1.14.0", + "tokio", "tokio-util 0.7.2", "tower-layer", "tower-service", @@ -2444,9 +2158,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" dependencies = [ - "base64", + "base64 0.13.1", "bitflags 1.3.2", - "bytes 1.5.0", + "bytes", "futures-core", "futures-util", "http", @@ -2476,7 +2190,7 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -2518,6 +2232,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicase" version = "2.7.0" @@ -2548,6 +2268,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.4.1" @@ -2598,7 +2324,7 @@ version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -2623,7 +2349,7 @@ version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -2669,10 +2395,23 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.2.8" +name = "webpki" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] [[package]] name = "winapi" @@ -2684,12 +2423,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2702,7 +2435,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2792,17 +2525,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] [[package]] diff --git a/KubeOS-Rust/Cargo.toml b/KubeOS-Rust/Cargo.toml index c1299f2dce7a8871899bf925257cde330bbb4774..135028f2ed58552587d27be0f96e143552c96a7d 100644 --- a/KubeOS-Rust/Cargo.toml +++ b/KubeOS-Rust/Cargo.toml @@ -1,16 +1,11 @@ [workspace] -members = [ - "manager", - "agent", - "cli", - "proxy", -] +members = ["agent", "cli", "manager", "proxy"] resolver = "2" [profile.release] -opt-level = 's' debug = false -rpath = false debug-assertions = false -overflow-checks = false lto = true +opt-level = 's' +overflow-checks = false +rpath = false diff --git a/KubeOS-Rust/agent/Cargo.toml b/KubeOS-Rust/agent/Cargo.toml index fd7d390575509ac99592138599136795fa60b169..6db4df45cf0ae088836867cbed6e76d0bd1e1fa5 100644 --- a/KubeOS-Rust/agent/Cargo.toml +++ b/KubeOS-Rust/agent/Cargo.toml @@ -1,20 +1,20 @@ [package] -name = "os-agent" -version = "0.1.0" -edition = "2021" -description = "KubeOS os-agent" -license = "MulanPSL-2.0" +description = "KubeOS os-agent" +edition = "2021" +license = "MulanPSL-2.0" +name = "os-agent" +version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -manager = { package = "manager", path = "../manager" } -jsonrpc-core = { version = "15.1" } -jsonrpc-derive = { version = "15.1" } -jsonrpc-ipc-server = { version = "15.1" } -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0" } -log = { version = "= 0.4.15" } -anyhow = { version = "1.0" } -env_logger = { version = "0.9" } -lazy_static = { version = "1.4" } -nix = { version = "0.26.2" } +anyhow = { version = "1.0" } +env_logger = { version = "0.9" } +jsonrpc-core = { version = "18.0" } +jsonrpc-derive = { version = "18.0" } +jsonrpc-ipc-server = { version = "18.0" } +lazy_static = { version = "1.4" } +log = { version = "= 0.4.15" } +manager = { package = "manager", path = "../manager" } +nix = { version = "0.26.2" } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0" } diff --git a/KubeOS-Rust/agent/src/function.rs b/KubeOS-Rust/agent/src/function.rs index 8fb8a4e36ae64a6e43a041446fe6aceea414a4ca..89775dce24322bbd9e6ecbd0858fb862fcdadf57 100644 --- a/KubeOS-Rust/agent/src/function.rs +++ b/KubeOS-Rust/agent/src/function.rs @@ -26,11 +26,7 @@ impl RpcFunction { { (f)().map_err(|e| { error!("{:?}", e); - Error { - code: ErrorCode::ServerError(RPC_OP_ERROR), - message: format!("{:?}", e), - data: None, - } + Error { code: ErrorCode::ServerError(RPC_OP_ERROR), message: format!("{:?}", e), data: None } }) } } diff --git a/KubeOS-Rust/agent/src/main.rs b/KubeOS-Rust/agent/src/main.rs index 2201c20296e4f61c3675e6667134ab26a8195469..cd95ef072e80731ff90f7a9cf2316919853b083d 100644 --- a/KubeOS-Rust/agent/src/main.rs +++ b/KubeOS-Rust/agent/src/main.rs @@ -35,10 +35,7 @@ fn start_and_run(sock_path: &str) { // Create directory for socket if it doesn't exist if let Some(dir_path) = socket_path.parent() { if !dir_path.exists() { - DirBuilder::new() - .mode(0o750) - .create(dir_path) - .expect("Couldn't create directory for socket"); + DirBuilder::new().mode(0o750).create(dir_path).expect("Couldn't create directory for socket"); } } @@ -51,8 +48,7 @@ fn start_and_run(sock_path: &str) { let server = builder.start(sock_path).expect("Couldn't open socket"); let gid = nix::unistd::getgid(); - nix::unistd::chown(socket_path, Some(nix::unistd::ROOT), Some(gid)) - .expect("Couldn't set socket group"); + nix::unistd::chown(socket_path, Some(nix::unistd::ROOT), Some(gid)).expect("Couldn't set socket group"); // Set socket permissions to 0640 let socket_permissions = Permissions::from_mode(0o640); @@ -63,13 +59,8 @@ fn start_and_run(sock_path: &str) { } fn main() { - Builder::from_env(Env::default().default_filter_or("info")) - .target(Target::Stdout) - .init(); + Builder::from_env(Env::default().default_filter_or("info")).target(Target::Stdout).init(); - info!( - "os-agent version is: {}", - CARGO_PKG_VERSION.unwrap_or("NOT FOUND") - ); + info!("os-agent version is: {}", CARGO_PKG_VERSION.unwrap_or("NOT FOUND")); start_and_run(SOCK_PATH); } diff --git a/KubeOS-Rust/agent/src/rpc/agent.rs b/KubeOS-Rust/agent/src/rpc/agent.rs index 97eb456682309e49f6f3186c58b5ce2058e83cf6..13775afbde0a588cac269e0d27f6827d92a78087 100644 --- a/KubeOS-Rust/agent/src/rpc/agent.rs +++ b/KubeOS-Rust/agent/src/rpc/agent.rs @@ -10,9 +10,10 @@ * See the Mulan PSL v2 for more details. */ -use super::function::{rpc, RpcResult}; use manager::api::{ConfigureRequest, Response, UpgradeRequest}; +use super::function::{rpc, RpcResult}; + #[rpc(server)] pub trait Agent { #[rpc(name = "prepare_upgrade")] diff --git a/KubeOS-Rust/agent/src/rpc/agent_impl.rs b/KubeOS-Rust/agent/src/rpc/agent_impl.rs index 95a2834814bcbd8f3586a48c7b5243044d497c40..7101d0db6572315fd890c364ba9188821e8acb62 100644 --- a/KubeOS-Rust/agent/src/rpc/agent_impl.rs +++ b/KubeOS-Rust/agent/src/rpc/agent_impl.rs @@ -12,21 +12,19 @@ use std::{sync::Mutex, thread, time::Duration}; -use anyhow::{anyhow, Result}; +use anyhow::{bail, Result}; use log::{debug, error, info}; +use manager::{ + api::{AgentStatus, ConfigureRequest, ImageType, Response, UpgradeRequest}, + sys_mgmt::{CtrImageHandler, DiskImageHandler, DockerImageHandler, CONFIG_TEMPLATE, DEFAULT_GRUBENV_PATH}, + utils::{clean_env, get_partition_info, switch_boot_menuentry, PreparePath, RealCommandExecutor}, +}; use nix::{sys::reboot::RebootMode, unistd::sync}; use super::{ agent::Agent, function::{RpcFunction, RpcResult}, }; -use manager::{ - api::{AgentStatus, ConfigureRequest, ImageType, Response, UpgradeRequest}, - sys_mgmt::{CtrImageHandler, CONFIG_TEMPLATE, DEFAULT_GRUBENV_PATH}, - utils::{ - clean_env, get_partition_info, switch_boot_menuentry, PreparePath, RealCommandExecutor, - }, -}; pub struct AgentImpl { mutex: Mutex<()>, @@ -57,10 +55,7 @@ impl Agent for AgentImpl { impl Default for AgentImpl { fn default() -> Self { - Self { - mutex: Mutex::new(()), - disable_reboot: false, - } + Self { mutex: Mutex::new(()), disable_reboot: false } } } @@ -72,19 +67,16 @@ impl AgentImpl { let handler: Box> = match req.image_type.as_str() { "containerd" => Box::new(ImageType::Containerd(CtrImageHandler::default())), - _ => return Err(anyhow!("Invalid image type \"{}\"", req.image_type)), + "docker" => Box::new(ImageType::Docker(DockerImageHandler::default())), + "disk" => Box::new(ImageType::Disk(DiskImageHandler::default())), + _ => bail!("Invalid image type \"{}\"", req.image_type), }; let image_manager = handler.download_image(&req)?; - info!( - "Ready to install image: {:?}", - image_manager.paths.image_path.display() - ); + info!("Ready to install image: {:?}", image_manager.paths.image_path.display()); image_manager.install()?; - Ok(Response { - status: AgentStatus::UpgradeReady, - }) + Ok(Response { status: AgentStatus::UpgradeReady }) } pub fn upgrade_impl(&self) -> Result { @@ -97,14 +89,9 @@ impl AgentImpl { let device = next_partition_info.device.as_str(); let menuentry = next_partition_info.menuentry.as_str(); switch_boot_menuentry(&command_executor, DEFAULT_GRUBENV_PATH, menuentry)?; - info!( - "Switch to boot partition: {}, device: {}", - menuentry, device - ); + info!("Switch to boot partition: {}, device: {}", menuentry, device); self.reboot()?; - Ok(Response { - status: AgentStatus::Upgraded, - }) + Ok(Response { status: AgentStatus::Upgraded }) } pub fn cleanup_impl(&self) -> Result { @@ -112,9 +99,7 @@ impl AgentImpl { info!("Start to cleanup"); let paths = PreparePath::default(); clean_env(paths.update_path, paths.mount_path, paths.image_path)?; - Ok(Response { - status: AgentStatus::CleanedUp, - }) + Ok(Response { status: AgentStatus::CleanedUp }) } pub fn configure_impl(&self, mut req: ConfigureRequest) -> Result { @@ -129,12 +114,10 @@ impl AgentImpl { configuration.set_config(config)?; } else { error!("Unknown configuration type: \"{}\"", config_type); - Err(anyhow!("Unknown configuration type: \"{}\"", config_type))?; + bail!("Unknown configuration type: \"{}\"", config_type); } } - Ok(Response { - status: AgentStatus::Configured, - }) + Ok(Response { status: AgentStatus::Configured }) } pub fn rollback_impl(&self) -> Result { @@ -147,14 +130,9 @@ impl AgentImpl { manager::sys_mgmt::DEFAULT_GRUBENV_PATH, &next_partition_info.menuentry, )?; - info!( - "Switch to boot partition: {}, device: {}", - next_partition_info.menuentry, next_partition_info.device - ); + info!("Switch to boot partition: {}, device: {}", next_partition_info.menuentry, next_partition_info.device); self.reboot()?; - Ok(Response { - status: AgentStatus::Rollbacked, - }) + Ok(Response { status: AgentStatus::Rollbacked }) } pub fn reboot(&self) -> Result<()> { @@ -171,10 +149,12 @@ impl AgentImpl { #[cfg(test)] mod test { - use super::*; - use manager::api::Sysconfig; use std::collections::HashMap; + use manager::api::{CertsInfo, Sysconfig}; + + use super::*; + #[test] fn configure_impl_tests() { let agent = AgentImpl::default(); @@ -186,12 +166,7 @@ mod test { }], }; let res = agent.configure_impl(req).unwrap(); - assert_eq!( - res, - Response { - status: AgentStatus::Configured, - } - ); + assert_eq!(res, Response { status: AgentStatus::Configured }); let req = ConfigureRequest { configs: vec![Sysconfig { @@ -217,6 +192,10 @@ mod test { check_sum: "xxx".into(), image_type: "xxx".into(), container_image: "xxx".into(), + image_url: "".to_string(), + flag_safe: false, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, }; let res = agent.prepare_upgrade_impl(req); assert!(res.is_err()); diff --git a/KubeOS-Rust/cli/Cargo.toml b/KubeOS-Rust/cli/Cargo.toml index 18ea908a9ee18ec2dcf749b2d2620bed78e7b9ef..1c46db366f84b124dd65ed796960395c3a182040 100644 --- a/KubeOS-Rust/cli/Cargo.toml +++ b/KubeOS-Rust/cli/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "cli" -version = "0.1.0" -edition = "2021" description = "KubeOS os-agent client" +edition = "2021" license = "MulanPSL-2.0" +name = "cli" +version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -kubeos-manager = { package = "manager", path = "../manager" } +anyhow = { version = "1.0" } jsonrpc = { version = "0.13", features = ["simple_uds"] } +kubeos-manager = { package = "manager", path = "../manager" } log = { version = "0.4" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } -anyhow = { version = "1.0" } diff --git a/KubeOS-Rust/cli/src/client.rs b/KubeOS-Rust/cli/src/client.rs index 71121fe0c0abb2fb061f1f5d69562d08058bc5dc..ce45cdd7143bc34ee11f3add2a8eddffa088a283 100644 --- a/KubeOS-Rust/cli/src/client.rs +++ b/KubeOS-Rust/cli/src/client.rs @@ -13,8 +13,7 @@ use std::path::Path; use jsonrpc::{ - simple_uds::UdsTransport, Client as JsonRPCClient, Request as JsonRPCRequest, - Response as JsonRPCResponse, + simple_uds::UdsTransport, Client as JsonRPCClient, Request as JsonRPCRequest, Response as JsonRPCResponse, }; use serde_json::value::RawValue; @@ -28,33 +27,26 @@ impl<'a> Request<'a> {} impl Client { pub fn new>(socket_path: P) -> Self { - let client = Client { - json_rpc_client: JsonRPCClient::with_transport(UdsTransport::new(socket_path)), - }; - client + Client { json_rpc_client: JsonRPCClient::with_transport(UdsTransport::new(socket_path)) } } - pub fn build_request<'a>( - &self, - command: &'a str, - params: &'a Vec>, - ) -> Request<'a> { - let json_rpc_request = self.json_rpc_client.build_request(command, ¶ms); + pub fn build_request<'a>(&self, command: &'a str, params: &'a Vec>) -> Request<'a> { + let json_rpc_request = self.json_rpc_client.build_request(command, params); let request = Request(json_rpc_request); request } pub fn send_request(&self, request: Request) -> Result { - let response = self.json_rpc_client.send_request(request.0); - response + self.json_rpc_client.send_request(request.0) } } #[cfg(test)] mod test { + use kubeos_manager::api; + use super::*; use crate::method::{callable_method::RpcMethod, configure::ConfigureMethod}; - use kubeos_manager::api; #[test] #[ignore] diff --git a/KubeOS-Rust/cli/src/method/callable_method.rs b/KubeOS-Rust/cli/src/method/callable_method.rs index d59ebd620bfa0a389f8616da0f167c43d0bc739b..c46614b4f5d50c3f7c1afa3f6452363d95568bf1 100644 --- a/KubeOS-Rust/cli/src/method/callable_method.rs +++ b/KubeOS-Rust/cli/src/method/callable_method.rs @@ -21,6 +21,6 @@ pub trait RpcMethod { fn command_params(&self) -> Vec>; fn call(&self, client: &Client) -> Result { let response = request(client, self.command_name(), self.command_params())?; - response.result().map_err(|e| parse_error(e)) + response.result().map_err(parse_error) } } diff --git a/KubeOS-Rust/cli/src/method/cleanup.rs b/KubeOS-Rust/cli/src/method/cleanup.rs index 48a03bc89f465f5aee58d4df8d398c1b5f42bac0..d1d7dbe2c5051ce995f06a282db13f915ebcd7b0 100644 --- a/KubeOS-Rust/cli/src/method/cleanup.rs +++ b/KubeOS-Rust/cli/src/method/cleanup.rs @@ -10,19 +10,14 @@ * See the Mulan PSL v2 for more details. */ +use kubeos_manager::api; use serde_json::value::RawValue; use crate::method::callable_method::RpcMethod; -use kubeos_manager::api; +#[derive(Default)] pub struct CleanupMethod {} -impl CleanupMethod { - pub fn new() -> Self { - CleanupMethod {} - } -} - impl RpcMethod for CleanupMethod { type Response = api::Response; fn command_name(&self) -> &'static str { diff --git a/KubeOS-Rust/cli/src/method/configure.rs b/KubeOS-Rust/cli/src/method/configure.rs index ddfeb05f90737328cfa02e07ff33e5596aabe65b..d1371068f5a6bb272e3ecf6b7efa3a3f1c58b2f8 100644 --- a/KubeOS-Rust/cli/src/method/configure.rs +++ b/KubeOS-Rust/cli/src/method/configure.rs @@ -10,10 +10,10 @@ * See the Mulan PSL v2 for more details. */ +use kubeos_manager::api; use serde_json::value::{to_raw_value, RawValue}; use crate::method::callable_method::RpcMethod; -use kubeos_manager::api; pub struct ConfigureMethod { req: api::ConfigureRequest, diff --git a/KubeOS-Rust/cli/src/method/prepare_upgrade.rs b/KubeOS-Rust/cli/src/method/prepare_upgrade.rs index dd3157df7cc2fb4a3d60eee5367e733a8cb95bd6..91dae7937ec9d7fdab3812aaf6507dec07e4d8d1 100644 --- a/KubeOS-Rust/cli/src/method/prepare_upgrade.rs +++ b/KubeOS-Rust/cli/src/method/prepare_upgrade.rs @@ -10,10 +10,10 @@ * See the Mulan PSL v2 for more details. */ +use kubeos_manager::api; use serde_json::value::{to_raw_value, RawValue}; use crate::method::callable_method::RpcMethod; -use kubeos_manager::api; pub struct PrepareUpgradeMethod { req: api::UpgradeRequest, diff --git a/KubeOS-Rust/cli/src/method/request.rs b/KubeOS-Rust/cli/src/method/request.rs index 4e3dbec6af196d4d98d5e6476fa332d9c293c673..2dc1ffba19485d202c11794c9fdbd1566dc8e65c 100644 --- a/KubeOS-Rust/cli/src/method/request.rs +++ b/KubeOS-Rust/cli/src/method/request.rs @@ -17,13 +17,9 @@ use serde_json::value::RawValue; use crate::client::Client; -pub fn request( - client: &Client, - command: &str, - params: Vec>, -) -> Result { +pub fn request(client: &Client, command: &str, params: Vec>) -> Result { let request = client.build_request(command, ¶ms); - let response = client.send_request(request).map_err(|e| parse_error(e)); + let response = client.send_request(request).map_err(parse_error); debug!("{:#?}", response); response } @@ -33,26 +29,24 @@ pub fn parse_error(error: Error) -> anyhow::Error { Error::Transport(e) => { anyhow!( "Cannot connect to KubeOS os-agent unix socket, {}", - e.source() - .map(|e| e.to_string()) - .unwrap_or_else(|| "Connection timeout".to_string()) + e.source().map(|e| e.to_string()).unwrap_or_else(|| "Connection timeout".to_string()) ) - } + }, Error::Json(e) => { debug!("Json parse error: {:?}", e); anyhow!("Failed to parse response") - } + }, Error::Rpc(ref e) => match e.message == "Method not found" { true => { anyhow!("Method is unimplemented") - } + }, false => { anyhow!("{}", e.message) - } + }, }, _ => { debug!("{:?}", error); anyhow!("Response is invalid") - } + }, } } diff --git a/KubeOS-Rust/cli/src/method/rollback.rs b/KubeOS-Rust/cli/src/method/rollback.rs index 5b9b0fde4d78bbe9d1d4b87c9a386a0589ad3403..55aa75116ae462a1e5cc59d02280578aea4e4e75 100644 --- a/KubeOS-Rust/cli/src/method/rollback.rs +++ b/KubeOS-Rust/cli/src/method/rollback.rs @@ -10,19 +10,14 @@ * See the Mulan PSL v2 for more details. */ +use kubeos_manager::api; use serde_json::value::RawValue; use crate::method::callable_method::RpcMethod; -use kubeos_manager::api; +#[derive(Default)] pub struct RollbackMethod {} -impl RollbackMethod { - pub fn new() -> Self { - RollbackMethod {} - } -} - impl RpcMethod for RollbackMethod { type Response = api::Response; fn command_name(&self) -> &'static str { diff --git a/KubeOS-Rust/cli/src/method/upgrade.rs b/KubeOS-Rust/cli/src/method/upgrade.rs index 9098e197e55ded16ae5eb6b9d43d5b24383545c0..a9692ca182a49de3f8e26cd01460bc569f3bb8cc 100644 --- a/KubeOS-Rust/cli/src/method/upgrade.rs +++ b/KubeOS-Rust/cli/src/method/upgrade.rs @@ -10,19 +10,14 @@ * See the Mulan PSL v2 for more details. */ +use kubeos_manager::api; use serde_json::value::RawValue; use crate::method::callable_method::RpcMethod; -use kubeos_manager::api; +#[derive(Default)] pub struct UpgradeMethod {} -impl UpgradeMethod { - pub fn new() -> Self { - UpgradeMethod {} - } -} - impl RpcMethod for UpgradeMethod { type Response = api::Response; fn command_name(&self) -> &'static str { diff --git a/KubeOS-Rust/manager/Cargo.toml b/KubeOS-Rust/manager/Cargo.toml index 0b82b17d9979c07c756bf728e01cac3bd3ac8b2f..29ec2f465d57fb4efeb772b02d019ee0dfc7def7 100644 --- a/KubeOS-Rust/manager/Cargo.toml +++ b/KubeOS-Rust/manager/Cargo.toml @@ -1,22 +1,24 @@ [package] -name = "manager" -version = "0.1.0" -edition = "2021" description = "KubeOS os-agent manager" +edition = "2021" license = "MulanPSL-2.0" +name = "manager" +version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] -tempfile = "3.6.0" mockall = { version = "=0.11.3" } predicates = "=2.0.1" +tempfile = "3.6.0" [dependencies] -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0" } -log = { version = "0.4" } anyhow = { version = "1.0" } env_logger = { version = "0.9" } lazy_static = { version = "1.4" } -regex = { version = "1.7.3" } +log = { version = "0.4" } nix = { version = "0.26.2" } +regex = { version = "1.7.3" } +reqwest = { version = "=0.11.18", features = ["blocking", "rustls-tls"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0" } +sha2 = { version = "0.10.8" } diff --git a/KubeOS-Rust/manager/src/api/types.rs b/KubeOS-Rust/manager/src/api/types.rs index e21f55bffacea758b452c2f6f5095d54c8d35492..28ee97dbf8038800707464d3f33da63ab02ddf5f 100644 --- a/KubeOS-Rust/manager/src/api/types.rs +++ b/KubeOS-Rust/manager/src/api/types.rs @@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize}; use super::agent_status::*; use crate::{ - sys_mgmt::CtrImageHandler, + sys_mgmt::{CtrImageHandler, DiskImageHandler, DockerImageHandler}, utils::{CommandExecutor, UpgradeImageManager}, }; @@ -26,6 +26,17 @@ pub struct UpgradeRequest { pub check_sum: String, pub image_type: String, pub container_image: String, + pub image_url: String, + pub flag_safe: bool, + pub mtls: bool, + pub certs: CertsInfo, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct CertsInfo { + pub ca_cert: String, + pub client_cert: String, + pub client_key: String, } #[derive(Deserialize, Serialize, Debug)] @@ -53,12 +64,16 @@ pub struct Response { pub enum ImageType { Containerd(CtrImageHandler), + Docker(DockerImageHandler), + Disk(DiskImageHandler), } impl ImageType { pub fn download_image(&self, req: &UpgradeRequest) -> anyhow::Result> { match self { ImageType::Containerd(handler) => handler.download_image(req), + ImageType::Docker(handler) => handler.download_image(req), + ImageType::Disk(handler) => handler.download_image(req), } } } diff --git a/KubeOS-Rust/manager/src/sys_mgmt/config.rs b/KubeOS-Rust/manager/src/sys_mgmt/config.rs index deec26eabd336079b32fdc1a46cefe847ae5744b..cb5fad1f070b1afa6efe37f155093af7631637bd 100644 --- a/KubeOS-Rust/manager/src/sys_mgmt/config.rs +++ b/KubeOS-Rust/manager/src/sys_mgmt/config.rs @@ -19,13 +19,12 @@ use std::{ string::String, }; -use anyhow::{anyhow, Context, Ok, Result}; +use anyhow::{bail, Context, Result}; use lazy_static::lazy_static; use log::{debug, info, trace, warn}; use regex::Regex; -use super::{api::*, values}; -use crate::utils::*; +use crate::{api::*, sys_mgmt::values, utils::*}; lazy_static! { pub static ref CONFIG_TEMPLATE: HashMap> = { @@ -40,17 +39,13 @@ lazy_static! { ); config_map.insert( values::GRUB_CMDLINE_CURRENT.to_string(), - Box::new(GrubCmdline { - grub_path: values::DEFAULT_GRUB_CFG_PATH.to_string(), - is_cur_partition: true, - }) as Box, + Box::new(GrubCmdline { grub_path: values::DEFAULT_GRUB_CFG_PATH.to_string(), is_cur_partition: true }) + as Box, ); config_map.insert( values::GRUB_CMDLINE_NEXT.to_string(), - Box::new(GrubCmdline { - grub_path: values::DEFAULT_GRUB_CFG_PATH.to_string(), - is_cur_partition: false, - }) as Box, + Box::new(GrubCmdline { grub_path: values::DEFAULT_GRUB_CFG_PATH.to_string(), is_cur_partition: false }) + as Box, ); config_map }; @@ -76,10 +71,9 @@ impl Configuration for KernelSysctl { let proc_path = self.get_proc_path(key); if key_info.operation == "delete" { warn!("Failed to delete kernel.sysctl config with key \"{}\"", key); - } else if key_info.value != "" && key_info.operation == "" { - fs::write(&proc_path, format!("{}\n", &key_info.value).as_bytes()).with_context( - || format!("Failed to write kernel.sysctl with key: \"{}\"", key), - )?; + } else if !key_info.value.is_empty() && key_info.operation.is_empty() { + fs::write(&proc_path, format!("{}\n", &key_info.value).as_bytes()) + .with_context(|| format!("Failed to write kernel.sysctl with key: \"{}\"", key))?; info!("Configured kernel.sysctl {}={}", key, key_info.value); } else { warn!( @@ -94,13 +88,11 @@ impl Configuration for KernelSysctl { impl KernelSysctl { fn new(proc_path: &str) -> Self { - Self { - proc_path: String::from(proc_path), - } + Self { proc_path: String::from(proc_path) } } fn get_proc_path(&self, key: &str) -> PathBuf { - let path_str = format!("{}{}", self.proc_path, key.replace(".", "/")); + let path_str = format!("{}{}", self.proc_path, key.replace('.', "/")); Path::new(&path_str).to_path_buf() } } @@ -109,7 +101,7 @@ impl Configuration for KernelSysctlPersist { fn set_config(&self, config: &mut Sysconfig) -> Result<()> { info!("Start set kernel.sysctl.persist"); let mut config_path = &values::DEFAULT_KERNEL_CONFIG_PATH.to_string(); - if config.config_path != "" { + if !config.config_path.is_empty() { config_path = &config.config_path; } debug!("kernel.sysctl.persist config_path: \"{}\"", config_path); @@ -131,29 +123,24 @@ fn create_config_file(config_path: &str) -> Result<()> { Ok(()) } -fn get_and_set_configs( - expect_configs: &mut HashMap, - config_path: &str, -) -> Result> { +fn get_and_set_configs(expect_configs: &mut HashMap, config_path: &str) -> Result> { let f = File::open(config_path)?; let mut configs_write = Vec::new(); for line in io::BufReader::new(f).lines() { let line = line?; // if line is a comment or blank - if line.starts_with("#") || line.starts_with(";") || line.trim().is_empty() { + if line.starts_with('#') || line.starts_with(';') || line.trim().is_empty() { configs_write.push(line); continue; } let config_kv: Vec<&str> = line.splitn(2, '=').map(|s| s.trim()).collect(); // if config_kv is not a key-value pair if config_kv.len() != 2 { - return Err(anyhow!("could not parse sysctl config {}", line)); + bail!("could not parse sysctl config {}", line); } let new_key_info = expect_configs.get(config_kv[0]); let new_config = match new_key_info { - Some(new_key_info) if new_key_info.operation == "delete" => { - handle_delete_key(&config_kv, new_key_info) - } + Some(new_key_info) if new_key_info.operation == "delete" => handle_delete_key(&config_kv, new_key_info), Some(new_key_info) => handle_update_key(&config_kv, new_key_info), None => config_kv.join("="), }; @@ -170,30 +157,24 @@ fn write_configs_to_file(config_path: &str, configs: &Vec) -> Result<()> let f = File::create(config_path)?; let mut w = BufWriter::new(f); for line in configs { - if line == "" { + if line.is_empty() { continue; } writeln!(w, "{}", line.as_str())?; } - w.flush() - .with_context(|| format!("Failed to flush file {}", config_path))?; - w.get_mut() - .sync_all() - .with_context(|| format!("Failed to sync"))?; + w.flush().with_context(|| format!("Failed to flush file {}", config_path))?; + w.get_mut().sync_all().with_context(|| "Failed to sync".to_string())?; debug!("Write configuration to file \"{}\" success", config_path); Ok(()) } fn handle_delete_key(config_kv: &Vec<&str>, new_config_info: &KeyInfo) -> String { let key = config_kv[0]; - if config_kv.len() == 1 && new_config_info.value == "" { + if config_kv.len() == 1 && new_config_info.value.is_empty() { info!("Delete configuration key: \"{}\"", key); return String::from(""); - } else if config_kv.len() == 1 && new_config_info.value != "" { - warn!( - "Failed to delete key \"{}\" with inconsistent values \"nil\" and \"{}\"", - key, new_config_info.value - ); + } else if config_kv.len() == 1 && !new_config_info.value.is_empty() { + warn!("Failed to delete key \"{}\" with inconsistent values \"nil\" and \"{}\"", key, new_config_info.value); return key.to_string(); } let old_value = config_kv[1]; @@ -210,21 +191,21 @@ fn handle_delete_key(config_kv: &Vec<&str>, new_config_info: &KeyInfo) -> String fn handle_update_key(config_kv: &Vec<&str>, new_config_info: &KeyInfo) -> String { let key = config_kv[0]; - if new_config_info.operation != "" { + if !new_config_info.operation.is_empty() { warn!( "Unknown operation \"{}\", updating key \"{}\" with value \"{}\" by default", new_config_info.operation, key, new_config_info.value ); } - if config_kv.len() == values::ONLY_KEY && new_config_info.value == "" { + if config_kv.len() == values::ONLY_KEY && new_config_info.value.is_empty() { return key.to_string(); } let new_value = new_config_info.value.trim(); - if config_kv.len() == values::ONLY_KEY && new_config_info.value != "" { + if config_kv.len() == values::ONLY_KEY && !new_config_info.value.is_empty() { info!("Update configuration \"{}={}\"", key, new_value); return format!("{}={}", key, new_value); } - if new_config_info.value == "" { + if new_config_info.value.is_empty() { warn!("Failed to update key \"{}\" with \"null\" value", key); return config_kv.join("="); } @@ -232,34 +213,28 @@ fn handle_update_key(config_kv: &Vec<&str>, new_config_info: &KeyInfo) -> String format!("{}={}", key, new_value) } -fn handle_add_key( - expect_configs: &HashMap, - is_only_key_valid: bool, -) -> Vec { +fn handle_add_key(expect_configs: &HashMap, is_only_key_valid: bool) -> Vec { let mut configs_write = Vec::new(); for (key, config_info) in expect_configs.iter() { if config_info.operation == "delete" { warn!("Failed to delete inexistent key: \"{}\"", key); continue; } - if key == "" || key.contains("=") { - warn!( - "Failed to add \"null\" key or key containing \"=\", key: \"{}\"", - key - ); + if key.is_empty() || key.contains('=') { + warn!("Failed to add \"null\" key or key containing \"=\", key: \"{}\"", key); continue; } - if config_info.operation != "" { + if !config_info.operation.is_empty() { warn!( "Unknown operation \"{}\", adding key \"{}\" with value \"{}\" by default", config_info.operation, key, config_info.value ); } let (k, v) = (key.trim(), config_info.value.trim()); - if v == "" && is_only_key_valid { + if v.is_empty() && is_only_key_valid { info!("Add configuration \"{}\"", k); configs_write.push(k.to_string()); - } else if v == "" { + } else if v.is_empty() { warn!("Failed to add key \"{}\" with \"null\" value", k); } else { info!("Add configuration \"{}={}\"", k, v); @@ -277,17 +252,11 @@ impl Configuration for GrubCmdline { info!("Start set grub.cmdline.next configuration"); } if !is_file_exist(&self.grub_path) { - return Err(anyhow!("Failed to find grub.cfg file")); + bail!("Failed to find grub.cfg file"); } - let config_partition = if cfg!(test) { - self.is_cur_partition - } else { - self.get_config_partition(RealCommandExecutor {})? - }; - debug!( - "Config_partition: {} (false means partition A, true means partition B)", - config_partition - ); + let config_partition = + if cfg!(test) { self.is_cur_partition } else { self.get_config_partition(RealCommandExecutor {})? }; + debug!("Config_partition: {} (false means partition A, true means partition B)", config_partition); let configs = get_and_set_grubcfg(&mut config.contents, &self.grub_path, config_partition)?; write_configs_to_file(&self.grub_path, &configs)?; Ok(()) @@ -330,29 +299,21 @@ fn get_and_set_grubcfg( } fn modify_boot_cfg(expect_configs: &mut HashMap, line: &String) -> Result { - trace!( - "Match partition that need to be configured, entering modify_boot_cfg, linux line: {}", - line - ); + trace!("Match partition that need to be configured, entering modify_boot_cfg, linux line: {}", line); let mut new_configs = vec![" ".to_string()]; let olg_configs: Vec<&str> = line.split(' ').collect(); for old_config in olg_configs { - if old_config == "" { + if old_config.is_empty() { continue; } // At most 2 substrings can be returned to satisfy the case like root=UUID=xxxx - let config = old_config.splitn(2, "=").collect::>(); + let config = old_config.splitn(2, '=').collect::>(); if config.len() != values::ONLY_KEY && config.len() != values::KV_PAIR { - return Err(anyhow!( - "Failed to parse grub.cfg linux line {}", - old_config - )); + bail!("Failed to parse grub.cfg linux line {}", old_config); } let new_key_info = expect_configs.get(config[0]); let new_config = match new_key_info { - Some(new_key_info) if new_key_info.operation == "delete" => { - handle_delete_key(&config, new_key_info) - } + Some(new_key_info) if new_key_info.operation == "delete" => handle_delete_key(&config, new_key_info), Some(new_key_info) => handle_update_key(&config, new_key_info), None => config.join("="), }; @@ -368,14 +329,14 @@ fn modify_boot_cfg(expect_configs: &mut HashMap, line: &String) #[cfg(test)] mod tests { - use super::*; - use crate::sys_mgmt::{ - GRUB_CMDLINE_CURRENT, GRUB_CMDLINE_NEXT, KERNEL_SYSCTL, KERNEL_SYSCTL_PERSIST, - }; - use mockall::{mock, predicate::*}; use std::fs; + + use mockall::{mock, predicate::*}; use tempfile::{NamedTempFile, TempDir}; + use super::*; + use crate::sys_mgmt::{GRUB_CMDLINE_CURRENT, GRUB_CMDLINE_NEXT, KERNEL_SYSCTL, KERNEL_SYSCTL_PERSIST}; + // Mock the CommandExecutor trait mock! { pub CommandExec{} @@ -399,19 +360,12 @@ mod tests { #[test] fn test_get_config_partition() { init(); - let mut grub_cmdline = GrubCmdline { - grub_path: String::from(""), - is_cur_partition: true, - }; + let mut grub_cmdline = GrubCmdline { grub_path: String::from(""), is_cur_partition: true }; let mut executor = MockCommandExec::new(); // the output shows that current root menuentry is A - let command_output1 = - "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; - executor - .expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output1.to_string())); + let command_output1 = "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; + executor.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output1.to_string())); let result = grub_cmdline.get_config_partition(executor).unwrap(); // it should return false because the current root menuentry is A and we want to configure current partition @@ -420,12 +374,8 @@ mod tests { let mut executor = MockCommandExec::new(); // the output shows that current root menuentry is A - let command_output1 = - "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; - executor - .expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output1.to_string())); + let command_output1 = "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; + executor.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output1.to_string())); grub_cmdline.is_cur_partition = false; let result = grub_cmdline.get_config_partition(executor).unwrap(); // it should return true because the current root menuentry is A and we want to configure next partition @@ -440,52 +390,18 @@ mod tests { let kernel_sysctl = KernelSysctl::new(tmp_dir.path().to_str().unwrap()); let config_detail = HashMap::from([ - ( - "a".to_string(), - KeyInfo { - value: "1".to_string(), - operation: "".to_string(), - }, - ), - ( - "b".to_string(), - KeyInfo { - value: "2".to_string(), - operation: "delete".to_string(), - }, - ), - ( - "c".to_string(), - KeyInfo { - value: "3".to_string(), - operation: "add".to_string(), - }, - ), - ( - "d".to_string(), - KeyInfo { - value: "".to_string(), - operation: "".to_string(), - }, - ), - ( - "e".to_string(), - KeyInfo { - value: "".to_string(), - operation: "delete".to_string(), - }, - ), + ("a".to_string(), KeyInfo { value: "1".to_string(), operation: "".to_string() }), + ("b".to_string(), KeyInfo { value: "2".to_string(), operation: "delete".to_string() }), + ("c".to_string(), KeyInfo { value: "3".to_string(), operation: "add".to_string() }), + ("d".to_string(), KeyInfo { value: "".to_string(), operation: "".to_string() }), + ("e".to_string(), KeyInfo { value: "".to_string(), operation: "delete".to_string() }), ]); - let mut config = Sysconfig { - model: KERNEL_SYSCTL.to_string(), - config_path: String::from(""), - contents: config_detail, - }; + let mut config = + Sysconfig { model: KERNEL_SYSCTL.to_string(), config_path: String::from(""), contents: config_detail }; kernel_sysctl.set_config(&mut config).unwrap(); - let result = - fs::read_to_string(format!("{}{}", tmp_dir.path().to_str().unwrap(), "a")).unwrap(); + let result = fs::read_to_string(format!("{}{}", tmp_dir.path().to_str().unwrap(), "a")).unwrap(); assert_eq!(result, "1\n"); } @@ -499,27 +415,9 @@ mod tests { writeln!(tmp_file, "a=0").unwrap(); let kernel_sysctl_persist = KernelSysctlPersist {}; let config_detail = HashMap::from([ - ( - "a".to_string(), - KeyInfo { - value: "1".to_string(), - operation: "".to_string(), - }, - ), - ( - "b".to_string(), - KeyInfo { - value: "2".to_string(), - operation: "delete".to_string(), - }, - ), - ( - "c".to_string(), - KeyInfo { - value: "3".to_string(), - operation: "add".to_string(), - }, - ), + ("a".to_string(), KeyInfo { value: "1".to_string(), operation: "".to_string() }), + ("b".to_string(), KeyInfo { value: "2".to_string(), operation: "delete".to_string() }), + ("c".to_string(), KeyInfo { value: "3".to_string(), operation: "add".to_string() }), ]); let mut config = Sysconfig { model: KERNEL_SYSCTL_PERSIST.to_string(), @@ -560,19 +458,18 @@ mod tests { #[test] fn write_configs_to_file_tests() { init(); - let path = "/home/yuhang/abc.txt"; + let tmp_file = NamedTempFile::new().unwrap(); let configs = vec!["a=1".to_string(), "b=2".to_string()]; - write_configs_to_file(&path.to_string(), &configs).unwrap(); + write_configs_to_file(tmp_file.path().to_str().unwrap(), &configs).unwrap(); + assert_eq!(fs::read(tmp_file.path()).unwrap(), b"a=1\nb=2\n"); } #[test] fn test_grub_cmdline() { init(); let mut tmp_file = NamedTempFile::new().unwrap(); - let mut grub_cmdline = GrubCmdline { - grub_path: tmp_file.path().to_str().unwrap().to_string(), - is_cur_partition: true, - }; + let mut grub_cmdline = + GrubCmdline { grub_path: tmp_file.path().to_str().unwrap().to_string(), is_cur_partition: true }; let grub_cfg = r"menuentry 'A' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-A' { load_video set gfxpayload=keep @@ -596,69 +493,15 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri }"; writeln!(tmp_file, "{}", grub_cfg).unwrap(); let config_first_part = HashMap::from([ - ( - "debug".to_string(), - KeyInfo { - value: "".to_string(), - operation: "".to_string(), - }, - ), - ( - "quiet".to_string(), - KeyInfo { - value: "".to_string(), - operation: "delete".to_string(), - }, - ), - ( - "panic".to_string(), - KeyInfo { - value: "5".to_string(), - operation: "".to_string(), - }, - ), - ( - "nomodeset".to_string(), - KeyInfo { - value: "".to_string(), - operation: "update".to_string(), - }, - ), - ( - "oops".to_string(), - KeyInfo { - value: "".to_string(), - operation: "".to_string(), - }, - ), - ( - "".to_string(), - KeyInfo { - value: "test".to_string(), - operation: "".to_string(), - }, - ), - ( - "selinux".to_string(), - KeyInfo { - value: "1".to_string(), - operation: "delete".to_string(), - }, - ), - ( - "acpi".to_string(), - KeyInfo { - value: "off".to_string(), - operation: "delete".to_string(), - }, - ), - ( - "ro".to_string(), - KeyInfo { - value: "1".to_string(), - operation: "".to_string(), - }, - ), + ("debug".to_string(), KeyInfo { value: "".to_string(), operation: "".to_string() }), + ("quiet".to_string(), KeyInfo { value: "".to_string(), operation: "delete".to_string() }), + ("panic".to_string(), KeyInfo { value: "5".to_string(), operation: "".to_string() }), + ("nomodeset".to_string(), KeyInfo { value: "".to_string(), operation: "update".to_string() }), + ("oops".to_string(), KeyInfo { value: "".to_string(), operation: "".to_string() }), + ("".to_string(), KeyInfo { value: "test".to_string(), operation: "".to_string() }), + ("selinux".to_string(), KeyInfo { value: "1".to_string(), operation: "delete".to_string() }), + ("acpi".to_string(), KeyInfo { value: "off".to_string(), operation: "delete".to_string() }), + ("ro".to_string(), KeyInfo { value: "1".to_string(), operation: "".to_string() }), ]); let mut config = Sysconfig { model: GRUB_CMDLINE_CURRENT.to_string(), @@ -668,20 +511,8 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri grub_cmdline.set_config(&mut config).unwrap(); grub_cmdline.is_cur_partition = false; let config_second = HashMap::from([ - ( - "pci".to_string(), - KeyInfo { - value: "nomis".to_string(), - operation: "".to_string(), - }, - ), - ( - "panic".to_string(), - KeyInfo { - value: "5".to_string(), - operation: "".to_string(), - }, - ), + ("pci".to_string(), KeyInfo { value: "nomis".to_string(), operation: "".to_string() }), + ("panic".to_string(), KeyInfo { value: "5".to_string(), operation: "".to_string() }), ]); config.contents = config_second; config.model = GRUB_CMDLINE_NEXT.to_string(); diff --git a/KubeOS-Rust/manager/src/sys_mgmt/containerd_image.rs b/KubeOS-Rust/manager/src/sys_mgmt/containerd_image.rs index 479740e4b476e7ed371bc0dc02857ba0b7a25c7f..6ed3623a14469d6840a3b6cf8e2c7ac47f919217 100644 --- a/KubeOS-Rust/manager/src/sys_mgmt/containerd_image.rs +++ b/KubeOS-Rust/manager/src/sys_mgmt/containerd_image.rs @@ -15,9 +15,11 @@ use std::{fs, os::unix::fs::PermissionsExt, path::Path}; use anyhow::{anyhow, Result}; use log::{debug, info}; -use super::api::{ImageHandler, UpgradeRequest}; -use crate::sys_mgmt::{IMAGE_PERMISSION, NEED_GB_SIZE, PERSIST_DIR}; -use crate::utils::*; +use crate::{ + api::{ImageHandler, UpgradeRequest}, + sys_mgmt::{IMAGE_PERMISSION, NEED_BYTES, PERSIST_DIR}, + utils::*, +}; pub struct CtrImageHandler { pub paths: PreparePath, @@ -28,26 +30,19 @@ const DEFAULT_NAMESPACE: &str = "k8s.io"; impl ImageHandler for CtrImageHandler { fn download_image(&self, req: &UpgradeRequest) -> Result> { - perpare_env(&self.paths, NEED_GB_SIZE, PERSIST_DIR, IMAGE_PERMISSION)?; + perpare_env(&self.paths, NEED_BYTES, PERSIST_DIR, IMAGE_PERMISSION)?; self.get_image(req)?; self.get_rootfs_archive(req, IMAGE_PERMISSION)?; let (_, next_partition_info) = get_partition_info(&self.executor)?; - let img_manager = UpgradeImageManager::new( - self.paths.clone(), - next_partition_info, - self.executor.clone(), - ); + let img_manager = UpgradeImageManager::new(self.paths.clone(), next_partition_info, self.executor.clone()); img_manager.create_os_image(IMAGE_PERMISSION) } } impl Default for CtrImageHandler { fn default() -> Self { - Self { - paths: PreparePath::default(), - executor: RealCommandExecutor {}, - } + Self { paths: PreparePath::default(), executor: RealCommandExecutor {} } } } @@ -60,90 +55,47 @@ impl CtrImageHandler { fn get_image(&self, req: &UpgradeRequest) -> Result<()> { let image_name = &req.container_image; is_valid_image_name(image_name)?; + let cli: String = + if is_command_available("crictl", &self.executor) { "crictl".to_string() } else { "ctr".to_string() }; + remove_image_if_exist(&cli, image_name, &self.executor)?; info!("Start pulling image {}", image_name); - let containerd_command: String; - if is_command_available("crictl", &self.executor) { - containerd_command = "crictl".to_string(); - } else { - containerd_command = "ctr".to_string(); - } - pull_image(&containerd_command, image_name, &self.executor)?; + pull_image(&cli, image_name, &self.executor)?; info!("Start checking image digest"); - check_oci_image_digest_match( - &containerd_command, - image_name, - &req.check_sum, - &self.executor, - )?; + check_oci_image_digest(&cli, image_name, &req.check_sum, &self.executor)?; Ok(()) } fn get_rootfs_archive(&self, req: &UpgradeRequest, permission: u32) -> Result<()> { let image_name = &req.container_image; - let mount_path = &self.paths.mount_path.to_str().ok_or_else(|| { - anyhow!( - "Failed to get mount path: {}", - self.paths.mount_path.display() - ) - })?; + let mount_path = &self + .paths + .mount_path + .to_str() + .ok_or_else(|| anyhow!("Failed to get mount path: {}", self.paths.mount_path.display()))?; info!("Start get rootfs {}", image_name); self.check_and_unmount(mount_path)?; - self.executor.run_command( - "ctr", - &[ - "-n", - DEFAULT_NAMESPACE, - "images", - "mount", - "--rw", - image_name, - mount_path, - ], - )?; + self.executor + .run_command("ctr", &["-n", DEFAULT_NAMESPACE, "images", "mount", "--rw", image_name, mount_path])?; // copy os.tar from mount_path to its partent dir - self.copy_file( - &self.paths.mount_path.join(&self.paths.rootfs_file), - &self.paths.tar_path, - permission, - )?; + self.copy_file(self.paths.mount_path.join(&self.paths.rootfs_file), &self.paths.tar_path, permission)?; self.check_and_unmount(mount_path)?; Ok(()) } fn check_and_unmount(&self, mount_path: &str) -> Result<()> { - let ctr_snapshot_cmd = format!( - "ctr -n={} snapshots ls | grep {} | awk '{{print $1}}'", - DEFAULT_NAMESPACE, mount_path - ); - let exist_snapshot = self - .executor - .run_command_with_output("bash", &["-c", &ctr_snapshot_cmd])?; + let ctr_snapshot_cmd = + format!("ctr -n={} snapshots ls | grep {} | awk '{{print $1}}'", DEFAULT_NAMESPACE, mount_path); + let exist_snapshot = self.executor.run_command_with_output("bash", &["-c", &ctr_snapshot_cmd])?; if !exist_snapshot.is_empty() { - self.executor.run_command( - "ctr", - &["-n", DEFAULT_NAMESPACE, "images", "unmount", mount_path], - )?; - self.executor.run_command( - "ctr", - &["-n", DEFAULT_NAMESPACE, "snapshots", "remove", mount_path], - )?; + self.executor.run_command("ctr", &["-n", DEFAULT_NAMESPACE, "images", "unmount", mount_path])?; + self.executor.run_command("ctr", &["-n", DEFAULT_NAMESPACE, "snapshots", "remove", mount_path])?; } Ok(()) } - fn copy_file, Q: AsRef>( - &self, - src: P, - dst: Q, - permission: u32, - ) -> Result<()> { + fn copy_file, Q: AsRef>(&self, src: P, dst: Q, permission: u32) -> Result<()> { let copied_bytes = fs::copy(src.as_ref(), dst.as_ref())?; - debug!( - "Copy {} to {}, total bytes: {}", - src.as_ref().display(), - dst.as_ref().display(), - copied_bytes - ); + debug!("Copy {} to {}, total bytes: {}", src.as_ref().display(), dst.as_ref().display(), copied_bytes); fs::set_permissions(dst, fs::Permissions::from_mode(permission))?; Ok(()) } @@ -151,13 +103,17 @@ impl CtrImageHandler { #[cfg(test)] mod tests { - use super::*; + use std::{ + io::Write, + path::{Path, PathBuf}, + }; + use mockall::mock; - use std::io::Write; - use std::path::Path; - use std::path::PathBuf; use tempfile::NamedTempFile; + use super::*; + use crate::api::CertsInfo; + mock! { pub CommandExec{} impl CommandExecutor for CommandExec { @@ -187,6 +143,10 @@ mod tests { image_type: "containerd".to_string(), container_image: image_name.to_string(), check_sum: "22222".to_string(), + image_url: "".to_string(), + flag_safe: false, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, }; // mock is_command_available mock_executor @@ -194,13 +154,22 @@ mod tests { .withf(|cmd, args| cmd == "/bin/sh" && args.contains(&"command -v crictl")) // simplified with a closure .times(1) .returning(|_, _| Ok(())); + // mock remove_image_if_exist + mock_executor + .expect_run_command() + .withf(|cmd, args| cmd == "crictl" && args.contains(&"inspecti")) // simplified with a closure + .times(1) + .returning(|_, _| Ok(())); + mock_executor + .expect_run_command() + .withf(|cmd, args| cmd == "crictl" && args.contains(&"rmi")) // simplified with a closure + .times(1) + .returning(|_, _| Ok(())); // mock pull_image mock_executor .expect_run_command() .withf(|cmd, args| { - cmd == "crictl" - && args.contains(&"pull") - && args.contains(&"docker.io/library/busybox:latest") + cmd == "crictl" && args.contains(&"pull") && args.contains(&"docker.io/library/busybox:latest") }) .times(1) .returning(|_, _| Ok(())); @@ -209,9 +178,7 @@ mod tests { mock_executor .expect_run_command_with_output() .withf(|cmd, args| { - cmd == "crictl" - && args.contains(&"inspecti") - && args.contains(&"{{.status.repoDigests}}") + cmd == "crictl" && args.contains(&"inspecti") && args.contains(&"{{.status.repoDigests}}") }) .times(1) .returning(|_, _| Ok(command_output2.to_string())); @@ -230,6 +197,10 @@ mod tests { image_type: "containerd".to_string(), container_image: image_name.to_string(), check_sum: "22222".to_string(), + image_url: "".to_string(), + flag_safe: false, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, }; // mock check_and_unmount @@ -252,13 +223,7 @@ mod tests { // Get the path of the temporary file and the path where it should be copied. let src_dir = tmp_file.path().parent().unwrap(); - let src_file_name = tmp_file - .path() - .file_name() - .unwrap() - .to_str() - .unwrap() - .to_string(); + let src_file_name = tmp_file.path().file_name().unwrap().to_str().unwrap().to_string(); let dst_file = NamedTempFile::new().expect("Failed to create destination temporary file."); let dst_path = dst_file.path().to_path_buf(); @@ -299,8 +264,7 @@ mod tests { assert!(result.is_ok()); let expected_content = "Hello, world!\n"; - let actual_content = - fs::read_to_string(&dst_path).expect("Failed to read destination file."); + let actual_content = fs::read_to_string(&dst_path).expect("Failed to read destination file."); assert_eq!(expected_content, actual_content); // Assert the file permission @@ -332,8 +296,7 @@ mod tests { .times(1) .returning(|_, _| Ok(())); - let result = CtrImageHandler::new(PreparePath::default(), mock_executor) - .check_and_unmount("test_mount_path"); + let result = CtrImageHandler::new(PreparePath::default(), mock_executor).check_and_unmount("test_mount_path"); assert!(result.is_ok()); } @@ -342,15 +305,16 @@ mod tests { #[ignore] fn test_download_image() { init(); - let ctr = CtrImageHandler { - paths: PreparePath::default(), - executor: RealCommandExecutor {}, - }; + let ctr = CtrImageHandler { paths: PreparePath::default(), executor: RealCommandExecutor {} }; let update_req = UpgradeRequest { version: "KubeOS v2".to_string(), image_type: "containerd".to_string(), container_image: "docker.io/library/busybox:latest".to_string(), check_sum: "".to_string(), + image_url: "".to_string(), + flag_safe: false, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, }; ctr.download_image(&update_req).unwrap(); let tar_path = "/persist/KubeOS-Update/os.tar"; diff --git a/KubeOS-Rust/manager/src/sys_mgmt/disk_image.rs b/KubeOS-Rust/manager/src/sys_mgmt/disk_image.rs new file mode 100644 index 0000000000000000000000000000000000000000..5c4190ab69d54ab661d371677039f3c1b7ea43a1 --- /dev/null +++ b/KubeOS-Rust/manager/src/sys_mgmt/disk_image.rs @@ -0,0 +1,307 @@ +use std::{ + fs, + os::unix::fs::PermissionsExt, + path::{Path, PathBuf}, +}; + +use anyhow::{bail, Context, Result}; +use log::{debug, info, trace}; +use reqwest::{blocking::Client, Certificate}; +use sha2::{Digest, Sha256}; + +use crate::{ + api::{CertsInfo, ImageHandler, UpgradeRequest}, + sys_mgmt::{CERTS_PATH, IMAGE_PERMISSION, PERSIST_DIR}, + utils::*, +}; + +const BUFFER: u64 = 1024 * 1024 * 10; + +pub struct DiskImageHandler { + pub paths: PreparePath, + pub executor: T, + pub certs_path: String, +} + +impl ImageHandler for DiskImageHandler { + fn download_image(&self, req: &UpgradeRequest) -> Result> { + self.download(req)?; + self.checksum_match(self.paths.image_path.to_str().unwrap_or_default(), &req.check_sum)?; + let (_, next_partition_info) = get_partition_info(&self.executor)?; + let img_manager = UpgradeImageManager::new(self.paths.clone(), next_partition_info, self.executor.clone()); + Ok(img_manager) + } +} + +impl Default for DiskImageHandler { + fn default() -> Self { + Self { paths: PreparePath::default(), executor: RealCommandExecutor {}, certs_path: CERTS_PATH.to_string() } + } +} + +impl DiskImageHandler { + #[cfg(test)] + fn new(paths: PreparePath, executor: T, certs_path: String) -> Self { + Self { paths, executor, certs_path } + } + + fn download(&self, req: &UpgradeRequest) -> Result<()> { + let mut resp = self.send_download_request(req)?; + if resp.status() != reqwest::StatusCode::OK { + bail!("Failed to download image from {}, status: {}", req.image_url, resp.status()); + } + debug!("Received response body size: {:?}", resp.content_length().unwrap_or_default()); + let need_bytes = resp.content_length().unwrap_or_default() + BUFFER; + + check_disk_size( + i64::try_from(need_bytes).with_context(|| "Failed to transform content length from u64 to i64")?, + self.paths.image_path.parent().unwrap_or_else(|| Path::new(PERSIST_DIR)), + )?; + + let mut out = fs::File::create(&self.paths.image_path)?; + trace!("Start to save upgrade image to path {}", &self.paths.image_path.display()); + out.set_permissions(fs::Permissions::from_mode(IMAGE_PERMISSION))?; + let bytes = resp.copy_to(&mut out)?; + info!( + "Download image successfully, upgrade image path: {}, write bytes: {}", + &self.paths.image_path.display(), + bytes + ); + Ok(()) + } + + fn checksum_match(&self, file_path: &str, check_sum: &str) -> Result<()> { + trace!("Start to check checksum"); + let file = fs::read(file_path)?; + let mut hasher = Sha256::new(); + hasher.update(file); + let hash = hasher.finalize(); + // sha256sum -b /persist/update.img + let cal_sum = format!("{:X}", hash); + if cal_sum.to_lowercase() != check_sum.to_lowercase() { + delete_file_or_dir(file_path)?; + bail!("Checksum {} mismatch to {}", cal_sum, check_sum); + } + debug!("Checksum match"); + Ok(()) + } + + fn send_download_request(&self, req: &UpgradeRequest) -> Result { + let client: Client; + + if !req.image_url.starts_with("https://") { + // http request + if !req.flag_safe { + bail!("The upgrade image url is not safe"); + } + info!("Discover http request to: {}", &req.image_url); + client = Client::new(); + } else if req.mtls { + // https mtls request + client = self.load_ca_client_certs(&req.certs).with_context(|| "Failed to load client certificates")?; + info!("Discover https mtls request to: {}", &req.image_url); + } else { + // https request + client = self.load_ca_certs(&req.certs.ca_cert).with_context(|| "Failed to load CA certificates")?; + info!("Discover https request to: {}", &req.image_url); + } + + client.get(&req.image_url).send().with_context(|| format!("Failed to fetch from URL: {}", &req.image_url)) + } + + fn load_ca_certs(&self, ca_cert: &str) -> Result { + trace!("Start to load CA certificates"); + self.cert_exist(ca_cert)?; + let ca = Certificate::from_pem(&std::fs::read(self.get_certs_path(ca_cert))?)?; + let client = Client::builder().add_root_certificate(ca).build()?; + Ok(client) + } + + fn load_ca_client_certs(&self, certs: &CertsInfo) -> Result { + trace!("Start to load CA and client certificates"); + self.cert_exist(&certs.ca_cert)?; + let ca = Certificate::from_pem(&std::fs::read(self.get_certs_path(&certs.ca_cert))?)?; + + self.cert_exist(&certs.client_cert)?; + self.cert_exist(&certs.client_key)?; + let client_cert = std::fs::read(self.get_certs_path(&certs.client_cert))?; + let client_key = std::fs::read(self.get_certs_path(&certs.client_key))?; + let mut client_identity = Vec::new(); + client_identity.extend_from_slice(&client_cert); + client_identity.extend_from_slice(&client_key); + let client_id = reqwest::Identity::from_pem(&client_identity)?; + + let client = Client::builder().use_rustls_tls().add_root_certificate(ca).identity(client_id).build()?; + Ok(client) + } + + fn cert_exist(&self, cert_file: &str) -> Result<()> { + if cert_file.is_empty() { + bail!("Please provide the certificate"); + } + if !self.get_certs_path(cert_file).exists() { + bail!("Certificate does not exist: {}", cert_file); + } + Ok(()) + } + + fn get_certs_path(&self, cert: &str) -> PathBuf { + let cert_path = format!("{}{}", self.certs_path, cert); + PathBuf::from(cert_path) + } +} + +#[cfg(test)] +mod tests { + use tempfile::NamedTempFile; + + use super::*; + + fn init() { + let _ = env_logger::builder() + .target(env_logger::Target::Stdout) + .filter_level(log::LevelFilter::Trace) + .is_test(true) + .try_init(); + } + + #[test] + fn test_get_certs_path() { + init(); + let handler = DiskImageHandler::::default(); + let certs_path = handler.get_certs_path("ca.pem"); + assert_eq!(certs_path.to_str().unwrap(), "/etc/KubeOS/certs/ca.pem"); + } + + #[test] + fn test_cert_exist() { + init(); + // generate tmp file + let tmp_file = NamedTempFile::new().unwrap(); + let handler = + DiskImageHandler::::new(PreparePath::default(), RealCommandExecutor {}, String::new()); + let res = handler.cert_exist(tmp_file.path().to_str().unwrap()); + assert!(res.is_ok()); + + assert!(handler.cert_exist("aaa.pem").is_err()) + } + + #[test] + #[ignore] + fn test_send_download_request() { + init(); + // http + let handler = DiskImageHandler::::default(); + let req = UpgradeRequest { + version: "v2".into(), + check_sum: "1327e27d600538354d93bd68cce86566dd089e240c126dc3019cafabdc65aa02".into(), + image_type: "disk".into(), + container_image: "".into(), + image_url: "http://localhost:8080/aaa.txt".to_string(), + flag_safe: true, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, + }; + let res = handler.send_download_request(&req); + assert!(res.is_ok()); + assert_eq!(res.unwrap().text().unwrap(), "This is a test txt file generated by yuhang wei\n"); + + // https + let mut handler = DiskImageHandler::::default(); + handler.certs_path = "/home/yuhang/Documents/data/https-nginx/nginx/certs/".to_string(); + let req = UpgradeRequest { + version: "v2".into(), + check_sum: "1327e27d600538354d93bd68cce86566dd089e240c126dc3019cafabdc65aa02".into(), + image_type: "disk".into(), + container_image: "".into(), + image_url: "https://7.250.142.47:8081/aaa.txt".to_string(), + flag_safe: true, + mtls: false, + certs: CertsInfo { + ca_cert: "nginx.crt".to_string(), + client_cert: "".to_string(), + client_key: "".to_string(), + }, + }; + let res = handler.send_download_request(&req); + assert!(res.is_ok()); + assert_eq!(res.unwrap().text().unwrap(), "This is a test txt file generated by yuhang wei\n"); + + // mtls + let mut handler = DiskImageHandler::::default(); + handler.certs_path = "/home/yuhang/Documents/data/cert/".to_string(); + let req = UpgradeRequest { + version: "v2".into(), + check_sum: "1327e27d600538354d93bd68cce86566dd089e240c126dc3019cafabdc65aa02".into(), + image_type: "disk".into(), + container_image: "".into(), + image_url: "https://7.250.142.47:8082/aaa.txt".to_string(), + flag_safe: true, + mtls: true, + certs: CertsInfo { + ca_cert: "nginx.crt".to_string(), + client_cert: "client.crt".to_string(), + client_key: "client.key".to_string(), + }, + }; + let res = handler.send_download_request(&req); + assert!(res.is_ok()); + assert_eq!(res.unwrap().text().unwrap(), "This is a test txt file generated by yuhang wei\n"); + } + + #[test] + #[ignore] + fn test_download() { + init(); + let mut handler = DiskImageHandler::::default(); + handler.paths.image_path = PathBuf::from("/home/yuhang/Documents/KubeOS/KubeOS-Rust/test_download_image"); + let req = UpgradeRequest { + version: "v2".into(), + check_sum: "90da5a14e9c06ddb276b06134e90d37098be2830beaa4357205bec7ff1aa1f7c".into(), + image_type: "disk".into(), + container_image: "".into(), + image_url: "http://localhost:8080/linux-firmware.rpm".to_string(), + flag_safe: true, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, + }; + let res = handler.download(&req); + assert!(res.is_ok()); + assert_eq!(true, handler.paths.image_path.exists()) + } + + #[test] + #[ignore] + fn test_checksum_match() { + init(); + let mut handler = DiskImageHandler::::default(); + handler.paths.image_path = PathBuf::from("/home/yuhang/Documents/KubeOS/KubeOS-Rust/test_download_image"); + let req = UpgradeRequest { + version: "v2".into(), + check_sum: "90da5a14e9c06ddb276b06134e90d37098be2830beaa4357205bec7ff1aa1f7c".into(), + image_type: "disk".into(), + container_image: "".into(), + image_url: "http://localhost:8080/aaa.txt".to_string(), + flag_safe: true, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, + }; + assert_eq!(handler.paths.image_path.exists(), true); + handler.checksum_match(handler.paths.image_path.to_str().unwrap(), &req.check_sum).unwrap(); + } + + #[test] + #[ignore] + fn test_load_ca_client_certs() { + init(); + let mut handler = DiskImageHandler::::default(); + handler.certs_path = "/home/yuhang/Documents/data/cert/".to_string(); + let certs = CertsInfo { + ca_cert: "nginx.crt".to_string(), + client_cert: "client.crt".to_string(), + client_key: "client.key".to_string(), + }; + let res = handler.load_ca_client_certs(&certs); + assert!(res.is_ok()); + } +} diff --git a/KubeOS-Rust/manager/src/sys_mgmt/docker_image.rs b/KubeOS-Rust/manager/src/sys_mgmt/docker_image.rs new file mode 100644 index 0000000000000000000000000000000000000000..74d3649aa86ab5787971133d50ed04fab531b5e9 --- /dev/null +++ b/KubeOS-Rust/manager/src/sys_mgmt/docker_image.rs @@ -0,0 +1,131 @@ +use anyhow::Result; +use log::{debug, info}; + +use crate::{ + api::{ImageHandler, UpgradeRequest}, + sys_mgmt::{IMAGE_PERMISSION, NEED_BYTES, PERSIST_DIR}, + utils::*, +}; + +pub struct DockerImageHandler { + pub paths: PreparePath, + pub container_name: String, + pub executor: T, +} + +impl ImageHandler for DockerImageHandler { + fn download_image(&self, req: &UpgradeRequest) -> Result> { + perpare_env(&self.paths, NEED_BYTES, PERSIST_DIR, IMAGE_PERMISSION)?; + self.get_image(req)?; + self.get_rootfs_archive(req)?; + + let (_, next_partition_info) = get_partition_info(&self.executor)?; + let img_manager = UpgradeImageManager::new(self.paths.clone(), next_partition_info, self.executor.clone()); + img_manager.create_os_image(IMAGE_PERMISSION) + } +} + +impl Default for DockerImageHandler { + fn default() -> Self { + Self { paths: PreparePath::default(), container_name: "kubeos-temp".into(), executor: RealCommandExecutor {} } + } +} + +impl DockerImageHandler { + #[cfg(test)] + fn new(paths: PreparePath, container_name: String, executor: T) -> Self { + Self { paths, container_name, executor } + } + + fn get_image(&self, req: &UpgradeRequest) -> Result<()> { + let image_name = &req.container_image; + is_valid_image_name(image_name)?; + let cli = "docker"; + remove_image_if_exist(cli, image_name, &self.executor)?; + info!("Start pull image {}", image_name); + pull_image(cli, image_name, &self.executor)?; + info!("Start check image digest"); + check_oci_image_digest(cli, image_name, &req.check_sum, &self.executor)?; + Ok(()) + } + + fn get_rootfs_archive(&self, req: &UpgradeRequest) -> Result<()> { + let image_name = &req.container_image; + info!("Start get rootfs {}", image_name); + self.check_and_rm_container()?; + debug!("Create container {}", self.container_name); + let container_id = + self.executor.run_command_with_output("docker", &["create", "--name", &self.container_name, image_name])?; + debug!("Copy rootfs from container {} to {}", container_id, self.paths.update_path.display()); + self.executor.run_command( + "docker", + &[ + "cp", + format!("{}:/{}", container_id, self.paths.rootfs_file).as_str(), + self.paths.update_path.to_str().unwrap(), + ], + )?; + self.check_and_rm_container()?; + Ok(()) + } + + fn check_and_rm_container(&self) -> Result<()> { + let docker_ps_cmd = format!("docker ps -a -f=name={} | awk 'NR==2' | awk '{{print $1}}'", self.container_name); + let exist_id = self.executor.run_command_with_output("bash", &["-c", &docker_ps_cmd])?; + if !exist_id.is_empty() { + info!("Remove container {} {} for cleaning environment", self.container_name, exist_id); + self.executor.run_command("docker", &["rm", exist_id.as_str()])?; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use mockall::mock; + + use super::*; + + mock! { + pub CommandExec{} + impl CommandExecutor for CommandExec { + fn run_command<'a>(&self, name: &'a str, args: &[&'a str]) -> Result<()>; + fn run_command_with_output<'a>(&self, name: &'a str, args: &[&'a str]) -> Result; + } + impl Clone for CommandExec { + fn clone(&self) -> Self; + } + } + + fn init() { + let _ = env_logger::builder() + .target(env_logger::Target::Stdout) + .filter_level(log::LevelFilter::Trace) + .is_test(true) + .try_init(); + } + + #[test] + fn test_check_and_rm_container() { + init(); + let mut mock_executor = MockCommandExec::new(); + mock_executor + .expect_run_command_with_output() + .withf(|cmd, args| { + cmd == "bash" + && args.len() == 2 + && args.contains(&"docker ps -a -f=name=test | awk 'NR==2' | awk '{print $1}'") + }) + .times(1) + .returning(|_, _| Ok(String::from("1111"))); + mock_executor + .expect_run_command() + .withf(|cmd, args| cmd == "docker" && args.contains(&"rm") && args.contains(&"1111")) + .times(1) + .returning(|_, _| Ok(())); + + let result = + DockerImageHandler::new(PreparePath::default(), "test".into(), mock_executor).check_and_rm_container(); + assert!(result.is_ok()); + } +} diff --git a/KubeOS-Rust/manager/src/sys_mgmt/mod.rs b/KubeOS-Rust/manager/src/sys_mgmt/mod.rs index 446d072cb8d8dd3c5b58ab885acd9645865261f2..0e06f297b4233d6d7be82b7e68a21e1f26375970 100644 --- a/KubeOS-Rust/manager/src/sys_mgmt/mod.rs +++ b/KubeOS-Rust/manager/src/sys_mgmt/mod.rs @@ -10,12 +10,14 @@ * See the Mulan PSL v2 for more details. */ -use super::api; - mod config; mod containerd_image; +mod disk_image; +mod docker_image; mod values; pub use config::*; pub use containerd_image::*; +pub use disk_image::*; +pub use docker_image::*; pub use values::*; diff --git a/KubeOS-Rust/manager/src/sys_mgmt/values.rs b/KubeOS-Rust/manager/src/sys_mgmt/values.rs index 3452b4adedc39130f67914cbd060ed4e5aaa9691..b107efc3b65607620819147145a607d0d5d0addd 100644 --- a/KubeOS-Rust/manager/src/sys_mgmt/values.rs +++ b/KubeOS-Rust/manager/src/sys_mgmt/values.rs @@ -25,6 +25,7 @@ pub const ROOTFS_ARCHIVE: &str = "os.tar"; pub const UPDATE_DIR: &str = "KubeOS-Update"; pub const MOUNT_DIR: &str = "kubeos-update"; pub const OS_IMAGE_NAME: &str = "update.img"; +pub const CERTS_PATH: &str = "/etc/KubeOS/certs/"; pub const DEFAULT_KERNEL_CONFIG_PERM: u32 = 0o644; pub const DEFAULT_GRUB_CFG_PERM: u32 = 0o751; @@ -32,4 +33,4 @@ pub const IMAGE_PERMISSION: u32 = 0o600; pub const ONLY_KEY: usize = 1; pub const KV_PAIR: usize = 2; -pub const NEED_GB_SIZE: i64 = 3; +pub const NEED_BYTES: i64 = 3 * 1024 * 1024 * 1024; diff --git a/KubeOS-Rust/manager/src/utils/common.rs b/KubeOS-Rust/manager/src/utils/common.rs index 7bb75a84b926a8130f2fc0488b7d96fed336fbf6..0fe94b7c9fe41aeebccca874b5fa71ef24ee3f49 100644 --- a/KubeOS-Rust/manager/src/utils/common.rs +++ b/KubeOS-Rust/manager/src/utils/common.rs @@ -12,12 +12,11 @@ use std::{ fs, - os::linux::fs::MetadataExt, - os::unix::fs::DirBuilderExt, + os::{linux::fs::MetadataExt, unix::fs::DirBuilderExt}, path::{Path, PathBuf}, }; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, bail, Result}; use log::{debug, info, trace}; use nix::{mount, mount::MntFlags}; @@ -51,41 +50,27 @@ pub fn is_file_exist>(path: P) -> bool { path.as_ref().exists() } -pub fn perpare_env( - prepare_path: &PreparePath, - need_gb: i64, - persist_path: &str, - permission: u32, -) -> Result<()> { +pub fn perpare_env(prepare_path: &PreparePath, need_bytes: i64, persist_path: &str, permission: u32) -> Result<()> { info!("Prepare environment to upgrade"); - check_disk_size(need_gb, persist_path)?; - clean_env( - &prepare_path.update_path, - &prepare_path.mount_path, - &prepare_path.image_path, - )?; - fs::DirBuilder::new() - .recursive(true) - .mode(permission) - .create(&prepare_path.mount_path)?; + check_disk_size(need_bytes, persist_path)?; + clean_env(&prepare_path.update_path, &prepare_path.mount_path, &prepare_path.image_path)?; + fs::DirBuilder::new().recursive(true).mode(permission).create(&prepare_path.mount_path)?; Ok(()) } -pub fn check_disk_size(need_gb: i64, path: &str) -> Result<()> { +pub fn check_disk_size>(need_bytes: i64, path: P) -> Result<()> { trace!("Check if there is enough disk space to upgrade"); - let kb = 1024; - let fs_stat = nix::sys::statfs::statfs(path)?; - let need_disk_size = need_gb * kb * kb * kb; + let fs_stat = nix::sys::statfs::statfs(path.as_ref())?; let available_blocks = i64::try_from(fs_stat.blocks_available())?; let available_space = available_blocks * fs_stat.block_size(); - if available_space < need_disk_size { - return Err(anyhow!("Space is not enough for downloading")); + if available_space < need_bytes { + bail!("Space is not enough for downloading"); } - debug!("There is enough disk space to upgrade"); + info!("There is enough disk space to upgrade"); Ok(()) } -// clean_env will umount the mount path and delete all files in /persist/KubeOS-Update and update.img +// clean_env will umount the mount path and delete directory /persist/KubeOS-Update and /persist/update.img pub fn clean_env

(update_path: P, mount_path: P, image_path: P) -> Result<()> where P: AsRef, @@ -94,11 +79,7 @@ where if is_mounted(&mount_path)? { debug!("Umount {}", mount_path.as_ref().display()); if let Err(errno) = mount::umount2(mount_path.as_ref(), MntFlags::MNT_FORCE) { - return Err(anyhow!( - "Failed to umount {} in clean_env: {}", - mount_path.as_ref().display(), - errno - )); + bail!("Failed to umount {} in clean_env: {}", mount_path.as_ref().display(), errno); } } // losetup -D? @@ -121,18 +102,15 @@ pub fn delete_file_or_dir>(path: P) -> Result<()> { } pub fn is_command_available(command: &str, command_executor: &T) -> bool { - match command_executor.run_command( - "/bin/sh", - &["-c", format!("command -v {}", command).as_str()], - ) { + match command_executor.run_command("/bin/sh", &["-c", format!("command -v {}", command).as_str()]) { Ok(_) => { debug!("command {} is available", command); true - } + }, Err(_) => { debug!("command {} is not available", command); false - } + }, } } @@ -145,12 +123,10 @@ pub fn is_mounted>(mount_path: P) -> Result { let dev = mount_meta.st_dev(); // Get device ID of mountPath's parent directory - let parent = mount_path.as_ref().parent().ok_or_else(|| { - anyhow!( - "Failed to get parent directory of {}", - mount_path.as_ref().display() - ) - })?; + let parent = mount_path + .as_ref() + .parent() + .ok_or_else(|| anyhow!("Failed to get parent directory of {}", mount_path.as_ref().display()))?; let parent_meta = fs::symlink_metadata(parent)?; let dev_parent = parent_meta.st_dev(); Ok(dev != dev_parent) @@ -164,11 +140,7 @@ pub fn switch_boot_menuentry( if get_boot_mode() == "uefi" { command_executor.run_command( "grub2-editenv", - &[ - grub_env_path, - "set", - format!("saved_entry={}", next_menuentry).as_str(), - ], + &[grub_env_path, "set", format!("saved_entry={}", next_menuentry).as_str()], )?; } else { command_executor.run_command("grub2-set-default", &[next_menuentry])?; @@ -177,19 +149,15 @@ pub fn switch_boot_menuentry( } pub fn get_boot_mode() -> String { - if is_file_exist("/sys/firmware/efi") { - "uefi".into() - } else { - "bios".into() - } + if is_file_exist("/sys/firmware/efi") { "uefi".into() } else { "bios".into() } } #[cfg(test)] mod tests { - use super::*; use mockall::{mock, predicate::*}; - use tempfile::NamedTempFile; - use tempfile::TempDir; + use tempfile::{NamedTempFile, TempDir}; + + use super::*; // Mock the CommandExecutor trait mock! { @@ -234,17 +202,18 @@ mod tests { image_path: PathBuf::from("/tmp/test_prepare_env/update.img"), rootfs_file: "os.tar".to_string(), }; - perpare_env(&paths, 1, "/home", 0o700).unwrap(); + perpare_env(&paths, 1 * 1024 * 1024 * 1024, "/home", 0o700).unwrap(); } #[test] fn test_check_disk_size() { init(); let path = "/home"; - let need_gb = 1; + let gb: i64 = 1 * 1024 * 1024 * 1024; + let need_gb = 1 * gb; let result = check_disk_size(need_gb, path); assert!(result.is_ok()); - let need_gb = 1000; + let need_gb = 10000 * gb; let result = check_disk_size(need_gb, path); assert!(result.is_err()); } @@ -255,12 +224,7 @@ mod tests { let update_path = "/tmp/test_clean_env"; let mount_path = "/tmp/test_clean_env/kubeos-update"; let image_path = "/tmp/test_clean_env/update.img"; - clean_env( - &update_path.to_string(), - &mount_path.to_string(), - &image_path.to_string(), - ) - .unwrap(); + clean_env(&update_path.to_string(), &mount_path.to_string(), &image_path.to_string()).unwrap(); } #[test] @@ -291,14 +255,21 @@ mod tests { let grubenv_path = "/boot/efi/EFI/openEuler/grubenv"; let next_menuentry = "B"; let mut mock = MockCommandExec::new(); - mock.expect_run_command() - .withf(move |name, args| { - name == "grub2-editenv" - && args[0] == grubenv_path - && args[2] == format!("saved_entry={}", next_menuentry).as_str() - }) - .times(1) // Expect it to be called once - .returning(move |_, _| Ok(())); + if get_boot_mode() == "uefi" { + mock.expect_run_command() + .withf(move |name, args| { + name == "grub2-editenv" + && args[0] == grubenv_path + && args[2] == format!("saved_entry={}", next_menuentry).as_str() + }) + .times(1) // Expect it to be called once + .returning(move |_, _| Ok(())); + } else { + mock.expect_run_command() + .withf(move |name, args| name == "grub2-set-default" && args[0] == next_menuentry) + .times(1) // Expect it to be called once + .returning(move |_, _| Ok(())); + } switch_boot_menuentry(&mock, grubenv_path, next_menuentry).unwrap() } diff --git a/KubeOS-Rust/manager/src/utils/container_image.rs b/KubeOS-Rust/manager/src/utils/container_image.rs index 8c5bfaf7ee71194536d5fefb1fdd5a87293b3850..a54fc19365d256ff05c10f66d191624e978c15d4 100644 --- a/KubeOS-Rust/manager/src/utils/container_image.rs +++ b/KubeOS-Rust/manager/src/utils/container_image.rs @@ -10,8 +10,8 @@ * See the Mulan PSL v2 for more details. */ -use anyhow::{anyhow, Result}; -use log::{debug, trace}; +use anyhow::{bail, Result}; +use log::{debug, info, trace}; use regex::Regex; use super::executor::CommandExecutor; @@ -20,25 +20,21 @@ pub fn is_valid_image_name(image: &str) -> Result<()> { let pattern = r"^(?P[a-z0-9\-.]+\.[a-z0-9\-]+:?[0-9]*)?/?((?P[a-zA-Z0-9-_]+?)|(?P[a-zA-Z0-9-_]+?)/(?P[a-zA-Z-_]+?))(?P(?::[\w_.-]+)?|(?:@sha256:[a-fA-F0-9]+)?)$"; let reg_ex = Regex::new(pattern)?; if !reg_ex.is_match(image) { - return Err(anyhow!("Invalid image name: {}", image)); + bail!("Invalid image name: {}", image); } - trace!("Image name {} is valid", image); + debug!("Image name {} is valid", image); Ok(()) } -pub fn check_oci_image_digest_match( +pub fn check_oci_image_digest( container_runtime: &str, image_name: &str, check_sum: &str, command_executor: &T, ) -> Result<()> { let image_digests = get_oci_image_digest(container_runtime, image_name, command_executor)?; - if image_digests != check_sum { - return Err(anyhow!( - "Image digest mismatch, expect {}, got {}", - check_sum, - image_digests - )); + if image_digests.to_lowercase() != check_sum.to_lowercase() { + bail!("Image digest mismatch, expect {}, got {}", check_sum, image_digests); } Ok(()) } @@ -53,33 +49,16 @@ pub fn get_oci_image_digest( "crictl" => { cmd_output = executor.run_command_with_output( "crictl", - &[ - "inspecti", - "--output", - "go-template", - "--template", - "{{.status.repoDigests}}", - image_name, - ], + &["inspecti", "--output", "go-template", "--template", "{{.status.repoDigests}}", image_name], )?; - } + }, "docker" => { - cmd_output = executor.run_command_with_output( - "docker", - &["inspect", "--format", "{{.RepoDigests}}", image_name], - )?; - } + cmd_output = + executor.run_command_with_output("docker", &["inspect", "--format", "{{.RepoDigests}}", image_name])?; + }, "ctr" => { - cmd_output = executor.run_command_with_output( - "ctr", - &[ - "-n", - "k8s.io", - "images", - "ls", - &format!("name=={}", image_name), - ], - )?; + cmd_output = executor + .run_command_with_output("ctr", &["-n", "k8s.io", "images", "ls", &format!("name=={}", image_name)])?; // Split by whitespaces, we get vec like [REF TYPE DIGEST SIZE PLATFORMS LABELS x x x x x x] // get the 8th element, and split by ':' to get the digest let fields: Vec<&str> = cmd_output.split_whitespace().collect(); @@ -87,18 +66,12 @@ pub fn get_oci_image_digest( trace!("get_oci_image_digest: {}", digest); return Ok(digest.to_string()); } else { - return Err(anyhow!( - "Failed to get digest from ctr command output: {}", - cmd_output - )); + bail!("Failed to get digest from ctr command output: {}", cmd_output); } - } + }, _ => { - return Err(anyhow!( - "Container runtime {} cannot be recognized", - container_runtime - )); - } + bail!("Container runtime {} cannot be recognized", container_runtime); + }, } // Parse the cmd_output to extract the digest @@ -108,16 +81,13 @@ pub fn get_oci_image_digest( let parsed_parts: Vec<&str> = last_part.trim_matches(|c| c == ']').split(':').collect(); // After spliiing by ':', we should get vec like [sha256, digests] if parsed_parts.len() == 2 { - trace!("get_oci_image_digest: {}", parsed_parts[1]); + debug!("get_oci_image_digest: {}", parsed_parts[1]); return Ok(parsed_parts[1].to_string()); // 1 is the index of digests } } } - Err(anyhow!( - "Failed to get digest from command output: {}", - cmd_output - )) + bail!("Failed to get digest from command output: {}", cmd_output) } pub fn pull_image(runtime: &str, image_name: &str, executor: &T) -> Result<()> { @@ -125,39 +95,60 @@ pub fn pull_image(runtime: &str, image_name: &str, executor: match runtime { "crictl" => { executor.run_command("crictl", &["pull", image_name])?; - } + }, "ctr" => { executor.run_command( "ctr", - &[ - &"-n", - "k8s.io", - "images", - "pull", - "--hosts-dir", - "/etc/containerd/certs.d", - image_name, - ], + &[&"-n", "k8s.io", "images", "pull", "--hosts-dir", "/etc/containerd/certs.d", image_name], )?; - } + }, "docker" => { executor.run_command("docker", &["pull", image_name])?; - } + }, _ => { - return Err(anyhow!( - "Container runtime {} cannot be recognized", - runtime - )); - } + bail!("Container runtime {} cannot be recognized", runtime); + }, + } + Ok(()) +} + +pub fn remove_image_if_exist(runtime: &str, image_name: &str, executor: &T) -> Result<()> { + match runtime { + "crictl" => { + if executor.run_command("crictl", &["inspecti", image_name]).is_ok() { + executor.run_command("crictl", &["rmi", image_name])?; + info!("Remove existing upgrade image: {}", image_name); + } + }, + "ctr" => { + let output = executor.run_command_with_output( + "ctr", + &[&"-n", "k8s.io", "images", "check", &format!("name=={}", image_name)], + )?; + if !output.is_empty() { + executor.run_command("ctr", &[&"-n", "k8s.io", "images", "rm", image_name, "--sync"])?; + info!("Remove existing upgrade image: {}", image_name); + } + }, + "docker" => { + if executor.run_command("docker", &["inspect", image_name]).is_ok() { + executor.run_command("docker", &["rmi", image_name])?; + info!("Remove existing upgrade image: {}", image_name); + } + }, + _ => { + bail!("Container runtime {} cannot be recognized", runtime); + }, } Ok(()) } #[cfg(test)] mod tests { - use super::*; use mockall::{mock, predicate::*}; + use super::*; + // Mock the CommandExecutor trait mock! { pub CommandExec{} @@ -183,14 +174,11 @@ mod tests { init(); let out = is_valid_image_name("nginx").unwrap(); assert_eq!(out, ()); - let out = is_valid_image_name( - "docker.example.com:5000/gmr/alpine@sha256:11111111111111111111111111111111", - ) - .unwrap(); + let out = + is_valid_image_name("docker.example.com:5000/gmr/alpine@sha256:11111111111111111111111111111111").unwrap(); assert_eq!(out, ()); - let out = is_valid_image_name( - "sosedoff/pgweb:latest@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8", - ); + let out = + is_valid_image_name("sosedoff/pgweb:latest@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8"); match out { Ok(_) => assert_eq!(true, false), Err(_) => assert_eq!(true, true), @@ -203,19 +191,16 @@ mod tests { let mut mock = MockCommandExec::new(); let container_runtime = "ctr"; let image_name = "docker.io/nginx:latest"; - let command_output1 = "REF TYPE DIGEST SIZE PLATFORMS LABELS\ndocker.io/nginx:latest text/html sha256:1111 132.5 KIB - -\n"; - mock.expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output1.to_string())); + let command_output1 = + "REF TYPE DIGEST SIZE PLATFORMS LABELS\ndocker.io/nginx:latest text/html sha256:1111 132.5 KIB - -\n"; + mock.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output1.to_string())); let out1 = get_oci_image_digest(container_runtime, image_name, &mock).unwrap(); let expect_output = "1111"; assert_eq!(out1, expect_output); let container_runtime = "crictl"; let command_output2 = "[docker.io/nginx@sha256:1111]"; - mock.expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output2.to_string())); + mock.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output2.to_string())); let out2 = get_oci_image_digest(container_runtime, image_name, &mock).unwrap(); assert_eq!(out2, expect_output); } @@ -228,10 +213,8 @@ mod tests { let container_runtime = "crictl"; let command_output = "[docker.io/nginx@sha256:1111]"; let check_sum = "1111"; - mock.expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output.to_string())); - let result = check_oci_image_digest_match(container_runtime, image_name, check_sum, &mock); + mock.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output.to_string())); + let result = check_oci_image_digest(container_runtime, image_name, check_sum, &mock); assert!(result.is_ok()); } diff --git a/KubeOS-Rust/manager/src/utils/executor.rs b/KubeOS-Rust/manager/src/utils/executor.rs index 5c70c8e4213f6900f6efacb5e48a488724ae2d13..8f4cb25c7652d9ec05ec8a499260f74acc41d22f 100644 --- a/KubeOS-Rust/manager/src/utils/executor.rs +++ b/KubeOS-Rust/manager/src/utils/executor.rs @@ -12,8 +12,8 @@ use std::process::Command; -use anyhow::{anyhow, Result}; -use log::trace; +use anyhow::{bail, Result}; +use log::{debug, trace}; pub trait CommandExecutor: Clone { fn run_command<'a>(&self, name: &'a str, args: &[&'a str]) -> Result<()>; @@ -25,34 +25,26 @@ pub struct RealCommandExecutor {} impl CommandExecutor for RealCommandExecutor { fn run_command<'a>(&self, name: &'a str, args: &[&'a str]) -> Result<()> { + trace!("run_command: {} {:?}", name, args); let output = Command::new(name).args(args).output()?; if !output.status.success() { let error_message = String::from_utf8_lossy(&output.stderr); - return Err(anyhow!( - "Failed to run command: {} {:?}, stderr: {}", - name, - args, - error_message - )); + bail!("Failed to run command: {} {:?}, stderr: {}", name, args, error_message); } - trace!("run_command: {} {:?} done", name, args); + debug!("run_command: {} {:?} done", name, args); Ok(()) } fn run_command_with_output<'a>(&self, name: &'a str, args: &[&'a str]) -> Result { + trace!("run_command_with_output: {} {:?}", name, args); let output = Command::new(name).args(args).output()?; if !output.status.success() { let error_message = String::from_utf8_lossy(&output.stderr); - return Err(anyhow!( - "Failed to run command: {} {:?}, stderr: {}", - name, - args, - error_message - )); + bail!("Failed to run command: {} {:?}, stderr: {}", name, args, error_message); } let stdout = String::from_utf8_lossy(&output.stdout).to_string(); - trace!("run_command_with_output: {} {:?} done", name, args); - Ok(stdout.trim_end_matches("\n").to_string()) + debug!("run_command_with_output: {} {:?} done", name, args); + Ok(stdout.trim_end_matches('\n').to_string()) } } @@ -74,16 +66,11 @@ mod tests { let executor: RealCommandExecutor = RealCommandExecutor {}; // test run_command_with_output - let output = executor - .run_command_with_output("echo", &["hello", "world"]) - .unwrap(); + let output = executor.run_command_with_output("echo", &["hello", "world"]).unwrap(); assert_eq!(output, "hello world"); - let out = executor - .run_command_with_output("sh", &["-c", format!("command -v {}", "cat").as_str()]) - .unwrap(); + let out = executor.run_command_with_output("sh", &["-c", format!("command -v {}", "cat").as_str()]).unwrap(); assert_eq!(out, "/usr/bin/cat"); - let out = executor - .run_command_with_output("sh", &["-c", format!("command -v {}", "apple").as_str()]); + let out = executor.run_command_with_output("sh", &["-c", format!("command -v {}", "apple").as_str()]); assert!(out.is_err()); } diff --git a/KubeOS-Rust/manager/src/utils/image_manager.rs b/KubeOS-Rust/manager/src/utils/image_manager.rs index ca48712fd81e160cf516ff98159fe48d1f7a2741..e3dddaaf2373d1215e0799f4eb5e3c1a7bd34f72 100644 --- a/KubeOS-Rust/manager/src/utils/image_manager.rs +++ b/KubeOS-Rust/manager/src/utils/image_manager.rs @@ -34,47 +34,26 @@ pub struct UpgradeImageManager { impl UpgradeImageManager { pub fn new(paths: PreparePath, next_partition: PartitionInfo, executor: T) -> Self { - Self { - paths, - next_partition, - executor, - } + Self { paths, next_partition, executor } } fn image_path_str(&self) -> Result<&str> { - self.paths - .image_path - .to_str() - .context("Failed to convert image path to string") + self.paths.image_path.to_str().context("Failed to convert image path to string") } fn mount_path_str(&self) -> Result<&str> { - self.paths - .mount_path - .to_str() - .context("Failed to convert mount path to string") + self.paths.mount_path.to_str().context("Failed to convert mount path to string") } fn tar_path_str(&self) -> Result<&str> { - self.paths - .tar_path - .to_str() - .context("Failed to convert tar path to string") + self.paths.tar_path.to_str().context("Failed to convert tar path to string") } pub fn create_image_file(&self, permission: u32) -> Result<()> { let image_str = self.image_path_str()?; debug!("Create image {}", image_str); - self.executor.run_command( - "dd", - &[ - "if=/dev/zero", - &format!("of={}", image_str), - "bs=2M", - "count=1024", - ], - )?; + self.executor.run_command("dd", &["if=/dev/zero", &format!("of={}", image_str), "bs=2M", "count=1024"])?; fs::set_permissions(&self.paths.image_path, Permissions::from_mode(permission))?; Ok(()) } @@ -84,11 +63,7 @@ impl UpgradeImageManager { debug!("Format image {}", image_str); self.executor.run_command( format!("mkfs.{}", self.next_partition.fs_type).as_str(), - &[ - "-L", - format!("ROOT-{}", self.next_partition.menuentry).as_str(), - image_str, - ], + &["-L", format!("ROOT-{}", self.next_partition.menuentry).as_str(), image_str], )?; Ok(()) } @@ -97,8 +72,7 @@ impl UpgradeImageManager { let image_str = self.image_path_str()?; let mount_str = self.mount_path_str()?; debug!("Mount {} to {}", image_str, mount_str); - self.executor - .run_command("mount", &["-o", "loop", image_str, mount_str])?; + self.executor.run_command("mount", &["-o", "loop", image_str, mount_str])?; Ok(()) } @@ -106,8 +80,7 @@ impl UpgradeImageManager { let tar_str = self.tar_path_str()?; let mount_str = self.mount_path_str()?; debug!("Extract {} to mounted path {}", tar_str, mount_str); - self.executor - .run_command("tar", &["-xvf", tar_str, "-C", mount_str])?; + self.executor.run_command("tar", &["-xvf", tar_str, "-C", mount_str])?; Ok(()) } @@ -117,25 +90,15 @@ impl UpgradeImageManager { self.mount_image()?; self.extract_tar_to_image()?; // Pass empty image_path to clean_env to avoid delete image file - clean_env( - &self.paths.update_path, - &self.paths.mount_path, - &PathBuf::new(), - )?; + clean_env(&self.paths.update_path, &self.paths.mount_path, &PathBuf::new())?; Ok(self) } pub fn install(&self) -> Result<()> { let image_str = self.image_path_str()?; let device = self.next_partition.device.as_str(); - self.executor.run_command( - "dd", - &[ - format!("if={}", image_str).as_str(), - format!("of={}", device).as_str(), - "bs=8M", - ], - )?; + self.executor + .run_command("dd", &[format!("if={}", image_str).as_str(), format!("of={}", device).as_str(), "bs=8M"])?; debug!("Install image {} to {} done", image_str, device); info!( "Device {} is overwritten and unable to rollback to the previous version anymore if the eviction of node fails", @@ -148,11 +111,13 @@ impl UpgradeImageManager { #[cfg(test)] mod tests { - use super::*; - use mockall::{mock, predicate::*}; use std::{fs, io::Write, path::Path}; + + use mockall::{mock, predicate::*}; use tempfile::NamedTempFile; + use super::*; + // Mock the CommandExecutor trait mock! { pub CommandExec{} @@ -227,11 +192,7 @@ mod tests { tar_path: "/tmp/update/image.tar".into(), rootfs_file: "image.tar".into(), }, - PartitionInfo { - device: "/dev/sda3".into(), - fs_type: "ext4".into(), - menuentry: "B".into(), - }, + PartitionInfo { device: "/dev/sda3".into(), fs_type: "ext4".into(), menuentry: "B".into() }, mock, ); diff --git a/KubeOS-Rust/manager/src/utils/partition.rs b/KubeOS-Rust/manager/src/utils/partition.rs index 8d59e1745049f635bdbfc05804be624db9108db1..0419159b534e6e0ea0ed81e294dca16588733dba 100644 --- a/KubeOS-Rust/manager/src/utils/partition.rs +++ b/KubeOS-Rust/manager/src/utils/partition.rs @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. */ -use anyhow::{anyhow, Result}; +use anyhow::{bail, Result}; use log::{debug, trace}; use super::executor::CommandExecutor; @@ -22,9 +22,7 @@ pub struct PartitionInfo { pub fs_type: String, } -pub fn get_partition_info( - executor: &T, -) -> Result<(PartitionInfo, PartitionInfo), anyhow::Error> { +pub fn get_partition_info(executor: &T) -> Result<(PartitionInfo, PartitionInfo), anyhow::Error> { let lsblk = executor.run_command_with_output("lsblk", &["-lno", "NAME,MOUNTPOINTS,FSTYPE"])?; // After split whitespace, the root directory line should have 3 elements, which are "sda2 / ext4". let mut cur_partition = PartitionInfo::default(); @@ -38,31 +36,31 @@ pub fn get_partition_info( cur_partition.device = format!("/dev/{}", res[0]).to_string(); cur_partition.fs_type = res[2].to_string(); next_partition.fs_type = res[2].to_string(); - if res[0].contains("2") { + if res[0].contains('2') { + // root directory is mounted on sda2, so sda3 is the next partition cur_partition.menuentry = String::from("A"); next_partition.menuentry = String::from("B"); - next_partition.device = format!("/dev/{}", res[0].replace("2", "3")).to_string(); - } else if res[0].contains("3") { + next_partition.device = format!("/dev/{}", res[0].replace('2', "3")).to_string(); + } else if res[0].contains('3') { + // root directory is mounted on sda3, so sda2 is the next partition cur_partition.menuentry = String::from("B"); next_partition.menuentry = String::from("A"); - next_partition.device = format!("/dev/{}", res[0].replace("3", "2")).to_string(); + next_partition.device = format!("/dev/{}", res[0].replace('3', "2")).to_string(); } } } if cur_partition.device.is_empty() { - return Err(anyhow!( - "Failed to get partition info, lsblk output: {}", - lsblk - )); + bail!("Failed to get partition info, lsblk output: {}", lsblk); } Ok((cur_partition, next_partition)) } #[cfg(test)] mod tests { - use super::*; use mockall::{mock, predicate::*}; + use super::*; + // Mock the CommandExecutor trait mock! { pub CommandExec{} @@ -86,24 +84,13 @@ mod tests { #[test] fn test_get_partition_info() { init(); - let command_output1 = - "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; + let command_output1 = "sda\nsda1 /boot/efi vfat\nsda2 / ext4\nsda3 ext4\nsda4 /persist ext4\nsr0 iso9660\n"; let mut mock = MockCommandExec::new(); - mock.expect_run_command_with_output() - .times(1) - .returning(|_, _| Ok(command_output1.to_string())); + mock.expect_run_command_with_output().times(1).returning(|_, _| Ok(command_output1.to_string())); let res = get_partition_info(&mock).unwrap(); let expect_res = ( - PartitionInfo { - device: "/dev/sda2".to_string(), - menuentry: "A".to_string(), - fs_type: "ext4".to_string(), - }, - PartitionInfo { - device: "/dev/sda3".to_string(), - menuentry: "B".to_string(), - fs_type: "ext4".to_string(), - }, + PartitionInfo { device: "/dev/sda2".to_string(), menuentry: "A".to_string(), fs_type: "ext4".to_string() }, + PartitionInfo { device: "/dev/sda3".to_string(), menuentry: "B".to_string(), fs_type: "ext4".to_string() }, ); assert_eq!(res, expect_res); } diff --git a/KubeOS-Rust/proxy/Cargo.toml b/KubeOS-Rust/proxy/Cargo.toml index a0c483583a0fec8dd638458fc0964b727a789948..b96bd1cd337889705fc3e266267e9fb9dd633471 100644 --- a/KubeOS-Rust/proxy/Cargo.toml +++ b/KubeOS-Rust/proxy/Cargo.toml @@ -1,31 +1,33 @@ [package] +description = "KubeOS os-proxy" +edition = "2021" +license = "MulanPSL-2.0" name = "proxy" version = "0.1.0" -edition = "2021" -description = "KubeOS os-proxy" -license = "MulanPSL-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -kube = { version = "0.66.0", features = ["runtime", "derive"] } -k8s-openapi = { version = "0.13.1", features = ["v1_22"] } -tokio = { version = "=1.14.0", features = ["rt-multi-thread", "macros"] } anyhow = "1.0.44" +async-trait = "0.1" +chrono = { version = "0.4", default-features = false, features = ["std"] } +cli = { version = "0.1.0", path = "../cli" } +env_logger = "0.9.0" futures = "0.3.17" +h2 = "=0.3.16" +k8s-openapi = { version = "0.13.1", features = ["v1_22"] } +kube = { version = "0.66.0", features = ["derive", "runtime"] } +log = "=0.4.15" +manager = { version = "0.1.0", path = "../manager" } +regex = "=1.7.3" +reqwest = { version = "=0.11.18", default-features = false, features = [ + "json", +] } +schemars = "=0.8.10" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.68" -thiserror = "1.0.29" -env_logger = "0.9.0" -schemars = "=0.8.10" socket2 = "=0.4.9" -log = "=0.4.15" +thiserror = "1.0.29" thread_local = "=1.1.4" -async-trait = "0.1" -regex = "=1.7.3" -chrono = { version = "0.4", default-features = false, features = ["std"] } -h2 = "=0.3.16" +tokio = { version = "=1.14.0", features = ["macros", "rt-multi-thread"] } tokio-retry = "0.3" -reqwest = { version = "=0.11.10", default-features = false, features = [ "json" ] } -cli = { version = "0.1.0", path = "../cli" } -manager = { version = "0.1.0", path = "../manager" } diff --git a/KubeOS-Rust/proxy/src/controller/agentclient.rs b/KubeOS-Rust/proxy/src/controller/agentclient.rs index 4d954ee8229ccf8da8fa8e74053724bbf0ac74d0..ddc4f29072b0504128d3dc2c0e62ac011b65e109 100644 --- a/KubeOS-Rust/proxy/src/controller/agentclient.rs +++ b/KubeOS-Rust/proxy/src/controller/agentclient.rs @@ -10,21 +10,18 @@ * See the Mulan PSL v2 for more details. */ +use std::{collections::HashMap, path::Path}; + +use agent_call::AgentCallClient; +use agent_error::Error; use cli::{ client::Client, method::{ - callable_method::RpcMethod, configure::ConfigureMethod, - prepare_upgrade::PrepareUpgradeMethod, rollback::RollbackMethod, upgrade::UpgradeMethod, + callable_method::RpcMethod, configure::ConfigureMethod, prepare_upgrade::PrepareUpgradeMethod, + rollback::RollbackMethod, upgrade::UpgradeMethod, }, }; - -use agent_call::AgentCallClient; -use agent_error::Error; -use manager::api::{ - ConfigureRequest, KeyInfo as AgentKeyInfo, Sysconfig as AgentSysconfig, UpgradeRequest, -}; -use std::collections::HashMap; -use std::path::Path; +use manager::api::{CertsInfo, ConfigureRequest, KeyInfo as AgentKeyInfo, Sysconfig as AgentSysconfig, UpgradeRequest}; pub struct UpgradeInfo { pub version: String, @@ -49,18 +46,10 @@ pub struct KeyInfo { } pub trait AgentMethod { - fn prepare_upgrade_method( - &self, - upgrade_info: UpgradeInfo, - agent_call: AgentCallClient, - ) -> Result<(), Error>; + fn prepare_upgrade_method(&self, upgrade_info: UpgradeInfo, agent_call: AgentCallClient) -> Result<(), Error>; fn upgrade_method(&self, agent_call: AgentCallClient) -> Result<(), Error>; fn rollback_method(&self, agent_call: AgentCallClient) -> Result<(), Error>; - fn configure_method( - &self, - config_info: ConfigInfo, - agent_call: AgentCallClient, - ) -> Result<(), Error>; + fn configure_method(&self, config_info: ConfigInfo, agent_call: AgentCallClient) -> Result<(), Error>; } pub mod agent_call { @@ -69,11 +58,7 @@ pub mod agent_call { pub struct AgentCallClient {} impl AgentCallClient { - pub fn call_agent( - &self, - client: &Client, - method: T, - ) -> Result<(), Error> { + pub fn call_agent(&self, client: &Client, method: T) -> Result<(), Error> { match method.call(client) { Ok(_resp) => Ok(()), Err(e) => Err(Error::AgentError { source: e }), @@ -88,62 +73,51 @@ pub struct AgentClient { impl AgentClient { pub fn new>(socket_path: P) -> Self { - AgentClient { - agent_client: Client::new(socket_path), - } + AgentClient { agent_client: Client::new(socket_path) } } } impl AgentMethod for AgentClient { - fn prepare_upgrade_method( - &self, - upgrade_info: UpgradeInfo, - agent_call: AgentCallClient, - ) -> Result<(), Error> { + fn prepare_upgrade_method(&self, upgrade_info: UpgradeInfo, agent_call: AgentCallClient) -> Result<(), Error> { let upgrade_request = UpgradeRequest { version: upgrade_info.version, image_type: upgrade_info.image_type, check_sum: upgrade_info.check_sum, container_image: upgrade_info.container_image, + // TODO: add image_url, flag_safe, mtls, certs + image_url: "".to_string(), + flag_safe: false, + mtls: false, + certs: CertsInfo { ca_cert: "".to_string(), client_cert: "".to_string(), client_key: "".to_string() }, }; - match agent_call.call_agent( - &self.agent_client, - PrepareUpgradeMethod::new(upgrade_request), - ) { + match agent_call.call_agent(&self.agent_client, PrepareUpgradeMethod::new(upgrade_request)) { Ok(_resp) => Ok(()), Err(e) => Err(e), } } fn upgrade_method(&self, agent_call: AgentCallClient) -> Result<(), Error> { - match agent_call.call_agent(&self.agent_client, UpgradeMethod::new()) { + match agent_call.call_agent(&self.agent_client, UpgradeMethod::default()) { Ok(_resp) => Ok(()), Err(e) => Err(e), } } fn rollback_method(&self, agent_call: AgentCallClient) -> Result<(), Error> { - match agent_call.call_agent(&self.agent_client, RollbackMethod::new()) { + match agent_call.call_agent(&self.agent_client, RollbackMethod::default()) { Ok(_resp) => Ok(()), Err(e) => Err(e), } } - fn configure_method( - &self, - config_info: ConfigInfo, - agent_call: AgentCallClient, - ) -> Result<(), Error> { + fn configure_method(&self, config_info: ConfigInfo, agent_call: AgentCallClient) -> Result<(), Error> { let mut agent_configs: Vec = Vec::new(); for config in config_info.configs { let mut contents_tmp: HashMap = HashMap::new(); for (key, key_info) in config.contents.iter() { contents_tmp.insert( key.to_string(), - AgentKeyInfo { - value: key_info.value.clone(), - operation: key_info.operation.clone(), - }, + AgentKeyInfo { value: key_info.value.clone(), operation: key_info.operation.clone() }, ); } agent_configs.push(AgentSysconfig { @@ -152,9 +126,7 @@ impl AgentMethod for AgentClient { contents: contents_tmp, }) } - let config_request = ConfigureRequest { - configs: agent_configs, - }; + let config_request = ConfigureRequest { configs: agent_configs }; match agent_call.call_agent(&self.agent_client, ConfigureMethod::new(config_request)) { Ok(_resp) => Ok(()), Err(e) => Err(e), diff --git a/KubeOS-Rust/proxy/src/controller/apiclient.rs b/KubeOS-Rust/proxy/src/controller/apiclient.rs index 5ee2800428687446f4260cdcc51ebe97c0425abc..3afd5a511506b96a1d4951cd754b4e84e3bfe5fa 100644 --- a/KubeOS-Rust/proxy/src/controller/apiclient.rs +++ b/KubeOS-Rust/proxy/src/controller/apiclient.rs @@ -10,8 +10,8 @@ * See the Mulan PSL v2 for more details. */ -use super::crd::{OSInstance, OSInstanceSpec, OSInstanceStatus}; -use super::values::{LABEL_OSINSTANCE, NODE_STATUS_IDLE, OSINSTANCE_API_VERSION, OSINSTANCE_KIND}; +use std::collections::BTreeMap; + use anyhow::Result; use apiclient_error::Error; use async_trait::async_trait; @@ -20,7 +20,11 @@ use kube::{ Client, }; use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; + +use super::{ + crd::{OSInstance, OSInstanceSpec, OSInstanceStatus}, + values::{LABEL_OSINSTANCE, NODE_STATUS_IDLE, OSINSTANCE_API_VERSION, OSINSTANCE_KIND}, +}; #[derive(Debug, Serialize, Deserialize)] struct OSInstanceSpecPatch { @@ -35,11 +39,7 @@ impl Default for OSInstanceSpecPatch { OSInstanceSpecPatch { api_version: OSINSTANCE_API_VERSION.to_string(), kind: OSINSTANCE_KIND.to_string(), - spec: OSInstanceSpec { - nodestatus: NODE_STATUS_IDLE.to_string(), - sysconfigs: None, - upgradeconfigs: None, - }, + spec: OSInstanceSpec { nodestatus: NODE_STATUS_IDLE.to_string(), sysconfigs: None, upgradeconfigs: None }, } } } @@ -57,10 +57,7 @@ impl Default for OSInstanceStatusPatch { OSInstanceStatusPatch { api_version: OSINSTANCE_API_VERSION.to_string(), kind: OSINSTANCE_KIND.to_string(), - status: Some(OSInstanceStatus { - sysconfigs: None, - upgradeconfigs: None, - }), + status: Some(OSInstanceStatus { sysconfigs: None, upgradeconfigs: None }), } } } @@ -105,11 +102,7 @@ impl ApplyApi for ControllerClient { labels: Some(labels), ..ObjectMeta::default() }, - spec: OSInstanceSpec { - nodestatus: NODE_STATUS_IDLE.to_string(), - sysconfigs: None, - upgradeconfigs: None, - }, + spec: OSInstanceSpec { nodestatus: NODE_STATUS_IDLE.to_string(), sysconfigs: None, upgradeconfigs: None }, status: None, }; let osi_api = Api::namespaced(self.client.clone(), namespace); @@ -124,17 +117,8 @@ impl ApplyApi for ControllerClient { spec: &OSInstanceSpec, ) -> Result<(), Error> { let osi_api: Api = Api::namespaced(self.client.clone(), namespace); - let osi_spec_patch = OSInstanceSpecPatch { - spec: spec.clone(), - ..Default::default() - }; - osi_api - .patch( - node_name, - &PatchParams::default(), - &Patch::Merge(&osi_spec_patch), - ) - .await?; + let osi_spec_patch = OSInstanceSpecPatch { spec: spec.clone(), ..Default::default() }; + osi_api.patch(node_name, &PatchParams::default(), &Patch::Merge(&osi_spec_patch)).await?; Ok(()) } @@ -145,17 +129,8 @@ impl ApplyApi for ControllerClient { status: &Option, ) -> Result<(), Error> { let osi_api: Api = Api::namespaced(self.client.clone(), namespace); - let osi_status_patch = OSInstanceStatusPatch { - status: status.clone(), - ..Default::default() - }; - osi_api - .patch_status( - node_name, - &PatchParams::default(), - &Patch::Merge(&osi_status_patch), - ) - .await?; + let osi_status_patch = OSInstanceStatusPatch { status: status.clone(), ..Default::default() }; + osi_api.patch_status(node_name, &PatchParams::default(), &Patch::Merge(&osi_status_patch)).await?; Ok(()) } } diff --git a/KubeOS-Rust/proxy/src/controller/controller.rs b/KubeOS-Rust/proxy/src/controller/controller.rs index da2e031e08baf29e5a84ff5dbd514f191aaf3e53..b23ec18772197bba322c902284c57133de74138a 100644 --- a/KubeOS-Rust/proxy/src/controller/controller.rs +++ b/KubeOS-Rust/proxy/src/controller/controller.rs @@ -10,19 +10,8 @@ * See the Mulan PSL v2 for more details. */ -use super::{ - agentclient::{ - agent_call::AgentCallClient, AgentMethod, ConfigInfo, KeyInfo, Sysconfig, UpgradeInfo, - }, - apiclient::ApplyApi, - crd::{Configs, Content, OSInstance, OS}, - drain::drain_os, - utils::{check_version, get_config_version, ConfigOperation, ConfigType}, - values::{ - LABEL_UPGRADING, NODE_STATUS_CONFIG, NODE_STATUS_IDLE, OPERATION_TYPE_ROLLBACK, - OPERATION_TYPE_UPGRADE, REQUEUE_ERROR, REQUEUE_NORMAL, - }, -}; +use std::{collections::HashMap, env}; + use anyhow::Result; use k8s_openapi::api::core::v1::Node; use kube::{ @@ -33,8 +22,18 @@ use kube::{ }; use log::{debug, error, info}; use reconciler_error::Error; -use std::collections::HashMap; -use std::env; + +use super::{ + agentclient::{agent_call::AgentCallClient, AgentMethod, ConfigInfo, KeyInfo, Sysconfig, UpgradeInfo}, + apiclient::ApplyApi, + crd::{Configs, Content, OSInstance, OS}, + drain::drain_os, + utils::{check_version, get_config_version, ConfigOperation, ConfigType}, + values::{ + LABEL_UPGRADING, NODE_STATUS_CONFIG, NODE_STATUS_IDLE, OPERATION_TYPE_ROLLBACK, OPERATION_TYPE_UPGRADE, + REQUEUE_ERROR, REQUEUE_NORMAL, + }, +}; pub async fn reconcile( os: OS, @@ -44,34 +43,22 @@ pub async fn reconcile( let proxy_controller = ctx.get_ref(); let os_cr = &os; let node_name = env::var("NODE_NAME")?; - let namespace: String = os_cr.namespace().ok_or(Error::MissingObjectKey { - resource: "os".to_string(), - value: "namespace".to_string(), - })?; - proxy_controller - .check_osi_exisit(&namespace, &node_name) - .await?; - let controller_res = proxy_controller - .get_resources(&namespace, &node_name) - .await?; + let namespace: String = os_cr + .namespace() + .ok_or(Error::MissingObjectKey { resource: "os".to_string(), value: "namespace".to_string() })?; + proxy_controller.check_osi_exisit(&namespace, &node_name).await?; + let controller_res = proxy_controller.get_resources(&namespace, &node_name).await?; let node = controller_res.node; let mut osinstance = controller_res.osinstance; let node_os_image = &node .status .as_ref() - .ok_or(Error::MissingSubResource { - value: String::from("node.status"), - })? + .ok_or(Error::MissingSubResource { value: String::from("node.status") })? .node_info .as_ref() - .ok_or(Error::MissingSubResource { - value: String::from("node.status.node_info"), - })? + .ok_or(Error::MissingSubResource { value: String::from("node.status.node_info") })? .os_image; - debug!( - "os expected osversion is {},actual osversion is {}", - os_cr.spec.osversion, node_os_image - ); + debug!("os expected osversion is {},actual osversion is {}", os_cr.spec.osversion, node_os_image); if check_version(&os_cr.spec.osversion, &node_os_image) { match ConfigType::SysConfig.check_config_version(&os, &osinstance) { ConfigOperation::Reassign => { @@ -85,7 +72,7 @@ pub async fn reconcile( ) .await?; return Ok(REQUEUE_NORMAL); - } + }, ConfigOperation::UpdateConfig => { debug!("start update config"); osinstance.spec.sysconfigs = os_cr.spec.sysconfigs.clone(); @@ -94,19 +81,12 @@ pub async fn reconcile( .update_osinstance_spec(&osinstance.name(), &namespace, &osinstance.spec) .await?; return Ok(REQUEUE_ERROR); - } - _ => {} + }, + _ => {}, } + proxy_controller.set_config(&mut osinstance, ConfigType::SysConfig).await?; proxy_controller - .set_config(&mut osinstance, ConfigType::SysConfig) - .await?; - proxy_controller - .refresh_node( - node, - osinstance, - &get_config_version(os_cr.spec.sysconfigs.as_ref()), - ConfigType::SysConfig, - ) + .refresh_node(node, osinstance, &get_config_version(os_cr.spec.sysconfigs.as_ref()), ConfigType::SysConfig) .await?; } else { if os_cr.spec.opstype == NODE_STATUS_CONFIG { @@ -124,8 +104,8 @@ pub async fn reconcile( ) .await?; return Ok(REQUEUE_NORMAL); - } - _ => {} + }, + _ => {}, } if node.labels().contains_key(LABEL_UPGRADING) { if osinstance.spec.nodestatus == NODE_STATUS_IDLE { @@ -142,9 +122,7 @@ pub async fn reconcile( .await?; return Ok(REQUEUE_NORMAL); } - proxy_controller - .set_config(&mut osinstance, ConfigType::UpgradeConfig) - .await?; + proxy_controller.set_config(&mut osinstance, ConfigType::UpgradeConfig).await?; proxy_controller.upgrade_node(os_cr, &node).await?; } } @@ -171,11 +149,7 @@ pub struct ProxyController { impl ProxyController { pub fn new(k8s_client: Client, controller_client: T, agent_client: U) -> Self { - ProxyController { - k8s_client, - controller_client, - agent_client, - } + ProxyController { k8s_client, controller_client, agent_client } } } @@ -186,31 +160,22 @@ impl ProxyController { Ok(osi) => { debug!("osinstance is exist {:?}", osi.name()); return Ok(()); - } + }, Err(kube::Error::Api(ErrorResponse { reason, .. })) if &reason == "NotFound" => { info!("Create OSInstance {}", node_name); - self.controller_client - .create_osinstance(node_name, namespace) - .await?; + self.controller_client.create_osinstance(node_name, namespace).await?; Ok(()) - } + }, Err(err) => Err(Error::KubeError { source: err }), } } - async fn get_resources( - &self, - namespace: &str, - node_name: &str, - ) -> Result { + async fn get_resources(&self, namespace: &str, node_name: &str) -> Result { let osi_api: Api = Api::namespaced(self.k8s_client.clone(), namespace); let osinstance_cr = osi_api.get(node_name).await?; let node_api: Api = Api::all(self.k8s_client.clone()); let node_cr = node_api.get(node_name).await?; - Ok(ControllerResources { - osinstance: osinstance_cr, - node: node_cr, - }) + Ok(ControllerResources { osinstance: osinstance_cr, node: node_cr }) } async fn refresh_node( @@ -225,9 +190,7 @@ impl ProxyController { let labels = node.labels_mut(); if labels.contains_key(LABEL_UPGRADING) { labels.remove(LABEL_UPGRADING); - node = node_api - .replace(&node.name(), &PostParams::default(), &node) - .await?; + node = node_api.replace(&node.name(), &PostParams::default(), &node).await?; } if let Some(node_spec) = &node.spec { if let Some(node_unschedulable) = node_spec.unschedulable { @@ -237,8 +200,7 @@ impl ProxyController { } } } - self.update_node_status(osinstance, os_config_version, config_type) - .await?; + self.update_node_status(osinstance, os_config_version, config_type).await?; Ok(()) } @@ -252,8 +214,7 @@ impl ProxyController { if osinstance.spec.nodestatus == NODE_STATUS_IDLE { return Ok(()); } - let upgradeconfig_spec_version = - get_config_version(osinstance.spec.upgradeconfigs.as_ref()); + let upgradeconfig_spec_version = get_config_version(osinstance.spec.upgradeconfigs.as_ref()); let sysconfig_spec_version = get_config_version(osinstance.spec.sysconfigs.as_ref()); let sysconfig_status_version: String; if let Some(osinstance_status) = osinstance.status.as_ref() { @@ -263,65 +224,46 @@ impl ProxyController { } if sysconfig_spec_version == sysconfig_status_version || (config_type == ConfigType::SysConfig && os_config_version != sysconfig_spec_version) - || (config_type == ConfigType::UpgradeConfig - && os_config_version != upgradeconfig_spec_version) + || (config_type == ConfigType::UpgradeConfig && os_config_version != upgradeconfig_spec_version) { let namespace = osinstance.namespace().ok_or(Error::MissingObjectKey { resource: String::from("osinstance"), value: String::from("namespace"), })?; osinstance.spec.nodestatus = NODE_STATUS_IDLE.to_string(); - self.controller_client - .update_osinstance_spec(&osinstance.name(), &namespace, &osinstance.spec) - .await?; + self.controller_client.update_osinstance_spec(&osinstance.name(), &namespace, &osinstance.spec).await?; } Ok(()) } - async fn update_osi_status( - &self, - osinstance: &mut OSInstance, - config_type: ConfigType, - ) -> Result<(), Error> { + async fn update_osi_status(&self, osinstance: &mut OSInstance, config_type: ConfigType) -> Result<(), Error> { debug!("start update_osi_status"); config_type.set_osi_status_config(osinstance); debug!("osinstance status is update to {:?}", osinstance.status); - let namespace = &osinstance.namespace().ok_or(Error::MissingObjectKey { - resource: "osinstance".to_string(), - value: "namespace".to_string(), - })?; - self.controller_client - .update_osinstance_status(&osinstance.name(), &namespace, &osinstance.status) - .await?; + let namespace = &osinstance + .namespace() + .ok_or(Error::MissingObjectKey { resource: "osinstance".to_string(), value: "namespace".to_string() })?; + self.controller_client.update_osinstance_status(&osinstance.name(), &namespace, &osinstance.status).await?; Ok(()) } - async fn set_config( - &self, - osinstance: &mut OSInstance, - config_type: ConfigType, - ) -> Result<(), Error> { + async fn set_config(&self, osinstance: &mut OSInstance, config_type: ConfigType) -> Result<(), Error> { debug!("start set_config"); let config_info = config_type.check_config_start(osinstance); if config_info.need_config { match config_info.configs.and_then(convert_to_agent_config) { Some(agent_configs) => { let agent_call_client = AgentCallClient::default(); - match self.agent_client.configure_method( - ConfigInfo { - configs: agent_configs, - }, - agent_call_client, - ) { - Ok(_resp) => {} + match self.agent_client.configure_method(ConfigInfo { configs: agent_configs }, agent_call_client) { + Ok(_resp) => {}, Err(e) => { return Err(Error::AgentError { source: e }); - } + }, } - } + }, None => { info!("config is none, no need to config"); - } + }, }; self.update_osi_status(osinstance, config_type).await?; } @@ -339,41 +281,34 @@ impl ProxyController { container_image: os_cr.spec.containerimage.clone(), }; let agent_call_client = AgentCallClient::default(); - match self - .agent_client - .prepare_upgrade_method(upgrade_info, agent_call_client) - { - Ok(_resp) => {} + match self.agent_client.prepare_upgrade_method(upgrade_info, agent_call_client) { + Ok(_resp) => {}, Err(e) => { return Err(Error::AgentError { source: e }); - } + }, } - self.evict_node(&node.name(), os_cr.spec.evictpodforce) - .await?; + self.evict_node(&node.name(), os_cr.spec.evictpodforce).await?; let agent_call_client = AgentCallClient::default(); match self.agent_client.upgrade_method(agent_call_client) { - Ok(_resp) => {} + Ok(_resp) => {}, Err(e) => { return Err(Error::AgentError { source: e }); - } + }, } - } + }, OPERATION_TYPE_ROLLBACK => { - self.evict_node(&node.name(), os_cr.spec.evictpodforce) - .await?; + self.evict_node(&node.name(), os_cr.spec.evictpodforce).await?; let agent_call_client = AgentCallClient::default(); match self.agent_client.rollback_method(agent_call_client) { - Ok(_resp) => {} + Ok(_resp) => {}, Err(e) => { return Err(Error::AgentError { source: e }); - } + }, } - } + }, _ => { - return Err(Error::OperationError { - value: os_cr.spec.opstype.clone(), - }); - } + return Err(Error::OperationError { value: os_cr.spec.opstype.clone() }); + }, } Ok(()) } @@ -384,12 +319,12 @@ impl ProxyController { node_api.cordon(node_name).await?; info!("Cordon node Successfully{}, start drain nodes", node_name); match self.drain_node(node_name, evict_pod_force).await { - Ok(()) => {} + Ok(()) => {}, Err(e) => { node_api.uncordon(node_name).await?; info!("Drain node {} error, uncordon node successfully", node_name); return Err(e); - } + }, } Ok(()) } @@ -397,9 +332,7 @@ impl ProxyController { async fn drain_node(&self, node_name: &str, force: bool) -> Result<(), Error> { use crate::controller::drain::error::DrainError::*; match drain_os(&self.k8s_client.clone(), node_name, force).await { - Err(DeletePodsError { errors, .. }) => Err(Error::DrainNodeError { - value: errors.join("; "), - }), + Err(DeletePodsError { errors, .. }) => Err(Error::DrainNodeError { value: errors.join("; ") }), _ => Ok(()), } } @@ -417,11 +350,15 @@ fn convert_to_agent_config(configs: Configs) -> Option> { contents: contents_tmp, }; agent_configs.push(config_tmp) - } + }, None => { - info!("model {} which has configpath {} do not has any contents no need to configure",config.model.unwrap_or_default(),config.configpath.unwrap_or_default()); + info!( + "model {} which has configpath {} do not has any contents no need to configure", + config.model.unwrap_or_default(), + config.configpath.unwrap_or_default() + ); continue; - } + }, }; } if agent_configs.len() == 0 { @@ -436,19 +373,17 @@ fn convert_to_agent_config(configs: Configs) -> Option> { fn convert_to_config_hashmap(contents: Vec) -> Option> { let mut contents_tmp: HashMap = HashMap::new(); for content in contents.into_iter() { - let key_info = KeyInfo { - value: content.value.unwrap_or_default(), - operation: content.operation.unwrap_or_default(), - }; + let key_info = + KeyInfo { value: content.value.unwrap_or_default(), operation: content.operation.unwrap_or_default() }; contents_tmp.insert(content.key.unwrap_or_default(), key_info); } return Some(contents_tmp); } pub mod reconciler_error { - use crate::controller::agentclient::agent_error; - use crate::controller::apiclient::apiclient_error; use thiserror::Error; + + use crate::controller::{agentclient::agent_error, apiclient::apiclient_error}; #[derive(Error, Debug)] pub enum Error { #[error("Kubernetes reported error: {source}")] diff --git a/KubeOS-Rust/proxy/src/controller/crd.rs b/KubeOS-Rust/proxy/src/controller/crd.rs index 9f01a964af81e57af0175ed090e77950ead78c7a..efec0bd806710cc1fa6d5f498c58201b5c7e5bfa 100644 --- a/KubeOS-Rust/proxy/src/controller/crd.rs +++ b/KubeOS-Rust/proxy/src/controller/crd.rs @@ -14,14 +14,7 @@ use kube::CustomResource; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(CustomResource, Debug, Clone, Deserialize, Serialize, JsonSchema)] -#[kube( - group = "upgrade.openeuler.org", - version = "v1alpha1", - kind = "OS", - plural = "os", - singular = "os", - namespaced -)] +#[kube(group = "upgrade.openeuler.org", version = "v1alpha1", kind = "OS", plural = "os", singular = "os", namespaced)] pub struct OSSpec { pub osversion: String, pub maxunavailable: i64, diff --git a/KubeOS-Rust/proxy/src/controller/drain.rs b/KubeOS-Rust/proxy/src/controller/drain.rs index f03284b9de37fc771799ac047ec3beb67e5a4933..ddc38aed4229c475d77b880cfe5cccd58dcd5bff 100644 --- a/KubeOS-Rust/proxy/src/controller/drain.rs +++ b/KubeOS-Rust/proxy/src/controller/drain.rs @@ -10,14 +10,6 @@ * See the Mulan PSL v2 for more details. */ -use self::error::{ - DrainError::{DeletePodsError, GetPodListsError, WaitDeletionError}, - EvictionError::{EvictionErrorNoRetry, EvictionErrorRetry}, -}; -use super::values::{ - EVERY_DELETION_CHECK, EVERY_EVICTION_RETRY, MAX_EVICT_POD_NUM, MAX_RETRIES_TIMES, - RETRY_BASE_DELAY, RETRY_MAX_DELAY, TIMEOUT, -}; use futures::{stream, StreamExt}; use k8s_openapi::api::core::v1::{Pod, PodSpec, PodStatus}; use kube::{ @@ -33,11 +25,16 @@ use tokio_retry::{ RetryIf, }; -pub async fn drain_os( - client: &Client, - node_name: &str, - force: bool, -) -> Result<(), error::DrainError> { +use self::error::{ + DrainError::{DeletePodsError, GetPodListsError, WaitDeletionError}, + EvictionError::{EvictionErrorNoRetry, EvictionErrorRetry}, +}; +use super::values::{ + EVERY_DELETION_CHECK, EVERY_EVICTION_RETRY, MAX_EVICT_POD_NUM, MAX_RETRIES_TIMES, RETRY_BASE_DELAY, + RETRY_MAX_DELAY, TIMEOUT, +}; + +pub async fn drain_os(client: &Client, node_name: &str, force: bool) -> Result<(), error::DrainError> { let pods_list = get_pods_deleted(client, node_name, force).await?; stream::iter(pods_list) @@ -59,19 +56,13 @@ async fn get_pods_deleted( node_name: &str, force: bool, ) -> Result, error::DrainError> { - let lp = ListParams { - field_selector: Some(format!("spec.nodeName={}", node_name)), - ..Default::default() - }; + let lp = ListParams { field_selector: Some(format!("spec.nodeName={}", node_name)), ..Default::default() }; let pods_api: Api = Api::all(client.clone()); let pods: ObjectList = match pods_api.list(&lp).await { Ok(pods @ ObjectList { .. }) => pods, Err(err) => { - return Err(GetPodListsError { - source: err, - node_name: node_name.to_string(), - }); - } + return Err(GetPodListsError { source: err, node_name: node_name.to_string() }); + }, }; let mut filterd_pods_list: Vec = Vec::new(); let mut filterd_err: Vec = Vec::new(); @@ -87,25 +78,16 @@ async fn get_pods_deleted( } } if filterd_err.len() > 0 { - return Err(DeletePodsError { - errors: filterd_err, - }); + return Err(DeletePodsError { errors: filterd_err }); } Ok(filterd_pods_list.into_iter()) } -async fn evict_pod( - k8s_client: &kube::Client, - pod: &Pod, - force: bool, -) -> Result<(), error::EvictionError> { +async fn evict_pod(k8s_client: &kube::Client, pod: &Pod, force: bool) -> Result<(), error::EvictionError> { let pod_api: Api = get_pod_api_with_namespace(k8s_client, pod); - let error_handling_strategy = if force { - ErrorHandleStrategy::RetryStrategy - } else { - ErrorHandleStrategy::TolerateStrategy - }; + let error_handling_strategy = + if force { ErrorHandleStrategy::RetryStrategy } else { ErrorHandleStrategy::TolerateStrategy }; RetryIf::spawn( error_handling_strategy.retry_strategy(), @@ -203,18 +185,14 @@ async fn wait_for_deletion(k8s_client: &kube::Client, pod: &Pod) -> Result<(), e let name = (&p).name_any(); info!("Pod {} deleted.", name); break; - } + }, Ok(_) => { - info!( - "Pod '{}' is not yet deleted. Waiting {}s.", - pod.name_any(), - EVERY_DELETION_CHECK.as_secs_f64() - ); - } + info!("Pod '{}' is not yet deleted. Waiting {}s.", pod.name_any(), EVERY_DELETION_CHECK.as_secs_f64()); + }, Err(kube::Error::Api(e)) if e.code == response_error_not_found => { info!("Pod {} is deleted.", pod.name_any()); break; - } + }, Err(e) => { error!( "Get pod {} reported error: '{}', whether pod is deleted cannot be determined, waiting {}s.", @@ -222,13 +200,10 @@ async fn wait_for_deletion(k8s_client: &kube::Client, pod: &Pod) -> Result<(), e e, EVERY_DELETION_CHECK.as_secs_f64() ); - } + }, } if start_time.elapsed() > TIMEOUT { - return Err(WaitDeletionError { - pod_name: pod.name_any(), - max_wait: TIMEOUT, - }); + return Err(WaitDeletionError { pod_name: pod.name_any(), max_wait: TIMEOUT }); } else { sleep(EVERY_DELETION_CHECK).await; } @@ -249,11 +224,7 @@ trait NameAny { impl NameAny for &Pod { fn name_any(self: &Self) -> String { - self.metadata - .name - .clone() - .or_else(|| self.metadata.generate_name.clone()) - .unwrap_or_default() + self.metadata.name.clone().or_else(|| self.metadata.generate_name.clone()).unwrap_or_default() } } trait PodFilter { @@ -264,11 +235,9 @@ struct FinishedOrFailedFilter {} impl PodFilter for FinishedOrFailedFilter { fn filter(self: &Self, pod: &Pod) -> Box { return match pod.status.as_ref() { - Some(PodStatus { - phase: Some(phase), .. - }) if phase == "Failed" || phase == "Succeeded" => { + Some(PodStatus { phase: Some(phase), .. }) if phase == "Failed" || phase == "Succeeded" => { FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay) - } + }, _ => FilterResult::create_filter_result(false, "", PodDeleteStatus::Okay), }; } @@ -279,50 +248,31 @@ struct DaemonFilter { } impl PodFilter for DaemonFilter { fn filter(self: &Self, pod: &Pod) -> Box { - if let FilterResult { result: true, .. } = - self.finished_or_failed_filter.filter(pod).as_ref() - { + if let FilterResult { result: true, .. } = self.finished_or_failed_filter.filter(pod).as_ref() { return FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay); } return match pod.metadata.owner_references.as_ref() { Some(owner_references) - if owner_references.iter().any(|reference| { - reference.controller.unwrap_or(false) && reference.kind == "DaemonSet" - }) => + if owner_references + .iter() + .any(|reference| reference.controller.unwrap_or(false) && reference.kind == "DaemonSet") => { if self.force { - let description = format!( - "Ignore Pod '{}': Pod is member of a DaemonSet", - pod.name_any() - ); - Box::new(FilterResult { - result: false, - desc: description, - status: PodDeleteStatus::Warning, - }) + let description = format!("Ignore Pod '{}': Pod is member of a DaemonSet", pod.name_any()); + Box::new(FilterResult { result: false, desc: description, status: PodDeleteStatus::Warning }) } else { - let description = format!( - "Cannot drain Pod '{}': Pod is member of a DaemonSet", - pod.name_any() - ); - Box::new(FilterResult { - result: false, - desc: description, - status: PodDeleteStatus::Error, - }) + let description = format!("Cannot drain Pod '{}': Pod is member of a DaemonSet", pod.name_any()); + Box::new(FilterResult { result: false, desc: description, status: PodDeleteStatus::Error }) } - } + }, _ => FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay), }; } } impl DaemonFilter { fn new(force: bool) -> DaemonFilter { - return DaemonFilter { - finished_or_failed_filter: FinishedOrFailedFilter {}, - force: force, - }; + return DaemonFilter { finished_or_failed_filter: FinishedOrFailedFilter {}, force: force }; } } @@ -331,16 +281,9 @@ impl PodFilter for MirrorFilter { fn filter(self: &Self, pod: &Pod) -> Box { return match pod.metadata.annotations.as_ref() { Some(annotations) if annotations.contains_key("kubernetes.io/config.mirror") => { - let description = format!( - "Ignore Pod '{}': Pod is a static Mirror Pod", - pod.name_any() - ); - FilterResult::create_filter_result( - false, - &description.to_string(), - PodDeleteStatus::Warning, - ) - } + let description = format!("Ignore Pod '{}': Pod is a static Mirror Pod", pod.name_any()); + FilterResult::create_filter_result(false, &description.to_string(), PodDeleteStatus::Warning) + }, _ => FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay), }; } @@ -352,49 +295,27 @@ struct LocalStorageFilter { } impl PodFilter for LocalStorageFilter { fn filter(self: &Self, pod: &Pod) -> Box { - if let FilterResult { result: true, .. } = - self.finished_or_failed_filter.filter(pod).as_ref() - { + if let FilterResult { result: true, .. } = self.finished_or_failed_filter.filter(pod).as_ref() { return FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay); } return match pod.spec.as_ref() { - Some(PodSpec { - volumes: Some(volumes), - .. - }) if volumes.iter().any(|volume| volume.empty_dir.is_some()) => { + Some(PodSpec { volumes: Some(volumes), .. }) if volumes.iter().any(|volume| volume.empty_dir.is_some()) => { if self.force { - let description = format!( - "Force draining Pod '{}': Pod has local storage", - pod.name_any() - ); - Box::new(FilterResult { - result: true, - desc: description, - status: PodDeleteStatus::Warning, - }) + let description = format!("Force draining Pod '{}': Pod has local storage", pod.name_any()); + Box::new(FilterResult { result: true, desc: description, status: PodDeleteStatus::Warning }) } else { - let description = format!( - "Cannot drain Pod '{}': Pod has local Storage", - pod.name_any() - ); - Box::new(FilterResult { - result: false, - desc: description, - status: PodDeleteStatus::Error, - }) + let description = format!("Cannot drain Pod '{}': Pod has local Storage", pod.name_any()); + Box::new(FilterResult { result: false, desc: description, status: PodDeleteStatus::Error }) } - } + }, _ => FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay), }; } } impl LocalStorageFilter { fn new(force: bool) -> LocalStorageFilter { - return LocalStorageFilter { - finished_or_failed_filter: FinishedOrFailedFilter {}, - force: force, - }; + return LocalStorageFilter { finished_or_failed_filter: FinishedOrFailedFilter {}, force: force }; } } struct UnreplicatedFilter { @@ -403,9 +324,7 @@ struct UnreplicatedFilter { } impl PodFilter for UnreplicatedFilter { fn filter(self: &Self, pod: &Pod) -> Box { - if let FilterResult { result: true, .. } = - self.finished_or_failed_filter.filter(pod).as_ref() - { + if let FilterResult { result: true, .. } = self.finished_or_failed_filter.filter(pod).as_ref() { return FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay); } @@ -417,27 +336,16 @@ impl PodFilter for UnreplicatedFilter { return if !is_replicated && self.force { let description = format!("Force drain Pod '{}': Pod is unreplicated", pod.name_any()); - Box::new(FilterResult { - result: true, - desc: description, - status: PodDeleteStatus::Warning, - }) + Box::new(FilterResult { result: true, desc: description, status: PodDeleteStatus::Warning }) } else { let description = format!("Cannot drain Pod '{}': Pod is unreplicated", pod.name_any()); - Box::new(FilterResult { - result: false, - desc: description, - status: PodDeleteStatus::Error, - }) + Box::new(FilterResult { result: false, desc: description, status: PodDeleteStatus::Error }) }; } } impl UnreplicatedFilter { fn new(force: bool) -> UnreplicatedFilter { - return UnreplicatedFilter { - finished_or_failed_filter: FinishedOrFailedFilter {}, - force: force, - }; + return UnreplicatedFilter { finished_or_failed_filter: FinishedOrFailedFilter {}, force: force }; } } @@ -450,11 +358,10 @@ impl PodFilter for DeletedFilter { return match pod.metadata.deletion_timestamp.as_ref() { Some(time) if time.0.timestamp() != 0 - && now - Duration::from_secs(time.0.timestamp() as u64) - >= self.delete_wait_timeout => + && now - Duration::from_secs(time.0.timestamp() as u64) >= self.delete_wait_timeout => { FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay) - } + }, _ => FilterResult::create_filter_result(true, "", PodDeleteStatus::Okay), }; } @@ -521,9 +428,7 @@ impl PodFilter for CombinedFilter { impl CombinedFilter { fn new(force: bool) -> CombinedFilter { return CombinedFilter { - deleted_filter: DeletedFilter { - delete_wait_timeout: TIMEOUT, - }, + deleted_filter: DeletedFilter { delete_wait_timeout: TIMEOUT }, daemon_filter: DaemonFilter::new(force), mirror_filter: MirrorFilter {}, local_storage_filter: LocalStorageFilter::new(force), @@ -544,16 +449,8 @@ struct FilterResult { status: PodDeleteStatus, } impl FilterResult { - fn create_filter_result( - result: bool, - desc: &str, - status: PodDeleteStatus, - ) -> Box { - Box::new(FilterResult { - result: result, - desc: desc.to_string(), - status: status, - }) + fn create_filter_result(result: bool, desc: &str, status: PodDeleteStatus) -> Box { + Box::new(FilterResult { result: result, desc: desc.to_string(), status: status }) } } @@ -564,14 +461,13 @@ enum ErrorHandleStrategy { impl ErrorHandleStrategy { fn retry_strategy(&self) -> impl Iterator { - let backoff = ExponentialBackoff::from_millis(RETRY_BASE_DELAY.as_millis() as u64) - .max_delay(RETRY_MAX_DELAY) - .map(jitter); + let backoff = + ExponentialBackoff::from_millis(RETRY_BASE_DELAY.as_millis() as u64).max_delay(RETRY_MAX_DELAY).map(jitter); return match self { Self::TolerateStrategy => { return backoff.take(0); - } + }, Self::RetryStrategy => backoff.take(MAX_RETRIES_TIMES), }; @@ -588,7 +484,7 @@ impl tokio_retry::Condition for ErrorHandleStrategy { } else { false } - } + }, } } } @@ -600,16 +496,10 @@ pub mod error { #[derive(Debug, Error)] pub enum DrainError { #[error("Get node {} pods list error reported: {}", node_name, source)] - GetPodListsError { - source: kube::Error, - node_name: String, - }, + GetPodListsError { source: kube::Error, node_name: String }, #[error("Pod '{}' was not deleted in the time allocated ({:.2}s).",pod_name,max_wait.as_secs_f64())] - WaitDeletionError { - pod_name: String, - max_wait: Duration, - }, + WaitDeletionError { pod_name: String, max_wait: Duration }, #[error("")] DeletePodsError { errors: Vec }, } @@ -617,15 +507,9 @@ pub mod error { #[derive(Debug, Error)] pub enum EvictionError { #[error("Evict Pod {} error: '{}'", pod_name, source)] - EvictionErrorRetry { - source: kube::Error, - pod_name: String, - }, + EvictionErrorRetry { source: kube::Error, pod_name: String }, #[error("Evict Pod {} error: '{}'", pod_name, source)] - EvictionErrorNoRetry { - source: kube::Error, - pod_name: String, - }, + EvictionErrorNoRetry { source: kube::Error, pod_name: String }, } } diff --git a/KubeOS-Rust/proxy/src/controller/utils.rs b/KubeOS-Rust/proxy/src/controller/utils.rs index 26a0d18a3196ea6ba5e8b6d9bc05b5fa8d025eff..78502db0a0435064f427d515a0d506130a146f55 100644 --- a/KubeOS-Rust/proxy/src/controller/utils.rs +++ b/KubeOS-Rust/proxy/src/controller/utils.rs @@ -10,10 +10,13 @@ * See the Mulan PSL v2 for more details. */ -use super::crd::{Configs, OSInstance, OSInstanceStatus, OS}; -use super::values::{NODE_STATUS_CONFIG, NODE_STATUS_IDLE, NODE_STATUS_UPGRADE}; use log::{debug, info}; +use super::{ + crd::{Configs, OSInstance, OSInstanceStatus, OS}, + values::{NODE_STATUS_CONFIG, NODE_STATUS_IDLE, NODE_STATUS_UPGRADE}, +}; + #[derive(PartialEq, Clone, Copy)] pub enum ConfigType { UpgradeConfig, @@ -42,14 +45,18 @@ impl ConfigType { match self { ConfigType::UpgradeConfig => { let os_config_version = get_config_version(os.spec.upgradeconfigs.as_ref()); - let osi_config_version = - get_config_version(osinstance.spec.upgradeconfigs.as_ref()); - debug!("=======os upgradeconfig version is{},osinstance spec upragdeconfig version is{}",os_config_version,osi_config_version); + let osi_config_version = get_config_version(osinstance.spec.upgradeconfigs.as_ref()); + debug!( + "=======os upgradeconfig version is{},osinstance spec upragdeconfig version is{}", + os_config_version, osi_config_version + ); if !check_version(&os_config_version, &osi_config_version) { - info!("os.spec.upgradeconfig.version is not equal to oninstance.spec.upragdeconfig.version, operation: reassgin upgrade to get newest upgradeconfigs"); + info!( + "os.spec.upgradeconfig.version is not equal to oninstance.spec.upragdeconfig.version, operation: reassgin upgrade to get newest upgradeconfigs" + ); return ConfigOperation::Reassign; } - } + }, ConfigType::SysConfig => { let os_config_version = get_config_version(os.spec.sysconfigs.as_ref()); let osi_config_version = get_config_version(osinstance.spec.sysconfigs.as_ref()); @@ -59,15 +66,19 @@ impl ConfigType { ); if !check_version(&os_config_version, &osi_config_version) { if node_status == NODE_STATUS_CONFIG { - info!("os.spec.sysconfig.version is not equal to oninstance.spec.sysconfig.version, operation: reassgin config to get newest sysconfigs"); + info!( + "os.spec.sysconfig.version is not equal to oninstance.spec.sysconfig.version, operation: reassgin config to get newest sysconfigs" + ); return ConfigOperation::Reassign; } if node_status == NODE_STATUS_UPGRADE { - info!("os.spec.sysconfig.version is not equal to oninstance.spec.sysconfig.version, operation: update osinstance.spec.sysconfig and reconcile"); + info!( + "os.spec.sysconfig.version is not equal to oninstance.spec.sysconfig.version, operation: update osinstance.spec.sysconfig and reconcile" + ); return ConfigOperation::UpdateConfig; } } - } + }, }; ConfigOperation::DoNothing } @@ -80,40 +91,30 @@ impl ConfigType { ConfigType::UpgradeConfig => { spec_config_version = get_config_version(osinstance.spec.upgradeconfigs.as_ref()); if let Some(osinstance_status) = osinstance.status.as_ref() { - status_config_version = - get_config_version(osinstance_status.upgradeconfigs.as_ref()); + status_config_version = get_config_version(osinstance_status.upgradeconfigs.as_ref()); } else { status_config_version = get_config_version(None); } configs = osinstance.spec.upgradeconfigs.clone(); - } + }, ConfigType::SysConfig => { spec_config_version = get_config_version(osinstance.spec.sysconfigs.as_ref()); if let Some(osinstance_status) = osinstance.status.as_ref() { - status_config_version = - get_config_version(osinstance_status.sysconfigs.as_ref()); + status_config_version = get_config_version(osinstance_status.sysconfigs.as_ref()); } else { status_config_version = get_config_version(None); } configs = osinstance.spec.sysconfigs.clone(); - } + }, } debug!( "=======osinstance soec config version is {},status config version is {}", spec_config_version, status_config_version ); - if spec_config_version != status_config_version - && osinstance.spec.nodestatus != NODE_STATUS_IDLE - { - return ConfigInfo { - need_config: true, - configs: configs, - }; + if spec_config_version != status_config_version && osinstance.spec.nodestatus != NODE_STATUS_IDLE { + return ConfigInfo { need_config: true, configs: configs }; } - return ConfigInfo { - need_config: false, - configs: None, - }; + return ConfigInfo { need_config: false, configs: None }; } pub fn set_osi_status_config(&self, osinstance: &mut OSInstance) { match self { @@ -126,17 +127,15 @@ impl ConfigType { sysconfigs: None, }) } - } + }, ConfigType::SysConfig => { if let Some(osi_status) = &mut osinstance.status { osi_status.sysconfigs = osinstance.spec.sysconfigs.clone(); } else { - osinstance.status = Some(OSInstanceStatus { - upgradeconfigs: None, - sysconfigs: osinstance.spec.sysconfigs.clone(), - }) + osinstance.status = + Some(OSInstanceStatus { upgradeconfigs: None, sysconfigs: osinstance.spec.sysconfigs.clone() }) } - } + }, } } } diff --git a/KubeOS-Rust/proxy/src/controller/values.rs b/KubeOS-Rust/proxy/src/controller/values.rs index f5d419656832056280f40a7803ae19cad67b96e1..fe43851ffc8e19c3a88ee68d49c8ffa17aaa13ba 100644 --- a/KubeOS-Rust/proxy/src/controller/values.rs +++ b/KubeOS-Rust/proxy/src/controller/values.rs @@ -28,13 +28,9 @@ pub const OPERATION_TYPE_ROLLBACK: &str = "rollback"; pub const SOCK_PATH: &str = "/run/os-agent/os-agent.sock"; -pub const REQUEUE_NORMAL: ReconcilerAction = ReconcilerAction { - requeue_after: Some(Duration::from_secs(15)), -}; +pub const REQUEUE_NORMAL: ReconcilerAction = ReconcilerAction { requeue_after: Some(Duration::from_secs(15)) }; -pub const REQUEUE_ERROR: ReconcilerAction = ReconcilerAction { - requeue_after: Some(Duration::from_secs(1)), -}; +pub const REQUEUE_ERROR: ReconcilerAction = ReconcilerAction { requeue_after: Some(Duration::from_secs(1)) }; pub const MAX_EVICT_POD_NUM: usize = 5; diff --git a/KubeOS-Rust/proxy/src/main.rs b/KubeOS-Rust/proxy/src/main.rs index ef53117dde8ed9a61654b60f5a102e48bea2db67..cd601d0fa8fa178f99c2e195d3c0f24d36029bed 100644 --- a/KubeOS-Rust/proxy/src/main.rs +++ b/KubeOS-Rust/proxy/src/main.rs @@ -20,30 +20,23 @@ use kube::{ }; use log::{error, info}; mod controller; -use controller::{ - error_policy, reconcile, AgentClient, ControllerClient, ProxyController, OS, SOCK_PATH, -}; +use controller::{error_policy, reconcile, AgentClient, ControllerClient, ProxyController, OS, SOCK_PATH}; const PROXY_VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); #[tokio::main] async fn main() -> Result<()> { - Builder::from_env(Env::default().default_filter_or("info")) - .target(Target::Stdout) - .init(); + Builder::from_env(Env::default().default_filter_or("info")).target(Target::Stdout).init(); let client = Client::try_default().await?; let os: Api = Api::all(client.clone()); let controller_client = ControllerClient::new(client.clone()); let agent_client = AgentClient::new(SOCK_PATH); let proxy_controller = ProxyController::new(client, controller_client, agent_client); - info!( - "os-proxy version is {}, start renconcile", - PROXY_VERSION.unwrap_or("Not Found") - ); + info!("os-proxy version is {}, start renconcile", PROXY_VERSION.unwrap_or("Not Found")); Controller::new(os, ListParams::default()) .run(reconcile, error_policy, Context::new(proxy_controller)) .for_each(|res| async move { match res { - Ok(_o) => {} + Ok(_o) => {}, Err(e) => error!("reconcile failed: {}", e.to_string()), } }) diff --git a/KubeOS-Rust/rustfmt.toml b/KubeOS-Rust/rustfmt.toml new file mode 100644 index 0000000000000000000000000000000000000000..3c565cf53340471a5ca004302bec88efe3bcc3cd --- /dev/null +++ b/KubeOS-Rust/rustfmt.toml @@ -0,0 +1,11 @@ +# cargo +nightly fmt +version = "Two" +use_small_heuristics = "MAX" +match_block_trailing_comma = true +newline_style = "Unix" +merge_derives = false +max_width = 120 +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +reorder_imports = true +unstable_features = true \ No newline at end of file