From 367a2c050304db73d72249e3baf872d2fd8015e8 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 27 Mar 2024 21:00:59 +0000 Subject: [PATCH 01/49] add in download from release channel --- Cargo.lock | 654 +++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 6 + PROGRESS.md | 4 +- README.md | 9 + src/lib.rs | 118 ++++++++- src/main.rs | 11 + src/release.rs | 66 ++++- 7 files changed, 840 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1343ce9..cf64094 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -50,6 +65,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "async-compression" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "atty" version = "0.2.14" @@ -109,6 +138,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.15.4" @@ -121,6 +171,27 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cc" version = "1.0.90" @@ -165,6 +236,19 @@ dependencies = [ "vec_map", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -190,6 +274,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -216,6 +309,21 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -235,12 +343,65 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -381,6 +542,25 @@ dependencies = [ "url", ] +[[package]] +name = "h2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -422,6 +602,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -429,7 +620,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -467,8 +681,8 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -480,6 +694,26 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -487,13 +721,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.28", "log", - "rustls", + "rustls 0.21.10", "rustls-native-certs", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.2.0", + "hyper-util", + "rustls 0.22.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "tower-service", ] [[package]] @@ -502,12 +753,48 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.28", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -551,6 +838,34 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "itoa" version = "1.0.11" @@ -625,17 +940,17 @@ dependencies = [ "either", "futures", "home", - "http", - "http-body", - "hyper", - "hyper-rustls", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", "hyper-timeout", "jsonpath-rust", "k8s-openapi", "kube-core", "pem", "pin-project", - "rustls", + "rustls 0.21.10", "rustls-pemfile", "secrecy", "serde", @@ -657,7 +972,7 @@ checksum = "b5bba93d054786eba7994d03ce522f368ef7d48c88a1826faa28478d85fb63ae" dependencies = [ "chrono", "form_urlencoded", - "http", + "http 0.2.12", "k8s-openapi", "once_cell", "serde", @@ -717,6 +1032,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.11" @@ -765,6 +1086,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -784,6 +1123,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.2" @@ -799,6 +1144,32 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -948,6 +1319,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "proc-macro2" version = "1.0.79" @@ -1004,6 +1381,56 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "reqwest" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +dependencies = [ + "async-compression", + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.2.0", + "hyper-rustls 0.26.0", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.22.3", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.25.0", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + [[package]] name = "ring" version = "0.17.8" @@ -1034,6 +1461,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "rustls" version = "0.21.10" @@ -1042,10 +1482,24 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -1067,6 +1521,12 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1077,6 +1537,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.17" @@ -1188,6 +1659,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -1269,6 +1752,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "2.0.55" @@ -1280,6 +1769,56 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -1373,13 +1912,34 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.10", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.3", + "rustls-pki-types", "tokio", ] @@ -1425,8 +1985,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "mime", "pin-project-lite", @@ -1551,14 +2111,20 @@ dependencies = [ name = "validator-lab" version = "0.0.1" dependencies = [ + "bzip2", "clap", + "console", "git2", + "indicatif", "k8s-openapi", "kube", "log", + "reqwest", "rustc_version", "solana-logger", + "tar", "tokio", + "url", ] [[package]] @@ -1619,6 +2185,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -1648,6 +2226,25 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1820,6 +2417,27 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index b66f78d..ba2d98d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,19 @@ license = "Apache-2.0" edition = "2021" [dependencies] +bzip2 = "0.4.4" clap = "2.33.1" +console = "0.15.8" git2 = "0.18.3" +indicatif = "0.17.8" k8s-openapi ={ version = "0.20.0", features = ["v1_28"] } kube = "0.87.2" log = "0.4.21" +reqwest = { version = "0.12.2", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } solana-logger = "1.18.7" +tar = "0.4.40" tokio = { version = "1.29.1", features = ["full"] } +url = "2.5.0" [build-dependencies] rustc_version = "0.4" diff --git a/PROGRESS.md b/PROGRESS.md index a9fb96b..ec7199a 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -9,9 +9,9 @@ ## Steps - [x] Connect to kubernetes endpoint and check if namespace exists -- [ ] Setup build config Local +- [x] Setup build config Local - [x] Build from local commit - - [ ] Build from tar (release version) + - [x] Build from tar (release version) - [ ] Create Genesis - [ ] Generate faucet and bootstrap accounts - [ ] Build genesis diff --git a/README.md b/README.md index 6fc337f..5785390 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,18 @@ kubectl create ns ``` ### Run +#### Build Agave from local agave repo ``` cargo run --bin cluster -- -n --deploy-method local --local-path ``` + +#### Build specific Agave release +``` +cargo run --bin cluster -- + -n + --deploy-method tar + --release-channel # note: MUST include the "v" +``` diff --git a/src/lib.rs b/src/lib.rs index d652f51..2c5f0f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,20 @@ -use std::{env, path::PathBuf}; +use { + bzip2::bufread::BzDecoder, + console::Emoji, + indicatif::{ProgressBar, ProgressStyle}, + log::*, + reqwest::Client, + std::{ + env, + error::Error, + fs::{self, File}, + io::{BufReader, Cursor, Read}, + path::{Path, PathBuf}, + time::Duration, + }, + tar::Archive, + url::Url, +}; #[macro_export] macro_rules! boxed_error { @@ -8,10 +24,7 @@ macro_rules! boxed_error { } pub fn get_solana_root() -> PathBuf { - PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")) - .parent() - .expect("Failed to get Solana root directory") - .to_path_buf() + PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")).to_path_buf() } pub struct SolanaRoot { @@ -38,3 +51,98 @@ impl SolanaRoot { pub mod kubernetes; pub mod release; + +static PACKAGE: Emoji = Emoji("📦 ", ""); +static TRUCK: Emoji = Emoji("🚚 ", ""); + +/// Creates a new process bar for processing that will take an unknown amount of time +pub fn new_spinner_progress_bar() -> ProgressBar { + let progress_bar = ProgressBar::new(42); + progress_bar.set_style( + ProgressStyle::default_spinner() + .template("{spinner:.green} {wide_msg}") + .expect("ProgresStyle::template direct input to be correct"), + ); + progress_bar.enable_steady_tick(Duration::from_millis(100)); + progress_bar +} + +pub fn cat_file(path: &PathBuf) -> std::io::Result<()> { + let mut file = File::open(path)?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + info!("version.yml:\n{}", contents); + + Ok(()) +} + +pub async fn download_to_temp( + url: &str, + file_name: &str, + solana_root_path: PathBuf, +) -> Result<(), Box> { + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!("{TRUCK}Downloading...")); + + let url = Url::parse(url).map_err(|err| format!("Unable to parse {url}: {err}"))?; + + let client = Client::builder() + .connect_timeout(Duration::from_secs(30)) + .https_only(false) + .build()?; + + let response = client.get(url.clone()).send().await?; + if !response.status().is_success() { + return Err(boxed_error!(format!( + "Failed to download release from url: {:?}, response body: {:?}", + url.to_string(), + response.text().await? + ))); + } + + let file_name: PathBuf = solana_root_path.join(file_name); + let mut out = File::create(file_name).expect("failed to create file"); + let mut content = Cursor::new(response.bytes().await?); + std::io::copy(&mut content, &mut out)?; + + progress_bar.finish_and_clear(); + Ok(()) +} + +pub fn extract_release_archive( + archive: &Path, + extract_dir: &Path, + file_name: &str, +) -> Result<(), Box> { + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!("{PACKAGE}Extracting...")); + + if extract_dir.exists() { + fs::remove_dir_all(extract_dir)?; + } + fs::create_dir_all(extract_dir)?; + + let tmp_extract_dir = extract_dir.with_file_name("tmp-extract"); + + if tmp_extract_dir.exists() { + let _ = fs::remove_dir_all(&tmp_extract_dir); + } + fs::create_dir_all(&tmp_extract_dir)?; + + let tar_bz2 = File::open(archive)?; + let tar = BzDecoder::new(BufReader::new(tar_bz2)); + let mut release = Archive::new(tar); + release.unpack(&tmp_extract_dir)?; + + for entry in tmp_extract_dir.join(file_name).read_dir()? { + let entry = entry?; + let entry_path = entry.path(); + let target_entry_path = extract_dir.join(entry_path.file_name().unwrap()); + fs::rename(entry_path, target_entry_path)?; + } + + // Remove the tmp-extract directory + fs::remove_dir_all(tmp_extract_dir)?; + progress_bar.finish_and_clear(); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index d3bbb45..4887e24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,13 @@ fn parse_matches() -> ArgMatches<'static> { .long("debug-build") .help("Enable debug build"), ) + .arg( + Arg::with_name("release_channel") + .long("release-channel") + .takes_value(true) + .required_if("deploy_method", "tar") // Require if deploy_method is "tar" + .help("release version. e.g. v1.17.2. Required if '--deploy-method tar'"), + ) .get_matches() } @@ -120,6 +127,10 @@ async fn main() { matches.is_present("skip_build"), matches.is_present("debug_build"), &solana_root.get_root_path(), + matches + .value_of("release_channel") + .unwrap_or_default() + .to_string(), ) .unwrap_or_else(|err| { panic!("Error creating BuildConfig: {}", err); diff --git a/src/release.rs b/src/release.rs index 7381663..5f89245 100644 --- a/src/release.rs +++ b/src/release.rs @@ -1,8 +1,8 @@ use { - crate::boxed_error, + crate::{boxed_error, cat_file, download_to_temp, extract_release_archive}, git2::Repository, log::*, - std::{error::Error, fmt::Display, path::PathBuf, str::FromStr, time::Instant}, + std::{error::Error, fmt::Display, fs, path::PathBuf, str::FromStr, time::Instant}, }; #[derive(Debug)] @@ -41,6 +41,7 @@ pub struct BuildConfig { debug_build: bool, _build_path: PathBuf, solana_root_path: PathBuf, + release_channel: String, } impl BuildConfig { @@ -49,6 +50,7 @@ impl BuildConfig { skip_build: bool, debug_build: bool, solana_root_path: &PathBuf, + release_channel: String, ) -> Result> { let deploy_method = deploy_method .parse::() @@ -66,13 +68,21 @@ impl BuildConfig { debug_build, _build_path: build_path, solana_root_path: solana_root_path.clone(), + release_channel, }) } pub async fn prepare(&self) -> Result<(), Box> { match self.deploy_method { DeployMethod::Tar => { - return Err(boxed_error!("Tar deploy method not implemented yet.")); + let file_name = "solana-release"; + match self.setup_tar_deploy(file_name).await { + Ok(tar_directory) => { + info!("Sucessfuly setup tar file"); + cat_file(&tar_directory.join("version.yml")).unwrap(); + } + Err(err) => return Err(err), + } } DeployMethod::Local => { self.setup_local_deploy()?; @@ -85,6 +95,23 @@ impl BuildConfig { Ok(()) } + async fn setup_tar_deploy(&self, file_name: &str) -> Result> { + let tar_file = format!("{}{}", file_name, ".tar.bz2"); + info!("tar file: {}", tar_file); + self.download_release_from_channel(file_name).await?; + + // Extract it and load the release version metadata + let tarball_filename = self.solana_root_path.join(tar_file); + let temp_release_dir = self.solana_root_path.join(file_name); + extract_release_archive(&tarball_filename, &temp_release_dir, file_name).map_err( + |err| { + format!("Unable to extract {tarball_filename:?} into {temp_release_dir:?}: {err}") + }, + )?; + + Ok(temp_release_dir) + } + fn setup_local_deploy(&self) -> Result<(), Box> { if !self.skip_build { self.build()?; @@ -145,4 +172,37 @@ impl BuildConfig { info!("Build took {:.3?} seconds", start_time.elapsed()); Ok(()) } + + async fn download_release_from_channel(&self, file_name: &str) -> Result<(), Box> { + info!("Downloading release from channel: {}", self.release_channel); + let tar_file = format!("{}{}", file_name, ".tar.bz2"); + let file_path = self.solana_root_path.join(tar_file.as_str()); + // Remove file + if let Err(err) = fs::remove_file(&file_path) { + if err.kind() != std::io::ErrorKind::NotFound { + return Err(boxed_error!(format!( + "{}: {:?}", + "Error while removing file:", err + ))); + } + } + + let download_url = format!( + "{}{}{}", + "https://release.solana.com/", + self.release_channel, + "/solana-release-x86_64-unknown-linux-gnu.tar.bz2" + ); + info!("download_url: {}", download_url); + + download_to_temp( + download_url.as_str(), + tar_file.as_str(), + self.solana_root_path.clone(), + ) + .await + .map_err(|err| format!("Unable to download {download_url}. Error: {err}"))?; + + Ok(()) + } } From bcfbde6fdc28e0f8b14bdc5817c8714fef0ae3fd Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 30 Mar 2024 01:35:58 +0000 Subject: [PATCH 02/49] change how tar tar is downloaded and unpacked --- Cargo.lock | 74 ++++++++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- src/lib.rs | 37 ++++++------------------- src/main.rs | 23 ++++++++-------- src/release.rs | 61 ++++++++++++++++++++++++----------------- 5 files changed, 101 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf64094..eace9f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,15 +56,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "async-compression" version = "0.4.6" @@ -223,17 +214,27 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "ansi_term", "atty", "bitflags 1.3.2", + "clap_lex", + "indexmap 1.9.3", + "once_cell", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -554,13 +555,19 @@ dependencies = [ "futures-sink", "futures-util", "http 1.1.0", - "indexmap", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" @@ -828,6 +835,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.2.6" @@ -835,7 +852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", ] [[package]] @@ -1197,6 +1214,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1677,7 +1700,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -1748,9 +1771,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" @@ -1830,12 +1853,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" @@ -2133,12 +2153,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index ba2d98d..c627fb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" [dependencies] bzip2 = "0.4.4" -clap = "2.33.1" +clap = { version = "3.2.22", features = ["cargo"] } console = "0.15.8" git2 = "0.18.3" indicatif = "0.17.8" diff --git a/src/lib.rs b/src/lib.rs index 2c5f0f6..9786bb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ use { std::{ env, error::Error, - fs::{self, File}, + fs::File, io::{BufReader, Cursor, Read}, path::{Path, PathBuf}, time::Duration, @@ -71,7 +71,7 @@ pub fn cat_file(path: &PathBuf) -> std::io::Result<()> { let mut file = File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; - info!("version.yml:\n{}", contents); + info!("{:?}:\n{}", path.file_name(), contents); Ok(()) } @@ -110,39 +110,20 @@ pub async fn download_to_temp( } pub fn extract_release_archive( - archive: &Path, + tarball_filename: &Path, extract_dir: &Path, - file_name: &str, ) -> Result<(), Box> { let progress_bar = new_spinner_progress_bar(); progress_bar.set_message(format!("{PACKAGE}Extracting...")); - if extract_dir.exists() { - fs::remove_dir_all(extract_dir)?; - } - fs::create_dir_all(extract_dir)?; - - let tmp_extract_dir = extract_dir.with_file_name("tmp-extract"); + let tarball_file = File::open(tarball_filename)?; + let decompressed = BzDecoder::new(BufReader::new(tarball_file)); + let mut archive = Archive::new(decompressed); - if tmp_extract_dir.exists() { - let _ = fs::remove_dir_all(&tmp_extract_dir); - } - fs::create_dir_all(&tmp_extract_dir)?; - - let tar_bz2 = File::open(archive)?; - let tar = BzDecoder::new(BufReader::new(tar_bz2)); - let mut release = Archive::new(tar); - release.unpack(&tmp_extract_dir)?; - - for entry in tmp_extract_dir.join(file_name).read_dir()? { - let entry = entry?; - let entry_path = entry.path(); - let target_entry_path = extract_dir.join(entry_path.file_name().unwrap()); - fs::rename(entry_path, target_entry_path)?; - } + // Unpack the archive into extract_dir + archive.unpack(extract_dir)?; - // Remove the tmp-extract directory - fs::remove_dir_all(tmp_extract_dir)?; progress_bar.finish_and_clear(); + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 4887e24..ebf1a89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use { - clap::{crate_description, crate_name, App, Arg, ArgMatches}, + clap::{command, Arg}, log::*, std::fs, validator_lab::{ @@ -9,13 +9,12 @@ use { }, }; -fn parse_matches() -> ArgMatches<'static> { - App::new(crate_name!()) - .about(crate_description!()) +fn parse_matches() -> clap::ArgMatches { + command!() .arg( - Arg::with_name("cluster_namespace") + Arg::new("cluster_namespace") .long("namespace") - .short("n") + .short('n') .takes_value(true) .default_value("default") .help("namespace to deploy test cluster"), @@ -29,11 +28,11 @@ fn parse_matches() -> ArgMatches<'static> { .help("Deploy method. tar, local, skip. [default: local]"), ) .arg( - Arg::with_name("local-path") + Arg::new("local_path") .long("local-path") .takes_value(true) - .required_if("deploy-method", "local") - .conflicts_with_all(&["tar", "skip"]) + .required_if("deploy_method", "local") + .conflicts_with("release_channel") .help("Path to local agave repo. Required for 'local' deploy method."), ) .arg( @@ -50,7 +49,7 @@ fn parse_matches() -> ArgMatches<'static> { Arg::with_name("release_channel") .long("release-channel") .takes_value(true) - .required_if("deploy_method", "tar") // Require if deploy_method is "tar" + .conflicts_with("local_path") .help("release version. e.g. v1.17.2. Required if '--deploy-method tar'"), ) .get_matches() @@ -73,7 +72,7 @@ async fn main() { }; let deploy_method = matches.value_of("deploy_method").unwrap(); - let local_path = matches.value_of("local-path"); + let local_path = matches.value_of("local_path"); match deploy_method { method if method == DeployMethod::Local.to_string() => { if local_path.is_none() { @@ -87,7 +86,7 @@ async fn main() { } } - let solana_root = match matches.value_of("local-path") { + let solana_root = match matches.value_of("local_path") { Some(path) => SolanaRoot::new_from_path(path.into()), None => SolanaRoot::default(), }; diff --git a/src/release.rs b/src/release.rs index 5f89245..9c5502a 100644 --- a/src/release.rs +++ b/src/release.rs @@ -12,6 +12,19 @@ pub enum DeployMethod { Skip, } +// #[derive(Debug)] +// enum DeployMethod2 { +// Local(String), +// ReleaseChannel(String), +// Skip, +// } + +// enum Build { +// Skip, +// Debug, +// Release, +// } + impl Display for DeployMethod { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -74,16 +87,13 @@ impl BuildConfig { pub async fn prepare(&self) -> Result<(), Box> { match self.deploy_method { - DeployMethod::Tar => { - let file_name = "solana-release"; - match self.setup_tar_deploy(file_name).await { - Ok(tar_directory) => { - info!("Sucessfuly setup tar file"); - cat_file(&tar_directory.join("version.yml")).unwrap(); - } - Err(err) => return Err(err), + DeployMethod::Tar => match self.setup_tar_deploy().await { + Ok(tar_directory) => { + info!("Successfully setup tar file"); + cat_file(&tar_directory.join("version.yml")).unwrap(); } - } + Err(err) => return Err(err), + }, DeployMethod::Local => { self.setup_local_deploy()?; } @@ -95,21 +105,20 @@ impl BuildConfig { Ok(()) } - async fn setup_tar_deploy(&self, file_name: &str) -> Result> { - let tar_file = format!("{}{}", file_name, ".tar.bz2"); - info!("tar file: {}", tar_file); - self.download_release_from_channel(file_name).await?; + async fn setup_tar_deploy(&self) -> Result> { + let file_name = "solana-release"; + let tar_filename = format!("{file_name}.tar.bz2"); + info!("tar file: {}", tar_filename); + self.download_release_from_channel(&tar_filename).await?; // Extract it and load the release version metadata - let tarball_filename = self.solana_root_path.join(tar_file); - let temp_release_dir = self.solana_root_path.join(file_name); - extract_release_archive(&tarball_filename, &temp_release_dir, file_name).map_err( - |err| { - format!("Unable to extract {tarball_filename:?} into {temp_release_dir:?}: {err}") - }, - )?; + let tarball_filename = self.solana_root_path.join(&tar_filename); + let release_dir = self.solana_root_path.join(file_name); + extract_release_archive(&tarball_filename, &self.solana_root_path).map_err(|err| { + format!("Unable to extract {tar_filename} into {release_dir:?}: {err}") + })?; - Ok(temp_release_dir) + Ok(release_dir) } fn setup_local_deploy(&self) -> Result<(), Box> { @@ -173,10 +182,12 @@ impl BuildConfig { Ok(()) } - async fn download_release_from_channel(&self, file_name: &str) -> Result<(), Box> { + async fn download_release_from_channel( + &self, + tar_filename: &str, + ) -> Result<(), Box> { info!("Downloading release from channel: {}", self.release_channel); - let tar_file = format!("{}{}", file_name, ".tar.bz2"); - let file_path = self.solana_root_path.join(tar_file.as_str()); + let file_path = self.solana_root_path.join(tar_filename); // Remove file if let Err(err) = fs::remove_file(&file_path) { if err.kind() != std::io::ErrorKind::NotFound { @@ -197,7 +208,7 @@ impl BuildConfig { download_to_temp( download_url.as_str(), - tar_file.as_str(), + tar_filename, self.solana_root_path.clone(), ) .await From 239fb4d3d762ea771eaab0e98998e171dee08d94 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 30 Mar 2024 01:39:27 +0000 Subject: [PATCH 03/49] remove boxed_error. cast to dyn Error --- src/lib.rs | 13 +++---------- src/release.rs | 11 ++++------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9786bb4..250be20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,6 @@ use { reqwest::Client, std::{ env, - error::Error, fs::File, io::{BufReader, Cursor, Read}, path::{Path, PathBuf}, @@ -16,13 +15,6 @@ use { url::Url, }; -#[macro_export] -macro_rules! boxed_error { - ($message:expr) => { - Box::new(std::io::Error::new(std::io::ErrorKind::Other, $message)) as Box - }; -} - pub fn get_solana_root() -> PathBuf { PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")).to_path_buf() } @@ -93,11 +85,12 @@ pub async fn download_to_temp( let response = client.get(url.clone()).send().await?; if !response.status().is_success() { - return Err(boxed_error!(format!( + return Err(format!( "Failed to download release from url: {:?}, response body: {:?}", url.to_string(), response.text().await? - ))); + ) + .into()); } let file_name: PathBuf = solana_root_path.join(file_name); diff --git a/src/release.rs b/src/release.rs index 9c5502a..0d94edd 100644 --- a/src/release.rs +++ b/src/release.rs @@ -1,5 +1,5 @@ use { - crate::{boxed_error, cat_file, download_to_temp, extract_release_archive}, + crate::{cat_file, download_to_temp, extract_release_archive}, git2::Repository, log::*, std::{error::Error, fmt::Display, fs, path::PathBuf, str::FromStr, time::Instant}, @@ -98,7 +98,7 @@ impl BuildConfig { self.setup_local_deploy()?; } DeployMethod::Skip => { - return Err(boxed_error!("Skip deploy method not implemented yet.")); + return Err("Skip deploy method not implemented yet.".into()); } } info!("Completed Prepare Deploy"); @@ -146,7 +146,7 @@ impl BuildConfig { if result.success() { info!("Successfully built validator") } else { - return Err(boxed_error!("Failed to build validator")); + return Err("Failed to build validator".into()); } } Err(err) => return Err(Box::new(err)), @@ -191,10 +191,7 @@ impl BuildConfig { // Remove file if let Err(err) = fs::remove_file(&file_path) { if err.kind() != std::io::ErrorKind::NotFound { - return Err(boxed_error!(format!( - "{}: {:?}", - "Error while removing file:", err - ))); + return Err(format!("{}: {:?}", "Error while removing file:", err).into()); } } From c13e85140d38678e12eee4b11f969f8a17446772 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 30 Mar 2024 02:20:50 +0000 Subject: [PATCH 04/49] update DeployMethod. remove --deploy-method flag --- README.md | 2 -- src/main.rs | 44 +++++++++--------------------- src/release.rs | 72 +++++++++++--------------------------------------- 3 files changed, 27 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 5785390..0580e91 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ kubectl create ns ``` cargo run --bin cluster -- -n - --deploy-method local --local-path ``` @@ -34,6 +33,5 @@ cargo run --bin cluster -- ``` cargo run --bin cluster -- -n - --deploy-method tar --release-channel # note: MUST include the "v" ``` diff --git a/src/main.rs b/src/main.rs index ebf1a89..934dd74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,21 +19,12 @@ fn parse_matches() -> clap::ArgMatches { .default_value("default") .help("namespace to deploy test cluster"), ) - .arg( - Arg::with_name("deploy_method") - .long("deploy-method") - .takes_value(true) - .possible_values(&["local", "tar", "skip"]) - .default_value("local") - .help("Deploy method. tar, local, skip. [default: local]"), - ) .arg( Arg::new("local_path") .long("local-path") .takes_value(true) - .required_if("deploy_method", "local") .conflicts_with("release_channel") - .help("Path to local agave repo. Required for 'local' deploy method."), + .help("Build validator from local Agave repo. Specify path here."), ) .arg( Arg::with_name("skip_build") @@ -50,7 +41,7 @@ fn parse_matches() -> clap::ArgMatches { .long("release-channel") .takes_value(true) .conflicts_with("local_path") - .help("release version. e.g. v1.17.2. Required if '--deploy-method tar'"), + .help("Pulls specific release version. e.g. v1.17.2"), ) .get_matches() } @@ -71,24 +62,17 @@ async fn main() { namespace: matches.value_of("cluster_namespace").unwrap_or_default(), }; - let deploy_method = matches.value_of("deploy_method").unwrap(); - let local_path = matches.value_of("local_path"); - match deploy_method { - method if method == DeployMethod::Local.to_string() => { - if local_path.is_none() { - panic!("Error: --local-path is required for 'local' deploy-method."); - } - } - _ => { - if local_path.is_some() { - warn!("WARN: --local-path will be ignored"); - } - } - } + let deploy_method = if let Some(local_path) = matches.value_of("local_path") { + DeployMethod::Local(local_path.to_owned()) + } else if let Some(release_channel) = matches.value_of("release_channel") { + DeployMethod::ReleaseChannel(release_channel.to_owned()) + } else { + DeployMethod::Skip + }; - let solana_root = match matches.value_of("local_path") { - Some(path) => SolanaRoot::new_from_path(path.into()), - None => SolanaRoot::default(), + let solana_root = match &deploy_method { + DeployMethod::Local(path) => SolanaRoot::new_from_path(path.into()), + DeployMethod::ReleaseChannel(_) | DeployMethod::Skip => SolanaRoot::default(), }; if let Ok(metadata) = fs::metadata(solana_root.get_root_path()) { @@ -126,10 +110,6 @@ async fn main() { matches.is_present("skip_build"), matches.is_present("debug_build"), &solana_root.get_root_path(), - matches - .value_of("release_channel") - .unwrap_or_default() - .to_string(), ) .unwrap_or_else(|err| { panic!("Error creating BuildConfig: {}", err); diff --git a/src/release.rs b/src/release.rs index 0d94edd..a180854 100644 --- a/src/release.rs +++ b/src/release.rs @@ -2,76 +2,34 @@ use { crate::{cat_file, download_to_temp, extract_release_archive}, git2::Repository, log::*, - std::{error::Error, fmt::Display, fs, path::PathBuf, str::FromStr, time::Instant}, + std::{error::Error, fs, path::PathBuf, time::Instant}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum DeployMethod { - Local, - Tar, + Local(String), + ReleaseChannel(String), Skip, } -// #[derive(Debug)] -// enum DeployMethod2 { -// Local(String), -// ReleaseChannel(String), -// Skip, -// } - -// enum Build { -// Skip, -// Debug, -// Release, -// } - -impl Display for DeployMethod { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - DeployMethod::Local => write!(f, "local"), - DeployMethod::Tar => write!(f, "tar"), - DeployMethod::Skip => write!(f, "skip"), - } - } -} - -impl FromStr for DeployMethod { - type Err = (); - - fn from_str(s: &str) -> Result { - match s { - "local" => Ok(DeployMethod::Local), - "tar" => Ok(DeployMethod::Tar), - "skip" => Ok(DeployMethod::Skip), - _ => Err(()), - } - } -} - pub struct BuildConfig { deploy_method: DeployMethod, skip_build: bool, debug_build: bool, _build_path: PathBuf, solana_root_path: PathBuf, - release_channel: String, } impl BuildConfig { pub fn new( - deploy_method: &str, + deploy_method: DeployMethod, skip_build: bool, debug_build: bool, solana_root_path: &PathBuf, - release_channel: String, ) -> Result> { - let deploy_method = deploy_method - .parse::() - .map_err(|_| "Failed to parse deploy_method".to_string())?; - let build_path = match deploy_method { - DeployMethod::Local => solana_root_path.join("farf/bin"), - DeployMethod::Tar => solana_root_path.join("solana-release/bin"), + DeployMethod::Local(_) => solana_root_path.join("farf/bin"), + DeployMethod::ReleaseChannel(_) => solana_root_path.join("solana-release/bin"), DeployMethod::Skip => solana_root_path.join("farf/bin"), }; @@ -81,20 +39,19 @@ impl BuildConfig { debug_build, _build_path: build_path, solana_root_path: solana_root_path.clone(), - release_channel, }) } pub async fn prepare(&self) -> Result<(), Box> { - match self.deploy_method { - DeployMethod::Tar => match self.setup_tar_deploy().await { + match &self.deploy_method { + DeployMethod::ReleaseChannel(channel) => match self.setup_tar_deploy(channel).await { Ok(tar_directory) => { info!("Successfully setup tar file"); cat_file(&tar_directory.join("version.yml")).unwrap(); } Err(err) => return Err(err), }, - DeployMethod::Local => { + DeployMethod::Local(_) => { self.setup_local_deploy()?; } DeployMethod::Skip => { @@ -105,11 +62,11 @@ impl BuildConfig { Ok(()) } - async fn setup_tar_deploy(&self) -> Result> { + async fn setup_tar_deploy(&self, release_channel: &String) -> Result> { let file_name = "solana-release"; let tar_filename = format!("{file_name}.tar.bz2"); info!("tar file: {}", tar_filename); - self.download_release_from_channel(&tar_filename).await?; + self.download_release_from_channel(&tar_filename, release_channel).await?; // Extract it and load the release version metadata let tarball_filename = self.solana_root_path.join(&tar_filename); @@ -185,8 +142,9 @@ impl BuildConfig { async fn download_release_from_channel( &self, tar_filename: &str, + release_channel: &String, ) -> Result<(), Box> { - info!("Downloading release from channel: {}", self.release_channel); + info!("Downloading release from channel: {}", release_channel); let file_path = self.solana_root_path.join(tar_filename); // Remove file if let Err(err) = fs::remove_file(&file_path) { @@ -198,7 +156,7 @@ impl BuildConfig { let download_url = format!( "{}{}{}", "https://release.solana.com/", - self.release_channel, + release_channel, "/solana-release-x86_64-unknown-linux-gnu.tar.bz2" ); info!("download_url: {}", download_url); From 0dd8967f4af5811883fd7aec62c76f271e0fae7f Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 30 Mar 2024 02:47:52 +0000 Subject: [PATCH 05/49] add buildtype enum --- src/main.rs | 33 +++++++++++++++------------------ src/release.rs | 44 +++++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 934dd74..0e6e141 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use { std::fs, validator_lab::{ kubernetes::Kubernetes, - release::{BuildConfig, DeployMethod}, + release::{BuildConfig, BuildType, DeployMethod}, SolanaRoot, }, }; @@ -27,14 +27,12 @@ fn parse_matches() -> clap::ArgMatches { .help("Build validator from local Agave repo. Specify path here."), ) .arg( - Arg::with_name("skip_build") - .long("skip-build") - .help("Disable building for building from local repo"), - ) - .arg( - Arg::with_name("debug_build") - .long("debug-build") - .help("Enable debug build"), + Arg::new("build_type") + .long("build-type") + .takes_value(true) + .possible_values(&["skip", "debug", "release"]) + .default_value("release") + .help("Specifies the build type: skip, debug, or release."), ) .arg( Arg::with_name("release_channel") @@ -75,6 +73,10 @@ async fn main() { DeployMethod::ReleaseChannel(_) | DeployMethod::Skip => SolanaRoot::default(), }; + let build_type: BuildType = matches + .value_of_t("build_type") + .unwrap_or_else(|e| e.exit()); + if let Ok(metadata) = fs::metadata(solana_root.get_root_path()) { if !metadata.is_dir() { return error!( @@ -105,15 +107,10 @@ async fn main() { } } - let build_config = BuildConfig::new( - deploy_method, - matches.is_present("skip_build"), - matches.is_present("debug_build"), - &solana_root.get_root_path(), - ) - .unwrap_or_else(|err| { - panic!("Error creating BuildConfig: {}", err); - }); + let build_config = BuildConfig::new(deploy_method, build_type, &solana_root.get_root_path()) + .unwrap_or_else(|err| { + panic!("Error creating BuildConfig: {}", err); + }); match build_config.prepare().await { Ok(_) => info!("Validator setup prepared successfully"), diff --git a/src/release.rs b/src/release.rs index a180854..773a1dc 100644 --- a/src/release.rs +++ b/src/release.rs @@ -2,7 +2,7 @@ use { crate::{cat_file, download_to_temp, extract_release_archive}, git2::Repository, log::*, - std::{error::Error, fs, path::PathBuf, time::Instant}, + std::{error::Error, fs, path::PathBuf, str::FromStr, time::Instant}, }; #[derive(Debug, Clone)] @@ -12,10 +12,29 @@ pub enum DeployMethod { Skip, } +#[derive(PartialEq)] +pub enum BuildType { + Skip, + Debug, + Release, +} + +impl FromStr for BuildType { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "skip" => Ok(BuildType::Skip), + "debug" => Ok(BuildType::Debug), + "release" => Ok(BuildType::Release), + _ => Err("invalid string"), + } + } +} + pub struct BuildConfig { deploy_method: DeployMethod, - skip_build: bool, - debug_build: bool, + build_type: BuildType, _build_path: PathBuf, solana_root_path: PathBuf, } @@ -23,8 +42,7 @@ pub struct BuildConfig { impl BuildConfig { pub fn new( deploy_method: DeployMethod, - skip_build: bool, - debug_build: bool, + build_type: BuildType, solana_root_path: &PathBuf, ) -> Result> { let build_path = match deploy_method { @@ -35,8 +53,7 @@ impl BuildConfig { Ok(BuildConfig { deploy_method, - skip_build, - debug_build, + build_type, _build_path: build_path, solana_root_path: solana_root_path.clone(), }) @@ -66,7 +83,8 @@ impl BuildConfig { let file_name = "solana-release"; let tar_filename = format!("{file_name}.tar.bz2"); info!("tar file: {}", tar_filename); - self.download_release_from_channel(&tar_filename, release_channel).await?; + self.download_release_from_channel(&tar_filename, release_channel) + .await?; // Extract it and load the release version metadata let tarball_filename = self.solana_root_path.join(&tar_filename); @@ -79,17 +97,21 @@ impl BuildConfig { } fn setup_local_deploy(&self) -> Result<(), Box> { - if !self.skip_build { + if self.build_type != BuildType::Skip { self.build()?; } else { - info!("Build skipped due to --skip-build"); + info!("Build skipped due to --build-type skip"); } Ok(()) } fn build(&self) -> Result<(), Box> { let start_time = Instant::now(); - let build_variant = if self.debug_build { "--debug" } else { "" }; + let build_variant = if self.build_type == BuildType::Debug { + "--debug" + } else { + "" + }; let install_directory = self.solana_root_path.join("farf"); let install_script = self.solana_root_path.join("scripts/cargo-install-all.sh"); From 13d6d71e4fe1515e56706828e77ee980e4168cc9 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 17:42:44 +0000 Subject: [PATCH 06/49] rm Skip DeployMethod. use strum --- Cargo.lock | 33 +++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/main.rs | 16 +++++++++++----- src/release.rs | 26 +++++--------------------- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eace9f8..d345c2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -574,6 +574,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1571,6 +1577,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.17" @@ -1775,6 +1787,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "subtle" version = "2.5.0" @@ -2142,6 +2173,8 @@ dependencies = [ "reqwest", "rustc_version", "solana-logger", + "strum", + "strum_macros", "tar", "tokio", "url", diff --git a/Cargo.toml b/Cargo.toml index c627fb6..81bd72c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ kube = "0.87.2" log = "0.4.21" reqwest = { version = "0.12.2", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } solana-logger = "1.18.7" +strum = "0.26.2" +strum_macros = "0.26.2" tar = "0.4.40" tokio = { version = "1.29.1", features = ["full"] } url = "2.5.0" diff --git a/src/main.rs b/src/main.rs index 0e6e141..5943a72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ use { - clap::{command, Arg}, + clap::{command, Arg, ArgGroup}, log::*, std::fs, + strum::VariantNames, validator_lab::{ kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, @@ -30,8 +31,8 @@ fn parse_matches() -> clap::ArgMatches { Arg::new("build_type") .long("build-type") .takes_value(true) - .possible_values(&["skip", "debug", "release"]) - .default_value("release") + .possible_values(BuildType::VARIANTS) + .default_value(BuildType::Release.into()) .help("Specifies the build type: skip, debug, or release."), ) .arg( @@ -41,6 +42,11 @@ fn parse_matches() -> clap::ArgMatches { .conflicts_with("local_path") .help("Pulls specific release version. e.g. v1.17.2"), ) + .group( + ArgGroup::new("required_group") + .args(&["local_path", "release_channel"]) + .required(true), + ) .get_matches() } @@ -65,12 +71,12 @@ async fn main() { } else if let Some(release_channel) = matches.value_of("release_channel") { DeployMethod::ReleaseChannel(release_channel.to_owned()) } else { - DeployMethod::Skip + unreachable!("One of --local-path or --release-channel must be provided."); }; let solana_root = match &deploy_method { DeployMethod::Local(path) => SolanaRoot::new_from_path(path.into()), - DeployMethod::ReleaseChannel(_) | DeployMethod::Skip => SolanaRoot::default(), + DeployMethod::ReleaseChannel(_) => SolanaRoot::default(), }; let build_type: BuildType = matches diff --git a/src/release.rs b/src/release.rs index 773a1dc..fab5628 100644 --- a/src/release.rs +++ b/src/release.rs @@ -2,36 +2,24 @@ use { crate::{cat_file, download_to_temp, extract_release_archive}, git2::Repository, log::*, - std::{error::Error, fs, path::PathBuf, str::FromStr, time::Instant}, + std::{error::Error, fs, path::PathBuf, time::Instant}, + strum_macros::{EnumString, IntoStaticStr, VariantNames}, }; #[derive(Debug, Clone)] pub enum DeployMethod { Local(String), ReleaseChannel(String), - Skip, } -#[derive(PartialEq)] +#[derive(PartialEq, EnumString, IntoStaticStr, VariantNames)] +#[strum(serialize_all = "lowercase")] pub enum BuildType { - Skip, + Skip, // use Agave build from the previous run Debug, Release, } -impl FromStr for BuildType { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - match s { - "skip" => Ok(BuildType::Skip), - "debug" => Ok(BuildType::Debug), - "release" => Ok(BuildType::Release), - _ => Err("invalid string"), - } - } -} - pub struct BuildConfig { deploy_method: DeployMethod, build_type: BuildType, @@ -48,7 +36,6 @@ impl BuildConfig { let build_path = match deploy_method { DeployMethod::Local(_) => solana_root_path.join("farf/bin"), DeployMethod::ReleaseChannel(_) => solana_root_path.join("solana-release/bin"), - DeployMethod::Skip => solana_root_path.join("farf/bin"), }; Ok(BuildConfig { @@ -71,9 +58,6 @@ impl BuildConfig { DeployMethod::Local(_) => { self.setup_local_deploy()?; } - DeployMethod::Skip => { - return Err("Skip deploy method not implemented yet.".into()); - } } info!("Completed Prepare Deploy"); Ok(()) From 28188ce8818b391842bec5919412ce50850b20e1 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 27 Mar 2024 23:53:34 +0000 Subject: [PATCH 07/49] add in genesis::new --- PROGRESS.md | 2 +- src/genesis.rs | 16 ++++++++++++++++ src/lib.rs | 1 + src/main.rs | 3 +++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/genesis.rs diff --git a/PROGRESS.md b/PROGRESS.md index ec7199a..e97b4ff 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -13,7 +13,7 @@ - [x] Build from local commit - [x] Build from tar (release version) - [ ] Create Genesis - - [ ] Generate faucet and bootstrap accounts + - [x] Generate faucet and bootstrap accounts - [ ] Build genesis - [ ] Docker Build - [ ] Build Bootstrap Image diff --git a/src/genesis.rs b/src/genesis.rs new file mode 100644 index 0000000..218a691 --- /dev/null +++ b/src/genesis.rs @@ -0,0 +1,16 @@ +use std::path::PathBuf; + +pub struct Genesis { + pub config_dir: PathBuf, +} + +impl Genesis { + pub fn new(solana_root: PathBuf) -> Self { + let config_dir = solana_root.join("config-k8s"); + if config_dir.exists() { + std::fs::remove_dir_all(&config_dir).unwrap(); + } + std::fs::create_dir_all(&config_dir).unwrap(); + Genesis { config_dir } + } +} diff --git a/src/lib.rs b/src/lib.rs index 250be20..f4865b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,7 @@ impl SolanaRoot { } } +pub mod genesis; pub mod kubernetes; pub mod release; diff --git a/src/main.rs b/src/main.rs index 5943a72..ce63750 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use { std::fs, strum::VariantNames, validator_lab::{ + genesis::Genesis, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, SolanaRoot, @@ -125,4 +126,6 @@ async fn main() { return; } } + + let _genesis = Genesis::new(solana_root.get_root_path()); } From 0cc004355bf46c81d07eb24cc495701c3e5da2e6 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 28 Mar 2024 18:08:28 +0000 Subject: [PATCH 08/49] add generate faucet keypair --- Cargo.lock | 7229 +++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 85 +- src/genesis.rs | 29 +- src/main.rs | 10 +- 4 files changed, 6297 insertions(+), 1056 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d345c2c..1b9e521 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -17,6 +27,77 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.10.3" +source = "git+https://github.com/RustCrypto/AEADs?rev=6105d7a5591aefa646a95d12b5e8d3f55a9214ef#6105d7a5591aefa646a95d12b5e8d3f55a9214ef" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-geyser-plugin-interface" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf90f9c03c83a9a0c77de4135da29ef746eda69fdaceb54775df9147aa5f365" +dependencies = [ + "log", + "solana-sdk", + "solana-transaction-status", + "thiserror", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if 1.0.0", + "getrandom 0.2.12", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -26,6 +107,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -57,1729 +144,6244 @@ dependencies = [ ] [[package]] -name = "async-compression" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "atty" -version = "0.2.14" +name = "ansi_term" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "winapi 0.3.9", ] [[package]] -name = "autocfg" -version = "1.2.0" +name = "anyhow" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] -name = "backtrace" -version = "0.3.71" +name = "aquamarine" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "include_dir", + "itertools", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "bitflags" -version = "1.3.2" +name = "arc-swap" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] -name = "bitflags" -version = "2.5.0" +name = "ark-bn254" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "generic-array", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", ] [[package]] -name = "brotli" -version = "3.5.0" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint 0.4.4", + "num-traits", + "paste", + "rustc_version", + "zeroize", ] [[package]] -name = "brotli-decompressor" -version = "2.5.1" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "quote", + "syn 1.0.109", ] [[package]] -name = "bumpalo" -version = "3.15.4" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "bytes" -version = "1.6.0" +name = "ark-poly" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] [[package]] -name = "bzip2" -version = "0.4.4" +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "bzip2-sys", - "libc", + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", ] [[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" +name = "ark-serialize-derive" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "cc", - "libc", - "pkg-config", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "cc" -version = "1.0.90" +name = "ark-std" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "jobserver", - "libc", + "num-traits", + "rand 0.8.5", ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "arrayref" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] -name = "chrono" -version = "0.4.35" +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.52.4", -] +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] -name = "clap" -version = "3.2.25" +name = "ascii" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "once_cell", - "strsim", - "termcolor", - "textwrap", -] +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" [[package]] -name = "clap_lex" -version = "0.2.4" +name = "asn1-rs" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "os_str_bytes", + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", ] [[package]] -name = "console" -version = "0.15.8" +name = "asn1-rs-derive" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", ] [[package]] -name = "core-foundation" -version = "0.9.4" +name = "asn1-rs-impl" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "core-foundation-sys" -version = "0.8.6" +name = "assert_matches" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] -name = "cpufeatures" -version = "0.2.12" +name = "async-channel" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ - "libc", + "concurrent-queue", + "event-listener", + "futures-core", ] [[package]] -name = "crc32fast" -version = "1.4.0" +name = "async-compression" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "86a9249d1447a85f95810c620abea82e001fe58a31713fcce614caf52499f905" dependencies = [ - "cfg-if", + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", ] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "async-mutex" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" dependencies = [ - "generic-array", - "typenum", + "event-listener", ] [[package]] -name = "digest" -version = "0.10.7" +name = "async-stream" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ - "block-buffer", - "crypto-common", + "async-stream-impl", + "futures-core", + "pin-project-lite", ] [[package]] -name = "either" -version = "1.10.0" +name = "async-stream-impl" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] [[package]] -name = "encode_unicode" -version = "0.3.6" +name = "async-trait" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] [[package]] -name = "encoding_rs" -version = "0.8.33" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "cfg-if", + "hermit-abi 0.1.19", + "libc", + "winapi 0.3.9", ] [[package]] -name = "env_logger" -version = "0.9.3" +name = "autocfg" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] -name = "equivalent" -version = "1.0.1" +name = "autotools" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "aef8da1805e028a172334c3b680f93e71126f2327622faef2ec3d893c0a4ad77" +dependencies = [ + "cc", +] [[package]] -name = "errno" -version = "0.3.8" +name = "axum" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ - "libc", - "windows-sys 0.52.0", + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding 2.3.1", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", ] [[package]] -name = "fastrand" -version = "2.0.2" +name = "axum-core" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] [[package]] -name = "filetime" -version = "0.2.23" +name = "backoff" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "windows-sys 0.52.0", + "futures-core", + "getrandom 0.2.12", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", ] [[package]] -name = "flate2" -version = "1.0.28" +name = "backtrace" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ - "crc32fast", + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", "miniz_oxide", + "object", + "rustc-demangle", ] [[package]] -name = "fnv" -version = "1.0.7" +name = "base64" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] -name = "foreign-types" -version = "0.3.2" +name = "base64" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "percent-encoding", + "serde", ] [[package]] -name = "futures" -version = "0.3.30" +name = "bindgen" +version = "0.65.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease 0.2.17", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.57", ] [[package]] -name = "futures-channel" -version = "0.3.30" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" dependencies = [ - "futures-core", - "futures-sink", + "serde", ] [[package]] -name = "futures-core" -version = "0.3.30" +name = "bitmaps" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] [[package]] -name = "futures-executor" -version = "0.3.30" +name = "blake3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", + "digest 0.10.7", ] [[package]] -name = "futures-io" -version = "0.3.30" +name = "block-buffer" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] [[package]] -name = "futures-macro" -version = "0.3.30" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "proc-macro2", - "quote", - "syn", + "generic-array", ] [[package]] -name = "futures-sink" -version = "0.3.30" +name = "block-padding" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] -name = "futures-task" -version = "0.3.30" +name = "borsh" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] [[package]] -name = "futures-util" -version = "0.3.30" +name = "borsh" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "borsh-derive 0.10.3", + "hashbrown 0.13.2", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "borsh" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "0901fc8eb0aca4c83be0106d6f2db17d86a08dfc2c25f0e84464bf381158add6" dependencies = [ - "typenum", - "version_check", + "borsh-derive 1.4.0", + "cfg_aliases", ] [[package]] -name = "getrandom" -version = "0.2.12" +name = "borsh-derive" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "cfg-if", - "libc", - "wasi", + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", ] [[package]] -name = "gimli" -version = "0.28.1" +name = "borsh-derive" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] [[package]] -name = "git2" -version = "0.18.3" +name = "borsh-derive" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +checksum = "51670c3aa053938b0ee3bd67c3817e471e626151131b934038e83c5bf8de48f5" dependencies = [ - "bitflags 2.5.0", - "libc", - "libgit2-sys", - "log", - "openssl-probe", - "openssl-sys", - "url", + "once_cell", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.57", + "syn_derive", ] [[package]] -name = "h2" -version = "0.4.3" +name = "borsh-derive-internal" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "borsh-derive-internal" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "hashbrown" -version = "0.14.3" +name = "borsh-schema-derive-internal" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "heck" -version = "0.4.1" +name = "borsh-schema-derive-internal" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "brotli" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" dependencies = [ - "libc", + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", ] [[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "home" -version = "0.5.9" +name = "brotli-decompressor" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ - "windows-sys 0.52.0", + "alloc-no-stdlib", + "alloc-stdlib", ] [[package]] -name = "http" -version = "0.2.12" +name = "bs58" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] -name = "http" -version = "1.1.0" +name = "bstr" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ - "bytes", - "fnv", - "itoa", + "memchr", + "serde", ] [[package]] -name = "http-body" -version = "0.4.6" +name = "bumpalo" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] -name = "http-body" -version = "1.0.0" +name = "bv" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" dependencies = [ - "bytes", - "http 1.1.0", + "feature-probe", + "serde", ] [[package]] -name = "http-body-util" -version = "0.1.1" +name = "bytemuck" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" dependencies = [ - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.0", - "pin-project-lite", + "bytemuck_derive", ] [[package]] -name = "http-range-header" -version = "0.3.1" +name = "bytemuck_derive" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] [[package]] -name = "httparse" -version = "1.8.0" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "httpdate" -version = "1.0.3" +name = "bytes" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] -name = "humantime" -version = "2.1.0" +name = "bzip2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] [[package]] -name = "hyper" -version = "0.14.28" +name = "bzip2-sys" +version = "0.1.11+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", + "cc", + "libc", + "pkg-config", ] [[package]] -name = "hyper" -version = "1.2.0" +name = "caps" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2", - "http 1.1.0", - "http-body 1.0.0", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", + "libc", + "thiserror", ] [[package]] -name = "hyper-rustls" -version = "0.24.2" +name = "cc" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.28", - "log", - "rustls 0.21.10", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.24.1", + "jobserver", + "libc", ] [[package]] -name = "hyper-rustls" -version = "0.26.0" +name = "cexpr" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "futures-util", - "http 1.1.0", - "hyper 1.2.0", - "hyper-util", - "rustls 0.22.3", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.25.0", - "tower-service", + "nom", ] [[package]] -name = "hyper-timeout" -version = "0.4.1" +name = "cfg-if" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper 0.14.28", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "hyper-tls" -version = "0.6.0" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.2.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "hyper-util" -version = "0.1.3" +name = "cfg_aliases" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.2.0", - "pin-project-lite", - "socket2", - "tokio", - "tower", - "tower-service", - "tracing", -] +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] -name = "iana-time-zone" -version = "0.1.60" +name = "chrono" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", + "android-tzdata", + "iana-time-zone", "js-sys", + "num-traits", + "serde", "wasm-bindgen", - "windows-core", + "windows-targets 0.52.4", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "chrono-humanize" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "799627e6b4d27827a814e837b9d8a504832086081806d45b1afa34dc982b023b" dependencies = [ - "cc", + "chrono", ] [[package]] -name = "idna" -version = "0.5.0" +name = "cipher" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "generic-array", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "clang-sys" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "glob", + "libc", + "libloading 0.8.3", ] [[package]] -name = "indexmap" -version = "2.2.6" +name = "clap" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "equivalent", - "hashbrown 0.14.3", + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", ] [[package]] -name = "indicatif" -version = "0.17.8" +name = "clap" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap 1.9.3", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap 0.16.1", ] [[package]] -name = "instant" -version = "0.1.12" +name = "clap_lex" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ - "cfg-if", + "os_str_bytes", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "combine" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] [[package]] -name = "itoa" -version = "1.0.11" +name = "concurrent-queue" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] [[package]] -name = "jobserver" -version = "0.1.28" +name = "console" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ + "encode_unicode", + "lazy_static", "libc", + "unicode-width", + "windows-sys 0.52.0", ] [[package]] -name = "js-sys" -version = "0.3.69" +name = "console_error_panic_hook" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ + "cfg-if 1.0.0", "wasm-bindgen", ] [[package]] -name = "jsonpath-rust" -version = "0.3.5" +name = "console_log" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06cc127b7c3d270be504572364f9569761a180b981919dd0d87693a7f5fb7829" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" dependencies = [ - "pest", - "pest_derive", - "regex", - "serde_json", - "thiserror", + "log", + "web-sys", ] [[package]] -name = "k8s-openapi" -version = "0.20.0" +name = "const-oid" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc3606fd16aca7989db2f84bb25684d0270c6d6fa1dbcd0025af7b4130523a6" -dependencies = [ - "base64", - "bytes", - "chrono", - "serde", - "serde-value", - "serde_json", -] +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] -name = "kube" -version = "0.87.2" +name = "constant_time_eq" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3499c8d60c763246c7a213f51caac1e9033f46026904cb89bc8951ae8601f26e" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "k8s-openapi", - "kube-client", - "kube-core", + "core-foundation-sys", + "libc", ] [[package]] -name = "kube-client" -version = "0.87.2" +name = "core-foundation-sys" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033450dfa0762130565890dadf2f8835faedf749376ca13345bcd8ecd6b5f29f" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core_affinity" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8a03115cc34fb0d7c321dd154a3914b3ca082ccc5c11d91bf7117dbbe7171f" dependencies = [ - "base64", - "bytes", - "chrono", - "either", - "futures", - "home", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "hyper-rustls 0.24.2", - "hyper-timeout", - "jsonpath-rust", - "k8s-openapi", - "kube-core", - "pem", - "pin-project", - "rustls 0.21.10", - "rustls-pemfile", - "secrecy", - "serde", - "serde_json", - "serde_yaml", - "thiserror", - "tokio", - "tokio-util", - "tower", - "tower-http", - "tracing", + "kernel32-sys", + "libc", + "num_cpus", + "winapi 0.2.8", ] [[package]] -name = "kube-core" -version = "0.87.2" +name = "cpufeatures" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bba93d054786eba7994d03ce522f368ef7d48c88a1826faa28478d85fb63ae" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ - "chrono", - "form_urlencoded", - "http 0.2.12", - "k8s-openapi", - "once_cell", - "serde", - "serde_json", - "thiserror", + "libc", ] [[package]] -name = "lazy_static" +name = "crc32fast" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if 1.0.0", +] [[package]] -name = "libc" -version = "0.2.153" +name = "crossbeam-channel" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] [[package]] -name = "libgit2-sys" -version = "0.16.2+1.7.2" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cc", - "libc", - "libssh2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "libssh2-sys" -version = "0.3.0" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", + "crossbeam-utils", ] [[package]] -name = "libz-sys" -version = "1.1.16" +name = "crossbeam-utils" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] -name = "linux-raw-sys" -version = "0.4.13" +name = "crunchy" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "lock_api" -version = "0.4.11" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "autocfg", - "scopeguard", + "generic-array", + "typenum", ] [[package]] -name = "log" -version = "0.4.21" +name = "crypto-mac" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] [[package]] -name = "memchr" -version = "2.7.1" +name = "ctr" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] [[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +name = "curve25519-dalek" +version = "3.2.1" +source = "git+https://github.com/solana-labs/curve25519-dalek.git?rev=b500cdc2a920cd5bff9e2dd974d7b97349d61464#b500cdc2a920cd5bff9e2dd974d7b97349d61464" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] [[package]] -name = "miniz_oxide" -version = "0.7.2" +name = "darling" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "adler", + "darling_core", + "darling_macro", ] [[package]] -name = "mio" -version = "0.8.11" +name = "darling_core" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.57", ] [[package]] -name = "native-tls" -version = "0.2.11" +name = "darling_macro" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "darling_core", + "quote", + "syn 2.0.57", ] [[package]] -name = "num-traits" -version = "0.2.18" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "autocfg", + "cfg-if 1.0.0", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", + "rayon", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "data-encoding" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "hermit-abi 0.3.9", - "libc", + "const-oid", ] [[package]] -name = "number_prefix" -version = "0.4.0" +name = "der-parser" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint 0.4.4", + "num-traits", + "rusticata-macros", +] [[package]] -name = "object" -version = "0.32.2" +name = "deranged" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ - "memchr", + "powerfmt", ] [[package]] -name = "once_cell" -version = "1.19.0" +name = "derivation-path" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" [[package]] -name = "openssl" -version = "0.10.64" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "openssl-macros" -version = "0.1.1" +name = "derive_more" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ + "convert_case", "proc-macro2", "quote", - "syn", + "rustc_version", + "syn 1.0.109", ] [[package]] -name = "openssl-probe" -version = "0.1.5" +name = "dialoguer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] [[package]] -name = "openssl-sys" -version = "0.9.101" +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", + "generic-array", ] [[package]] -name = "ordered-float" -version = "2.10.1" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "num-traits", + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "dir-diff" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ad16bf5f84253b50d6557681c58c3ab67c47c77d39fed9aeb56e947290bd10" +dependencies = [ + "walkdir", +] + +[[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", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi 0.3.9", +] + +[[package]] +name = "dlopen2_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "eager" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek", + "hmac 0.12.1", + "sha2 0.10.8", +] + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etcd-client" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4b0ea5ef6dc2388a4b1669fa32097249bc03a15417b97cb75e38afb309e4a89" +dependencies = [ + "http", + "prost", + "tokio", + "tokio-stream", + "tonic", + "tonic-build", + "tower", + "tower-service", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fast-math" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2465292146cdfc2011350fe3b1c616ac83cf0faeedb33463ba1c332ed8948d66" +dependencies = [ + "ieee754", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding 2.3.1", +] + +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[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", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git2" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +dependencies = [ + "bitflags 2.5.0", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url 2.5.0", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "goauth" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8af59a261bcf42f45d1b261232847b9b850ba0a1419d6100698246fb66e9240" +dependencies = [ + "arc-swap", + "futures 0.3.30", + "log", + "reqwest", + "serde", + "serde_derive", + "serde_json", + "simpl", + "smpl_jwt", + "time", + "tokio", +] + +[[package]] +name = "goblin" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "h2" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util 0.7.10", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "histogram" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-proxy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" +dependencies = [ + "bytes", + "futures 0.3.30", + "headers", + "http", + "hyper", + "hyper-tls", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ieee754" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9007da9cacbd3e6343da136e98b0d2df013f553d35bdec8b518f07bea768e19c" + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "index_list" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70891286cb8e844fdfcf1178b47569699f9e20b5ecc4b45a6240a64771444638" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "rayon", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "jsonpath-rust" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06cc127b7c3d270be504572364f9569761a180b981919dd0d87693a7f5fb7829" +dependencies = [ + "pest", + "pest_derive", + "regex", + "serde_json", + "thiserror", +] + +[[package]] +name = "jsonrpc-client-transports" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" +dependencies = [ + "derive_more", + "futures 0.3.30", + "jsonrpc-core", + "jsonrpc-pubsub", + "log", + "serde", + "serde_json", + "url 1.7.2", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.30", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "jsonrpc-core-client" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" +dependencies = [ + "futures 0.3.30", + "jsonrpc-client-transports", +] + +[[package]] +name = "jsonrpc-derive" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" +dependencies = [ + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpc-http-server" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" +dependencies = [ + "futures 0.3.30", + "hyper", + "jsonrpc-core", + "jsonrpc-server-utils", + "log", + "net2", + "parking_lot 0.11.2", + "unicase", +] + +[[package]] +name = "jsonrpc-pubsub" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" +dependencies = [ + "futures 0.3.30", + "jsonrpc-core", + "lazy_static", + "log", + "parking_lot 0.11.2", + "rand 0.7.3", + "serde", +] + +[[package]] +name = "jsonrpc-server-utils" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" +dependencies = [ + "bytes", + "futures 0.3.30", + "globset", + "jsonrpc-core", + "lazy_static", + "log", + "tokio", + "tokio-stream", + "tokio-util 0.6.10", + "unicase", +] + +[[package]] +name = "k8s-openapi" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc3606fd16aca7989db2f84bb25684d0270c6d6fa1dbcd0025af7b4130523a6" +dependencies = [ + "base64 0.21.7", + "bytes", + "chrono", + "serde", + "serde-value", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[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.87.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3499c8d60c763246c7a213f51caac1e9033f46026904cb89bc8951ae8601f26e" +dependencies = [ + "k8s-openapi", + "kube-client", + "kube-core", +] + +[[package]] +name = "kube-client" +version = "0.87.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033450dfa0762130565890dadf2f8835faedf749376ca13345bcd8ecd6b5f29f" +dependencies = [ + "base64 0.21.7", + "bytes", + "chrono", + "either", + "futures 0.3.30", + "home", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-timeout", + "jsonpath-rust", + "k8s-openapi", + "kube-core", + "pem 3.0.3", + "pin-project", + "rustls", + "rustls-pemfile", + "secrecy", + "serde", + "serde_json", + "serde_yaml", + "thiserror", + "tokio", + "tokio-util 0.7.10", + "tower", + "tower-http", + "tracing", +] + +[[package]] +name = "kube-core" +version = "0.87.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5bba93d054786eba7994d03ce522f368ef7d48c88a1826faa28478d85fb63ae" +dependencies = [ + "chrono", + "form_urlencoded", + "http", + "k8s-openapi", + "once_cell", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libgit2-sys" +version = "0.16.2+1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if 1.0.0", + "windows-targets 0.52.4", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", +] + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint 0.4.4", + "thiserror", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown 0.12.3", +] + +[[package]] +name = "lz4" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +dependencies = [ + "libc", + "lz4-sys", +] + +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "min-max-heap" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2687e6cf9c00f48e9284cf9fd15f2ef341d03cc7743abf9df4c5f07fdee50b18" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "mockall" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +dependencies = [ + "cfg-if 1.0.0", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if 1.0.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.3+3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "ouroboros" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +dependencies = [ + "aliasable", + "ouroboros_macro", +] + +[[package]] +name = "ouroboros_macro" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +dependencies = [ + "Inflector", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +dependencies = [ + "base64 0.21.7", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "prettyplease" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +dependencies = [ + "proc-macro2", + "syn 2.0.57", +] + +[[package]] +name = "prio-graph" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6492a75ca57066a4479af45efa302bed448680182b0563f96300645d5f896097" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease 0.1.25", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "protobuf-src" +version = "1.1.0+21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac8852baeb3cc6fb83b93646fb93c0ffe5d14bf138c945ceb4b9948ee0e3c1" +dependencies = [ + "autotools", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding 2.3.1", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls", + "rustls-native-certs", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +dependencies = [ + "bytes", + "libc", + "socket2", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem 1.1.1", + "ring 0.16.20", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "reed-solomon-erasure" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7263373d500d4d4f505d43a2a662d475a894aa94503a1ee28e9188b5f3960d4f" +dependencies = [ + "cc", + "libc", + "libm", + "lru", + "parking_lot 0.11.2", + "smallvec", + "spin 0.9.8", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "async-compression", + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding 2.3.1", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util 0.7.10", + "tower-service", + "url 2.5.0", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi 0.3.9", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rolling-file" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8395b4f860856b740f20a296ea2cd4d823e81a2658cf05ef61be22916026a906" +dependencies = [ + "chrono", +] + +[[package]] +name = "rpassword" +version = "7.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.48.0", +] + +[[package]] +name = "rtoolbox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "seqlock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c67b6f14ecc5b86c66fa63d76b5092352678545a8a3cdae80aef5128371910" +dependencies = [ + "parking_lot 0.12.1", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.2.6", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "simpl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a30f10c911c0355f80f1c2faa8096efc4a58cdf8590b954d5b395efa071c711" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smpl_jwt" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b6ff8c21c74ce7744643a7cddbb02579a44f1f77e4316bff1ddb741aca8ac9" +dependencies = [ + "base64 0.13.1", + "log", + "openssl", + "serde", + "serde_derive", + "serde_json", + "simpl", + "time", +] + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures 0.3.30", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + +[[package]] +name = "solana-account-decoder" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5f49893e9e7cd1a45869e03ad6d767666544e47aa39cff5bcfd10c9b156177" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "bs58", + "bv", + "lazy_static", + "serde", + "serde_derive", + "serde_json", + "solana-config-program", + "solana-sdk", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror", + "zstd", +] + +[[package]] +name = "solana-accounts-db" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc530c7026893a9787b9d623071ea95a56df1999c0920d0615ac0b13dc9bc12a" +dependencies = [ + "arrayref", + "bincode", + "blake3", + "bv", + "bytemuck", + "byteorder", + "bzip2", + "crossbeam-channel", + "dashmap", + "flate2", + "fnv", + "im", + "index_list", + "itertools", + "lazy_static", + "log", + "lz4", + "memmap2", + "modular-bitfield", + "num-derive 0.4.2", + "num-traits", + "num_cpus", + "num_enum 0.7.2", + "ouroboros", + "percentage", + "qualifier_attr", + "rand 0.8.5", + "rayon", + "regex", + "rustc_version", + "seqlock", + "serde", + "serde_derive", + "smallvec", + "solana-bucket-map", + "solana-config-program", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-nohash-hasher", + "solana-program-runtime", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", + "static_assertions", + "strum 0.24.1", + "strum_macros 0.24.3", + "tar", + "tempfile", + "thiserror", +] + +[[package]] +name = "solana-address-lookup-table-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3602b15a5c70a16cac6008d3556098b7990c5ab72b047a996f5ea4e988871975" +dependencies = [ + "bincode", + "bytemuck", + "log", + "num-derive 0.4.2", + "num-traits", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-bloom" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac52b2029ff3b39162b0ae6aef653a1c1363d50005c37ab51eac9b6d560b035" +dependencies = [ + "bv", + "fnv", + "log", + "rand 0.8.5", + "rayon", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", +] + +[[package]] +name = "solana-bpf-loader-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e70419c0258baf10a8bb4f4dc5d535c597026eefbc3b288a8c3b87787bad05" +dependencies = [ + "bincode", + "byteorder", + "libsecp256k1", + "log", + "scopeguard", + "solana-measure", + "solana-program-runtime", + "solana-sdk", + "solana-zk-token-sdk", + "solana_rbpf", + "thiserror", +] + +[[package]] +name = "solana-bucket-map" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d4c00732ad91b4ee7afb949d0d2874282b7ecef3ac3e3305b6beb308073b95" +dependencies = [ + "bv", + "bytemuck", + "log", + "memmap2", + "modular-bitfield", + "num_enum 0.7.2", + "rand 0.8.5", + "solana-measure", + "solana-sdk", + "tempfile", +] + +[[package]] +name = "solana-clap-utils" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8528b2853d64e0b27889948e9f41b264d758074be9d9b8ba4e0ddce7c476dd" +dependencies = [ + "chrono", + "clap 2.34.0", + "rpassword", + "solana-remote-wallet", + "solana-sdk", + "thiserror", + "tiny-bip39", + "uriparse", + "url 2.5.0", +] + +[[package]] +name = "solana-cli-config" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dc88585f4027e74147a0623d86bec84e3355c23d14ef5efd8273fcb859d195" +dependencies = [ + "dirs-next", + "lazy_static", + "serde", + "serde_derive", + "serde_yaml", + "solana-clap-utils", + "solana-sdk", + "url 2.5.0", +] + +[[package]] +name = "solana-client" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b2b8e68c4b57a916400a77a66078a96b2914d7b218572ef8dff5a84e48ea2" +dependencies = [ + "async-trait", + "bincode", + "dashmap", + "futures 0.3.30", + "futures-util", + "indexmap 2.2.6", + "indicatif", + "log", + "quinn", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-quic-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", + "solana-sdk", + "solana-streamer", + "solana-thin-client", + "solana-tpu-client", + "solana-udp-client", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-compute-budget-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e729d000949680e57c82ea2d6568611e54e7c76de4308bfb0a7f369f17ae6067" +dependencies = [ + "solana-program-runtime", + "solana-sdk", +] + +[[package]] +name = "solana-config-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617228f9569238e544b526c422b632de368a5ce748a7af04f7f762bd937f42f3" +dependencies = [ + "bincode", + "chrono", + "serde", + "serde_derive", + "solana-program-runtime", + "solana-sdk", +] + +[[package]] +name = "solana-connection-cache" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec06c0772e0ebc54d22626ddb433eb798404fdc21b0175ac504f5fff4e50612" +dependencies = [ + "async-trait", + "bincode", + "crossbeam-channel", + "futures-util", + "indexmap 2.2.6", + "log", + "rand 0.8.5", + "rayon", + "rcgen", + "solana-measure", + "solana-metrics", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-core" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b78362bd81fbe11eb49a3c17bcd157f6e1f14b6e5292462fe2e0d77d0ef03" +dependencies = [ + "base64 0.21.7", + "bincode", + "bs58", + "bytes", + "chrono", + "crossbeam-channel", + "dashmap", + "eager", + "etcd-client", + "futures 0.3.30", + "histogram", + "itertools", + "lazy_static", + "log", + "lru", + "min-max-heap", + "num_enum 0.7.2", + "prio-graph", + "quinn", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "rcgen", + "rolling-file", + "rustc_version", + "rustls", + "serde", + "serde_bytes", + "serde_derive", + "solana-accounts-db", + "solana-bloom", + "solana-client", + "solana-cost-model", + "solana-entry", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-geyser-plugin-manager", + "solana-gossip", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-perf", + "solana-poh", + "solana-program-runtime", + "solana-quic-client", + "solana-rayon-threadlimit", + "solana-rpc", + "solana-rpc-client-api", + "solana-runtime", + "solana-sdk", + "solana-send-transaction-service", + "solana-streamer", + "solana-tpu-client", + "solana-transaction-status", + "solana-turbine", + "solana-unified-scheduler-pool", + "solana-version", + "solana-vote", + "solana-vote-program", + "solana-wen-restart", + "strum 0.24.1", + "strum_macros 0.24.3", + "sys-info", + "sysctl", + "tempfile", + "thiserror", + "tokio", + "trees", +] + +[[package]] +name = "solana-cost-model" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5188043556000e8cf13304e17c243be2653544589c35a20f6e6463a81f68f0bc" +dependencies = [ + "lazy_static", + "log", + "rustc_version", + "solana-address-lookup-table-program", + "solana-bpf-loader-program", + "solana-compute-budget-program", + "solana-config-program", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-loader-v4-program", + "solana-metrics", + "solana-program-runtime", + "solana-sdk", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", +] + +[[package]] +name = "solana-entry" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d99a57eb15a5d3a5f38697cc220f054a9c631e00d0ef68ac140d157c830d6c0" +dependencies = [ + "bincode", + "crossbeam-channel", + "dlopen2", + "lazy_static", + "log", + "rand 0.8.5", + "rayon", + "serde", + "solana-measure", + "solana-merkle-tree", + "solana-metrics", + "solana-perf", + "solana-rayon-threadlimit", + "solana-sdk", +] + +[[package]] +name = "solana-faucet" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2f6fe07f3f56f5483f153e3f1349e86d48d496f678aab77ecae5946e8d27c2" +dependencies = [ + "bincode", + "byteorder", + "clap 2.34.0", + "crossbeam-channel", + "log", + "serde", + "serde_derive", + "solana-clap-utils", + "solana-cli-config", + "solana-logger", + "solana-metrics", + "solana-sdk", + "solana-version", + "spl-memo", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-frozen-abi" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc46edad65d122c8b8634aa9ad11276a804c1aa2404755577fdfdea67484b620" +dependencies = [ + "block-buffer 0.10.4", + "bs58", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71c603d2203da423cfd8862572ffca7165268e76cab181035f50d106c3710eb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.57", +] + +[[package]] +name = "solana-geyser-plugin-manager" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6787272e9e497aff3947f24e8953cc71c8769d3f1a5d8f40c6d9d27e1994941" +dependencies = [ + "agave-geyser-plugin-interface", + "bs58", + "crossbeam-channel", + "json5", + "jsonrpc-core", + "jsonrpc-server-utils", + "libloading 0.7.4", + "log", + "serde_json", + "solana-accounts-db", + "solana-entry", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-rpc", + "solana-runtime", + "solana-sdk", + "solana-transaction-status", + "thiserror", +] + +[[package]] +name = "solana-gossip" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011f68dbbde79384ba903983e82b550006b53b12ba5bda3032cd70396a9b1c8" +dependencies = [ + "assert_matches", + "bincode", + "bv", + "clap 2.34.0", + "crossbeam-channel", + "flate2", + "indexmap 2.2.6", + "itertools", + "log", + "lru", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "solana-bloom", + "solana-clap-utils", + "solana-client", + "solana-entry", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-ledger", + "solana-logger", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-perf", + "solana-rayon-threadlimit", + "solana-runtime", + "solana-sdk", + "solana-streamer", + "solana-thin-client", + "solana-tpu-client", + "solana-version", + "solana-vote", + "solana-vote-program", + "static_assertions", + "thiserror", +] + +[[package]] +name = "solana-ledger" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86aed39a9728cebdce228bc8888c4bb472fe1990b3044a518e25015a769dd45a" +dependencies = [ + "assert_matches", + "bincode", + "bitflags 2.5.0", + "byteorder", + "chrono", + "chrono-humanize", + "crossbeam-channel", + "dashmap", + "fs_extra", + "futures 0.3.30", + "itertools", + "lazy_static", + "libc", + "log", + "lru", + "mockall", + "num_cpus", + "num_enum 0.7.2", + "prost", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "reed-solomon-erasure", + "rocksdb", + "rustc_version", + "scopeguard", + "serde", + "serde_bytes", + "sha2 0.10.8", + "solana-account-decoder", + "solana-accounts-db", + "solana-bpf-loader-program", + "solana-cost-model", + "solana-entry", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-perf", + "solana-program-runtime", + "solana-rayon-threadlimit", + "solana-runtime", + "solana-sdk", + "solana-stake-program", + "solana-storage-bigtable", + "solana-storage-proto", + "solana-transaction-status", + "solana-vote", + "solana-vote-program", + "spl-token", + "spl-token-2022", + "static_assertions", + "strum 0.24.1", + "strum_macros 0.24.3", + "tempfile", + "thiserror", + "tokio", + "tokio-stream", + "trees", +] + +[[package]] +name = "solana-loader-v4-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a9d776a3f71896ef5ea83c00816474ada49d1d718e1de7b220473c7e7e0cb0" +dependencies = [ + "log", + "solana-measure", + "solana-program-runtime", + "solana-sdk", + "solana_rbpf", +] + +[[package]] +name = "solana-logger" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5b3eef85d82c2c3030acb1d3272d77984d118d2a026d9b1a2cecc6e4c6602eb" +dependencies = [ + "env_logger", + "lazy_static", + "log", +] + +[[package]] +name = "solana-measure" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd072023ab870dcb7d524980d9481317bfd29c1dfd74a067747c8d1d249d1075" +dependencies = [ + "log", + "solana-sdk", +] + +[[package]] +name = "solana-merkle-tree" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3856fa7d7892a458d8ca8ac84dca5499ba3fa6306b76e2641477a3ce1024be56" +dependencies = [ + "fast-math", + "solana-program", +] + +[[package]] +name = "solana-metrics" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f594ca2a2698983b515580925d10be20b079617154bbed07d6cd455d1661b90" +dependencies = [ + "crossbeam-channel", + "gethostname", + "lazy_static", + "log", + "reqwest", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-net-utils" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e632ad2071b8c911baf873403273c574bb11da95947e2f56db4e53ef06b771fe" +dependencies = [ + "bincode", + "clap 3.2.25", + "crossbeam-channel", + "log", + "nix", + "rand 0.8.5", + "serde", + "serde_derive", + "socket2", + "solana-logger", + "solana-sdk", + "solana-version", + "tokio", + "url 2.5.0", +] + +[[package]] +name = "solana-nohash-hasher" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" + +[[package]] +name = "solana-perf" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3012434718bf3e76ef46cbf3be98a2de877afe7bff6571232d64cc67dce219a" +dependencies = [ + "ahash 0.8.11", + "bincode", + "bv", + "caps", + "curve25519-dalek", + "dlopen2", + "fnv", + "lazy_static", + "libc", + "log", + "nix", + "rand 0.8.5", + "rayon", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-vote-program", +] + +[[package]] +name = "solana-poh" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a7241232f802db676014bb191cd32ed9b74200daad61296d211e12621d975b" +dependencies = [ + "core_affinity", + "crossbeam-channel", + "log", + "solana-entry", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-program" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760e9e923050f30f03a159aec9ba1fe09ae7c7494ebd8ba74dc5b7429b11085b" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags 2.5.0", + "blake3", + "borsh 0.10.3", + "borsh 0.9.3", + "borsh 1.4.0", + "bs58", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.12", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset 0.9.1", + "num-bigint 0.4.4", + "num-derive 0.4.2", + "num-traits", + "parking_lot 0.12.1", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-program-runtime" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a61b65be846413bc504ecae468b6a3fa91b1b37631c80074c41ada8cdc36d165" +dependencies = [ + "base64 0.21.7", + "bincode", + "eager", + "enum-iterator", + "itertools", + "libc", + "log", + "num-derive 0.4.2", + "num-traits", + "percentage", + "rand 0.8.5", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-sdk", + "solana_rbpf", + "thiserror", +] + +[[package]] +name = "solana-pubsub-client" +version = "1.18.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4173029a0e3a20930791886dce92c1a6d293a59754e418ac68547f3e14a8f025" +dependencies = [ + "crossbeam-channel", + "futures-util", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url 2.5.0", ] [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "solana-quic-client" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "8ae1b9224efc32579fe61a9e06dc8efb2a3cd167c458091cc093086304441285" +dependencies = [ + "async-mutex", + "async-trait", + "futures 0.3.30", + "itertools", + "lazy_static", + "log", + "quinn", + "quinn-proto", + "rcgen", + "rustls", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-rpc-client-api", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] [[package]] -name = "parking_lot" -version = "0.12.1" +name = "solana-rayon-threadlimit" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "9460642bcb89090dcc15ecf11b6c4a1994c538ba49a4c5d99023365600631009" dependencies = [ - "lock_api", - "parking_lot_core", + "lazy_static", + "num_cpus", ] [[package]] -name = "parking_lot_core" -version = "0.9.9" +name = "solana-remote-wallet" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "c3de3b65d0fdbf0b2de6dc9aecac03d79ea7ef11c29efbdd67bf17a13d061a95" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", + "console", + "dialoguer", + "log", + "num-derive 0.4.2", + "num-traits", + "parking_lot 0.12.1", + "qstring", + "semver", + "solana-sdk", + "thiserror", + "uriparse", ] [[package]] -name = "pem" -version = "3.0.3" +name = "solana-rpc" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8bca7d5024bcd02ce40aa22c1f240957e8087abe975af2b6b87753e65c1a9158" dependencies = [ - "base64", + "base64 0.21.7", + "bincode", + "bs58", + "crossbeam-channel", + "dashmap", + "itertools", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "jsonrpc-http-server", + "jsonrpc-pubsub", + "libc", + "log", + "rayon", + "regex", "serde", + "serde_derive", + "serde_json", + "soketto", + "solana-account-decoder", + "solana-accounts-db", + "solana-client", + "solana-entry", + "solana-faucet", + "solana-gossip", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-perf", + "solana-poh", + "solana-rayon-threadlimit", + "solana-rpc-client-api", + "solana-runtime", + "solana-sdk", + "solana-send-transaction-service", + "solana-stake-program", + "solana-storage-bigtable", + "solana-streamer", + "solana-tpu-client", + "solana-transaction-status", + "solana-version", + "solana-vote", + "solana-vote-program", + "spl-token", + "spl-token-2022", + "stream-cancel", + "thiserror", + "tokio", + "tokio-util 0.6.10", ] [[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.8" +name = "solana-rpc-client" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "b27d16eaebd5889c4dd873d715be0bad4651a0bc2509ba99ec6fc7d3b3416278" dependencies = [ - "memchr", - "thiserror", - "ucd-trie", + "async-trait", + "base64 0.21.7", + "bincode", + "bs58", + "indicatif", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "tokio", ] [[package]] -name = "pest_derive" -version = "2.7.8" +name = "solana-rpc-client-api" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "d82323f7b130105a4789101b5e7d97142110774ee06aa84346effa661898d407" dependencies = [ - "pest", - "pest_generator", + "base64 0.21.7", + "bs58", + "jsonrpc-core", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "spl-token-2022", + "thiserror", ] [[package]] -name = "pest_generator" -version = "2.7.8" +name = "solana-rpc-client-nonce-utils" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "092867e337f366d1b719d28b4e02cffff4734cbbf9945daf5f172715db378e2c" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", + "clap 2.34.0", + "solana-clap-utils", + "solana-rpc-client", + "solana-sdk", + "thiserror", ] [[package]] -name = "pest_meta" -version = "2.7.8" +name = "solana-runtime" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "4502555f86bfd35b3deb96df1fbab846700bcbca9b66a55692ac7d651334ca0b" dependencies = [ - "once_cell", - "pest", - "sha2", + "aquamarine", + "arrayref", + "base64 0.21.7", + "bincode", + "blake3", + "bv", + "bytemuck", + "byteorder", + "bzip2", + "crossbeam-channel", + "dashmap", + "dir-diff", + "flate2", + "fnv", + "im", + "index_list", + "itertools", + "lazy_static", + "log", + "lru", + "lz4", + "memmap2", + "mockall", + "modular-bitfield", + "num-derive 0.4.2", + "num-traits", + "num_cpus", + "num_enum 0.7.2", + "ouroboros", + "percentage", + "qualifier_attr", + "rand 0.8.5", + "rayon", + "regex", + "rustc_version", + "serde", + "serde_derive", + "serde_json", + "solana-accounts-db", + "solana-address-lookup-table-program", + "solana-bpf-loader-program", + "solana-bucket-map", + "solana-compute-budget-program", + "solana-config-program", + "solana-cost-model", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-loader-v4-program", + "solana-measure", + "solana-metrics", + "solana-perf", + "solana-program-runtime", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-stake-program", + "solana-system-program", + "solana-version", + "solana-vote", + "solana-vote-program", + "solana-zk-token-proof-program", + "solana-zk-token-sdk", + "static_assertions", + "strum 0.24.1", + "strum_macros 0.24.3", + "symlink", + "tar", + "tempfile", + "thiserror", + "zstd", ] [[package]] -name = "pin-project" -version = "1.1.5" +name = "solana-sdk" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "1788023924ebb072288868f8b4b72f5459c1ff653238d769700da9c8043a8aea" dependencies = [ - "pin-project-internal", + "assert_matches", + "base64 0.21.7", + "bincode", + "bitflags 2.5.0", + "borsh 1.4.0", + "bs58", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek", + "ed25519-dalek-bip32", + "generic-array", + "hmac 0.12.1", + "itertools", + "js-sys", + "lazy_static", + "libsecp256k1", + "log", + "memmap2", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "pbkdf2 0.11.0", + "qstring", + "qualifier_attr", + "rand 0.7.3", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "serde_with", + "sha2 0.10.8", + "sha3 0.10.8", + "siphasher", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", ] [[package]] -name = "pin-project-internal" -version = "1.1.5" +name = "solana-sdk-macro" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "6f3b24f46820e8912b81719a828a3d05f4fbd2f6afdc13826b0327df065ab795" dependencies = [ + "bs58", "proc-macro2", "quote", - "syn", + "rustversion", + "syn 2.0.57", ] [[package]] -name = "pin-project-lite" -version = "0.2.13" +name = "solana-security-txt" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "solana-send-transaction-service" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "fb4766f89d339c89915dcd09ea84ba58ddd575da858391b50d1c6427027b54fa" +dependencies = [ + "crossbeam-channel", + "log", + "solana-client", + "solana-measure", + "solana-metrics", + "solana-runtime", + "solana-sdk", + "solana-tpu-client", +] [[package]] -name = "pkg-config" -version = "0.3.30" +name = "solana-stake-program" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "0eebaae45fc90e4fbdf347261e9e2aba973264e256dabf51c858a86926654b3e" +dependencies = [ + "bincode", + "log", + "rustc_version", + "solana-config-program", + "solana-program-runtime", + "solana-sdk", + "solana-vote-program", +] [[package]] -name = "portable-atomic" -version = "1.6.0" +name = "solana-storage-bigtable" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "0d7642cbbab1fe74df3cbf7fe8a54b221e37a43bf20e11f7b040a8650d58bfb9" +dependencies = [ + "backoff", + "bincode", + "bytes", + "bzip2", + "enum-iterator", + "flate2", + "futures 0.3.30", + "goauth", + "http", + "hyper", + "hyper-proxy", + "log", + "openssl", + "prost", + "prost-types", + "serde", + "serde_derive", + "smpl_jwt", + "solana-metrics", + "solana-sdk", + "solana-storage-proto", + "solana-transaction-status", + "thiserror", + "tokio", + "tonic", + "zstd", +] [[package]] -name = "proc-macro2" -version = "1.0.79" +name = "solana-storage-proto" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "4df3e6c24eb85618b1570b7ba497c5af3daa02c0d8118c061c104be2d265aa61" dependencies = [ - "unicode-ident", + "bincode", + "bs58", + "prost", + "protobuf-src", + "serde", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "tonic-build", ] [[package]] -name = "quote" -version = "1.0.35" +name = "solana-streamer" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "7403972b4233b87598c0a8e8fac26db549f8cb18076d385b8ef8deb1e36a6bc3" dependencies = [ - "proc-macro2", + "async-channel", + "bytes", + "crossbeam-channel", + "futures-util", + "histogram", + "indexmap 2.2.6", + "itertools", + "libc", + "log", + "nix", + "pem 1.1.1", + "percentage", + "pkcs8", + "quinn", + "quinn-proto", + "rand 0.8.5", + "rcgen", + "rustls", + "solana-metrics", + "solana-perf", + "solana-sdk", + "thiserror", + "tokio", + "x509-parser", ] [[package]] -name = "redox_syscall" -version = "0.4.1" +name = "solana-system-program" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "a74a76740e5e37b52b3be15f9bc2c1e388b8ac22a2c9b1297bff80da758fa444" dependencies = [ - "bitflags 1.3.2", + "bincode", + "log", + "serde", + "serde_derive", + "solana-program-runtime", + "solana-sdk", ] [[package]] -name = "regex" -version = "1.10.4" +name = "solana-thin-client" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "f63740969c229c77306024ed3ad809fabc0a1269cfe75a9c982c7cbd20c38d26" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "bincode", + "log", + "rayon", + "solana-connection-cache", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", ] [[package]] -name = "regex-automata" -version = "0.4.6" +name = "solana-tpu-client" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "0f910ac2556498a889d393309110bf4ec7607208104b40260df822e925fce933" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "async-trait", + "bincode", + "futures-util", + "indexmap 2.2.6", + "indicatif", + "log", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", ] [[package]] -name = "regex-syntax" -version = "0.8.3" +name = "solana-transaction-status" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "a5fa023f9a09216e809bf28c1dc16c8dfce726dfa64133f9016e8a1f01267f39" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "borsh 0.10.3", + "bs58", + "lazy_static", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "spl-associated-token-account", + "spl-memo", + "spl-token", + "spl-token-2022", + "thiserror", +] [[package]] -name = "reqwest" -version = "0.12.2" +name = "solana-turbine" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +checksum = "c75673f15036f4d81c9577bc46f9ebde698d86410fa18d02ddf20db2bbecba1b" dependencies = [ - "async-compression", - "base64", + "bincode", "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 1.1.0", - "http-body 1.0.0", - "http-body-util", - "hyper 1.2.0", - "hyper-rustls 0.26.0", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", + "crossbeam-channel", + "futures 0.3.30", + "itertools", "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.22.3", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "lru", + "quinn", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "rcgen", + "rustls", + "solana-entry", + "solana-gossip", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-perf", + "solana-poh", + "solana-quic-client", + "solana-rayon-threadlimit", + "solana-rpc", + "solana-rpc-client-api", + "solana-runtime", + "solana-sdk", + "solana-streamer", + "thiserror", "tokio", - "tokio-native-tls", - "tokio-rustls 0.25.0", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", ] [[package]] -name = "ring" -version = "0.17.8" +name = "solana-udp-client" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "0e15df3333f480774a47da0d3af3e7b9c78a3417f949bb99ed7a16dd33a906d4" dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", + "async-trait", + "solana-connection-cache", + "solana-net-utils", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", ] [[package]] -name = "rustc-demangle" -version = "0.1.23" +name = "solana-unified-scheduler-logic" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "c0c3501527927512e912692ee4fae38bae92d76824bf2280ae90306c906ceff0" [[package]] -name = "rustc_version" -version = "0.4.0" +name = "solana-unified-scheduler-pool" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "a4b7755ba8b9355e9d113bb09d003cd281fac85cab1f5ea866cdb2eb0c2c4bae" dependencies = [ - "semver", + "solana-ledger", + "solana-program-runtime", + "solana-runtime", + "solana-sdk", + "solana-unified-scheduler-logic", + "solana-vote", ] [[package]] -name = "rustix" -version = "0.38.32" +name = "solana-version" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "99147bd36e5ccc2e046bc3ef8af9517da1f34c255536e3aeaf0abc383a9f37ed" dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "log", + "rustc_version", + "semver", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", ] [[package]] -name = "rustls" -version = "0.21.10" +name = "solana-vote" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "b37c59c7d2ac0d120bb912c677b8c907e4ce54f91b423dbcd736e89f445b4bc0" dependencies = [ + "crossbeam-channel", + "itertools", "log", - "ring", - "rustls-webpki 0.101.7", - "sct", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", + "solana-vote-program", + "thiserror", ] [[package]] -name = "rustls" -version = "0.22.3" +name = "solana-vote-program" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "c6071a7f57e03c9d1b55ae4a96fbc55b0df0f97c3153df1dc0c9521ea823bb2b" dependencies = [ + "bincode", "log", - "ring", - "rustls-pki-types", - "rustls-webpki 0.102.2", - "subtle", - "zeroize", + "num-derive 0.4.2", + "num-traits", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", ] [[package]] -name = "rustls-native-certs" -version = "0.6.3" +name = "solana-wen-restart" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "fc20c2b61d6f86cb56c3f44a392eb479ef1abfd5fed297d3d6df80db16023de9" dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", + "log", + "prost", + "prost-build", + "prost-types", + "protobuf-src", + "rustc_version", + "solana-gossip", + "solana-ledger", + "solana-logger", + "solana-program", + "solana-runtime", + "solana-sdk", + "solana-vote-program", ] [[package]] -name = "rustls-pemfile" -version = "1.0.4" +name = "solana-zk-token-proof-program" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "4746241f2c398dd450557145b46ac9a5b196d3c8e604ffcab60b93280a5c7fd7" dependencies = [ - "base64", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-program-runtime", + "solana-sdk", + "solana-zk-token-sdk", ] [[package]] -name = "rustls-pki-types" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" +name = "solana-zk-token-sdk" +version = "1.18.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "76cba1f80c9001dc788655f2d7d5671af55c7a0a49b95de819f2fc45d8b803b0" dependencies = [ - "ring", - "untrusted", + "aes-gcm-siv", + "base64 0.21.7", + "bincode", + "bytemuck", + "byteorder", + "curve25519-dalek", + "getrandom 0.1.16", + "itertools", + "lazy_static", + "merlin", + "num-derive 0.4.2", + "num-traits", + "rand 0.7.3", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", ] [[package]] -name = "rustls-webpki" -version = "0.102.2" +name = "solana_rbpf" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "3d457cc2ba742c120492a64b7fa60e22c575e891f6b55039f4d736568fb112a3" dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "byteorder", + "combine", + "goblin", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "scroll", + "thiserror", + "winapi 0.3.9", ] [[package]] -name = "rustversion" -version = "1.0.14" +name = "spin" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] -name = "ryu" -version = "1.0.17" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "schannel" -version = "0.1.23" +name = "spki" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ - "windows-sys 0.52.0", + "base64ct", + "der", ] [[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" +name = "spl-associated-token-account" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" dependencies = [ - "ring", - "untrusted", + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-token", + "spl-token-2022", + "thiserror", ] [[package]] -name = "secrecy" -version = "0.8.0" +name = "spl-discriminator" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +checksum = "daa600f2fe56f32e923261719bae640d873edadbc5237681a39b8e37bfd4d263" dependencies = [ - "serde", - "zeroize", + "bytemuck", + "solana-program", + "spl-discriminator-derive", ] [[package]] -name = "security-framework" -version = "2.9.2" +name = "spl-discriminator-derive" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", + "quote", + "spl-discriminator-syn", + "syn 2.0.57", ] [[package]] -name = "security-framework-sys" -version = "2.9.1" +name = "spl-discriminator-syn" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.57", + "thiserror", ] [[package]] -name = "semver" -version = "1.0.22" +name = "spl-memo" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] [[package]] -name = "serde" -version = "1.0.197" +name = "spl-pod" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "85a5db7e4efb1107b0b8e52a13f035437cdcb36ef99c58f6d467f089d9b2915a" dependencies = [ - "serde_derive", + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", ] [[package]] -name = "serde-value" -version = "0.7.0" +name = "spl-program-error" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +checksum = "7e0657b6490196971d9e729520ba934911ff41fbb2cb9004463dbe23cf8b4b4f" dependencies = [ - "ordered-float", - "serde", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", ] [[package]] -name = "serde_derive" -version = "1.0.197" +name = "spl-program-error-derive" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" dependencies = [ "proc-macro2", "quote", - "syn", + "sha2 0.10.8", + "syn 2.0.57", ] [[package]] -name = "serde_json" -version = "1.0.115" +name = "spl-tlv-account-resolution" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "56f335787add7fa711819f9e7c573f8145a5358a709446fe2d24bf2a88117c90" dependencies = [ - "itoa", - "ryu", - "serde", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "spl-token" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "solana-program", + "thiserror", ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "spl-token-2022" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" dependencies = [ - "indexmap 2.2.6", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "solana-program", + "solana-security-txt", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror", ] [[package]] -name = "sha2" -version = "0.10.8" +name = "spl-token-group-interface" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", ] [[package]] -name = "signal-hook-registry" -version = "1.4.1" +name = "spl-token-metadata-interface" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" dependencies = [ - "libc", + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", ] [[package]] -name = "slab" -version = "0.4.9" +name = "spl-transfer-hook-interface" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" dependencies = [ - "autocfg", + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "spl-type-length-value" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8f9ebd75d29c5f48de5f6a9c114e08531030b75b8ac2c557600ac7da0b73b1e8" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] [[package]] -name = "socket2" -version = "0.5.6" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "solana-logger" -version = "1.18.8" +name = "stream-cancel" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5559aeadd3adc219fa7169e96a8c5dda618c7f06985f91f2a5f55b9814c7a2" +checksum = "5f9fbf9bd71e4cf18d68a8a0951c0e5b7255920c0cd992c4ff51cddd6ef514a3" dependencies = [ - "env_logger", - "lazy_static", - "log", + "futures-core", + "pin-project", + "tokio", ] [[package]] -name = "spin" -version = "0.9.8" +name = "strsim" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "strsim" @@ -1787,12 +6389,34 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros 0.24.3", +] + [[package]] name = "strum" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "strum_macros" version = "0.26.2" @@ -1803,32 +6427,96 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.57", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + +[[package]] +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "2.0.55" +version = "2.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.57", +] + [[package]] name = "sync_wrapper" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "sysctl" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225e483f02d0ad107168dc57381a8a40c3aeea6abe47f37506931f861643cfa8" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "libc", + "thiserror", + "walkdir", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -1867,7 +6555,7 @@ version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "rustix", "windows-sys 0.52.0", @@ -1877,9 +6565,24 @@ dependencies = [ name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "winapi-util", + "unicode-width", ] [[package]] @@ -1905,7 +6608,57 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", +] + +[[package]] +name = "time" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", ] [[package]] @@ -1925,16 +6678,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -1960,7 +6713,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", ] [[package]] @@ -1979,18 +6732,48 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls", "tokio", ] [[package]] -name = "tokio-rustls" -version = "0.25.0" +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.25.4", +] + +[[package]] +name = "tokio-util" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" dependencies = [ - "rustls 0.22.3", - "rustls-pki-types", + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "log", + "pin-project-lite", "tokio", ] @@ -2008,6 +6791,87 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding 2.3.1", + "pin-project", + "prost", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +dependencies = [ + "prettyplease 0.1.25", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + [[package]] name = "tower" version = "0.4.13" @@ -2016,10 +6880,13 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", + "indexmap 1.9.3", "pin-project", "pin-project-lite", + "rand 0.8.5", + "slab", "tokio", - "tokio-util", + "tokio-util 0.7.10", "tower-layer", "tower-service", "tracing", @@ -2031,13 +6898,13 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "base64", + "base64 0.21.7", "bitflags 2.5.0", "bytes", "futures-core", "futures-util", - "http 0.2.12", - "http-body 0.4.6", + "http", + "http-body", "http-range-header", "mime", "pin-project-lite", @@ -2078,7 +6945,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", ] [[package]] @@ -2090,12 +6957,39 @@ dependencies = [ "once_cell", ] +[[package]] +name = "trees" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de5f738ceab88e2491a94ddc33c3feeadfa95fedc60363ef110845df12f3878" + [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "sha1", + "thiserror", + "url 2.5.0", + "utf-8", + "webpki-roots 0.24.0", +] + [[package]] name = "typenum" version = "1.17.0" @@ -2108,6 +7002,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -2135,18 +7038,70 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +dependencies = [ + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", +] + [[package]] name = "url" version = "2.5.0" @@ -2154,30 +7109,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna", - "percent-encoding", + "idna 0.5.0", + "percent-encoding 2.3.1", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "validator-lab" version = "0.0.1" dependencies = [ "bzip2", - "clap", + "clap 3.2.25", "console", "git2", "indicatif", "k8s-openapi", "kube", "log", + "rand 0.8.5", "reqwest", "rustc_version", + "rustls", + "solana-core", "solana-logger", - "strum", - "strum_macros", + "solana-sdk", + "strum 0.26.2", + "strum_macros 0.26.2", + "subtle", "tar", + "tiny-bip39", "tokio", - "url", + "url 2.5.0", + "zeroize", ] [[package]] @@ -2186,12 +7154,34 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2201,6 +7191,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2213,7 +7209,7 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -2228,7 +7224,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-shared", ] @@ -2238,7 +7234,7 @@ version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -2262,7 +7258,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2285,13 +7281,37 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" +dependencies = [ + "rustls-webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ - "rustls-pki-types", + "either", + "home", + "once_cell", + "rustix", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -2302,6 +7322,12 @@ 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" @@ -2314,7 +7340,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2464,16 +7490,43 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "windows-sys 0.48.0", ] +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs", + "base64 0.13.1", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + [[package]] name = "xattr" version = "1.3.1" @@ -2485,8 +7538,80 @@ dependencies = [ "rustix", ] +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.57", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 81bd72c..2ce64ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,13 +16,21 @@ indicatif = "0.17.8" k8s-openapi ={ version = "0.20.0", features = ["v1_28"] } kube = "0.87.2" log = "0.4.21" -reqwest = { version = "0.12.2", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } -solana-logger = "1.18.7" +rand = "0.8.5" +reqwest = { version = "0.11.23", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } +rustls = { version = "0.21.10", default-features = false, features = ["quic"] } +solana-core = "1.18.8" +solana-logger = "1.18.8" +solana-sdk = "1.18.8" strum = "0.26.2" strum_macros = "0.26.2" +subtle = "2.4.1" tar = "0.4.40" +tiny-bip39 = "0.8.2" tokio = { version = "1.29.1", features = ["full"] } url = "2.5.0" +# See "zeroize versioning issues" below if you are updating this version. +zeroize = { version = "1.3", default-features = false } [build-dependencies] rustc_version = "0.4" @@ -33,3 +41,76 @@ path = "src/main.rs" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +# +# === zeroize versioning issues === +# +# A number of packages used explicit upper bound on the `zeroize` package, such +# as `>=1, <1.4`. The problem is that cargo still does not duplicate `zeroize` +# if a newer version is available and requested by another package and just +# fails the whole dependency resolution process. +# +# This is described in +# +# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#multiple-requirements +# +# So we have to patch `zeroize` dependency specifications in the projects that +# introduce these constraints. They have already removed these constraints in +# newer versions, but we have not updated yet. As we update, we need to remove +# these patch requests. +# +# When our dependencies are upgraded, we can remove these patches. Before that +# we might need to maintain these patches in sync with our full dependency tree. + +# Our dependency tree has `aes-gcm-siv` v0.10.3 and the `zeroize` restriction +# was removed in the next commit just after the release. So it seems safe to +# patch to this commit. +# +# `aes-gcm-siv` v0.10.3 release: +# +# https://github.com/RustCrypto/AEADs/releases/tag/aes-gcm-siv-v0.10.3 +# +# Corresponds to commit +# +# https://github.com/RustCrypto/AEADs/commit/6f16f4577a1fc839a2346cf8c5531c85a44bf5c0 +# +# Comparison with `6105d7a5591aefa646a95d12b5e8d3f55a9214ef` pinned here: +# +# https://github.com/RustCrypto/AEADs/compare/aes-gcm-siv-v0.10.3..6105d7a5591aefa646a95d12b5e8d3f55a9214ef +# +[patch.crates-io.aes-gcm-siv] +git = "https://github.com/RustCrypto/AEADs" +rev = "6105d7a5591aefa646a95d12b5e8d3f55a9214ef" + +# Our dependency tree has `curve25519-dalek` v3.2.1. They have removed the +# constraint in the next major release. The commit that removes the `zeroize` +# constraint was added to multiple release branches, but not to the 3.2 branch. +# +# `curve25519-dalek` maintainers are saying they do not want to invest any more +# time in the 3.2 release: +# +# https://github.com/dalek-cryptography/curve25519-dalek/issues/452#issuecomment-1749809428 +# +# So we have to fork and create our own release, based on v3.2.1, with the +# commit that removed `zeroize` constraint on the `main` branch cherry-picked on +# top. +# +# `curve25519-dalek` v3.2.1 release: +# +# https://github.com/dalek-cryptography/curve25519-dalek/releases/tag/3.2.1 +# +# Corresponds to commit +# +# https://github.com/dalek-cryptography/curve25519-dalek/commit/29e5c29b0e5c6821e4586af58b0d0891dd2ec639 +# +# Comparison with `b500cdc2a920cd5bff9e2dd974d7b97349d61464`: +# +# https://github.com/dalek-cryptography/curve25519-dalek/compare/3.2.1...solana-labs:curve25519-dalek:b500cdc2a920cd5bff9e2dd974d7b97349d61464 +# +# Or, using the branch name instead of the hash: +# +# https://github.com/dalek-cryptography/curve25519-dalek/compare/3.2.1...solana-labs:curve25519-dalek:3.2.1-unpin-zeroize +# +[patch.crates-io.curve25519-dalek] +git = "https://github.com/solana-labs/curve25519-dalek.git" +rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" \ No newline at end of file diff --git a/src/genesis.rs b/src/genesis.rs index 218a691..856b2c3 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -1,5 +1,19 @@ -use std::path::PathBuf; +use { + log::*, + rand::Rng, + solana_core::gen_keys::GenKeys, + solana_sdk::signature::{Keypair, write_keypair_file}, + std::{ + error::Error, + path::PathBuf, + result::Result, + }, +}; +fn output_keypair(keypair: &Keypair, outfile: &str) -> Result<(), Box> { + write_keypair_file(keypair, outfile)?; + Ok(()) +} pub struct Genesis { pub config_dir: PathBuf, } @@ -13,4 +27,17 @@ impl Genesis { std::fs::create_dir_all(&config_dir).unwrap(); Genesis { config_dir } } + + pub fn generate_faucet(&self) -> Result<(), Box> { + info!("generating faucet keypair"); + let outfile = self.config_dir.join("faucet.json"); + let seed: [u8; 32] = rand::thread_rng().gen(); + let keypair = GenKeys::new(seed).gen_keypair(); + + if let Some(outfile) = outfile.to_str() { + output_keypair(&keypair, outfile) + .map_err(|err| format!("Unable to write {outfile}: {err}"))?; + } + Ok(()) + } } diff --git a/src/main.rs b/src/main.rs index ce63750..a4fea4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,5 +127,13 @@ async fn main() { } } - let _genesis = Genesis::new(solana_root.get_root_path()); + let genesis = Genesis::new(solana_root.get_root_path()); + + match genesis.generate_faucet() { + Ok(_) => (), + Err(err) => { + error!("generate faucet error! {}", err); + return; + } + } } From a42258cffb0693be16324e08caef11fe77223f12 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 28 Mar 2024 18:10:38 +0000 Subject: [PATCH 09/49] add validator type enum --- src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f4865b7..58f63d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,25 @@ impl SolanaRoot { } } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ValidatorType { + Bootstrap, + Standard, + NonVoting, + Client, +} + +impl std::fmt::Display for ValidatorType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + ValidatorType::Bootstrap => write!(f, "bootstrap"), + ValidatorType::Standard => write!(f, "validator"), + ValidatorType::NonVoting => write!(f, "non-voting"), + ValidatorType::Client => write!(f, "client"), + } + } +} + pub mod genesis; pub mod kubernetes; pub mod release; From c2d1c1bfeee7be1aa9833bf6e520574e22b377d1 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 28 Mar 2024 19:51:23 +0000 Subject: [PATCH 10/49] add generate bootstrap accounts. and struct for generating other validator accounts --- Cargo.lock | 1 - Cargo.toml | 3 +- src/genesis.rs | 99 +++++++++++++++++++++++++++++++++++++++++--------- src/lib.rs | 6 +-- src/main.rs | 12 +++++- 5 files changed, 95 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b9e521..3638624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7142,7 +7142,6 @@ dependencies = [ "strum_macros 0.26.2", "subtle", "tar", - "tiny-bip39", "tokio", "url 2.5.0", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index 2ce64ea..c98d591 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ strum = "0.26.2" strum_macros = "0.26.2" subtle = "2.4.1" tar = "0.4.40" -tiny-bip39 = "0.8.2" tokio = { version = "1.29.1", features = ["full"] } url = "2.5.0" # See "zeroize versioning issues" below if you are updating this version. @@ -113,4 +112,4 @@ rev = "6105d7a5591aefa646a95d12b5e8d3f55a9214ef" # [patch.crates-io.curve25519-dalek] git = "https://github.com/solana-labs/curve25519-dalek.git" -rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" \ No newline at end of file +rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" diff --git a/src/genesis.rs b/src/genesis.rs index 856b2c3..e250b19 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -1,21 +1,15 @@ use { + crate::ValidatorType, log::*, rand::Rng, solana_core::gen_keys::GenKeys, - solana_sdk::signature::{Keypair, write_keypair_file}, - std::{ - error::Error, - path::PathBuf, - result::Result, - }, + solana_sdk::signature::{write_keypair_file, Keypair}, + std::{error::Error, path::PathBuf, result::Result}, }; -fn output_keypair(keypair: &Keypair, outfile: &str) -> Result<(), Box> { - write_keypair_file(keypair, outfile)?; - Ok(()) -} pub struct Genesis { - pub config_dir: PathBuf, + config_dir: PathBuf, + key_generator: GenKeys, } impl Genesis { @@ -25,18 +19,87 @@ impl Genesis { std::fs::remove_dir_all(&config_dir).unwrap(); } std::fs::create_dir_all(&config_dir).unwrap(); - Genesis { config_dir } + + let seed: [u8; 32] = rand::thread_rng().gen(); + + Self { + config_dir, + key_generator: GenKeys::new(seed), + } } - pub fn generate_faucet(&self) -> Result<(), Box> { + pub fn generate_faucet(&mut self) -> Result<(), Box> { info!("generating faucet keypair"); let outfile = self.config_dir.join("faucet.json"); - let seed: [u8; 32] = rand::thread_rng().gen(); - let keypair = GenKeys::new(seed).gen_keypair(); + let keypair = self.key_generator.gen_keypair(); + + write_keypair_file(&keypair, outfile)?; + Ok(()) + } + + pub fn generate_accounts( + &mut self, + validator_type: ValidatorType, + number_of_accounts: usize, + ) -> Result<(), Box> { + if validator_type == ValidatorType::Client { + return Err("Client valdiator_type in generate_accounts not allowed".into()); + } + + info!( + "generating {} {} accounts...", + number_of_accounts, validator_type + ); + + let mut account_types = vec!["identity", "stake-account", "vote-account"]; + match validator_type { + ValidatorType::Bootstrap | ValidatorType::Standard => (), + ValidatorType::RPC => { + account_types.pop(); // no vote-account for RPC + } + ValidatorType::Client => panic!("Client type not supported"), + }; + + let total_accounts_to_generate = number_of_accounts * account_types.len(); + let keypairs = self + .key_generator + .gen_n_keypairs(total_accounts_to_generate as u64); + + self.write_accounts_to_file(validator_type, account_types, keypairs)?; + + Ok(()) + } + + fn write_accounts_to_file( + &self, + validator_type: ValidatorType, + account_types: Vec<&str>, + keypairs: Vec, //TODO: reference this + ) -> Result<(), Box> { + for (i, keypair) in keypairs.iter().enumerate() { + let account_index = i / account_types.len(); + let account = account_types[i % account_types.len()]; + let filename = match validator_type { + ValidatorType::Bootstrap => { + format!("{}/{}.json", validator_type.to_string(), account) + } + ValidatorType::Standard => format!( + "{}-{}-{}.json", + validator_type.to_string(), + account, + account_index + ), + ValidatorType::RPC => format!( + "{}-{}-{}.json", + validator_type.to_string(), + account, + account_index + ), + ValidatorType::Client => panic!("Client type not supported"), + }; - if let Some(outfile) = outfile.to_str() { - output_keypair(&keypair, outfile) - .map_err(|err| format!("Unable to write {outfile}: {err}"))?; + let outfile = self.config_dir.join(&filename); + write_keypair_file(&keypair, outfile)?; } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 58f63d0..bc68d8e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,16 +45,16 @@ impl SolanaRoot { pub enum ValidatorType { Bootstrap, Standard, - NonVoting, + RPC, Client, } impl std::fmt::Display for ValidatorType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { - ValidatorType::Bootstrap => write!(f, "bootstrap"), + ValidatorType::Bootstrap => write!(f, "bootstrap-validator"), ValidatorType::Standard => write!(f, "validator"), - ValidatorType::NonVoting => write!(f, "non-voting"), + ValidatorType::RPC => write!(f, "rpc-node"), ValidatorType::Client => write!(f, "client"), } } diff --git a/src/main.rs b/src/main.rs index a4fea4e..9daf10a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use { genesis::Genesis, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, - SolanaRoot, + SolanaRoot, ValidatorType, }, }; @@ -127,7 +127,7 @@ async fn main() { } } - let genesis = Genesis::new(solana_root.get_root_path()); + let mut genesis = Genesis::new(solana_root.get_root_path()); match genesis.generate_faucet() { Ok(_) => (), @@ -136,4 +136,12 @@ async fn main() { return; } } + + match genesis.generate_accounts(ValidatorType::Bootstrap, 1) { + Ok(_) => (), + Err(err) => { + error!("generate accounts error! {}", err); + return; + } + } } From 2b559418ad6a468349465782e61711f529bb9c61 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 28 Mar 2024 22:16:56 +0000 Subject: [PATCH 11/49] add in genesis build and genesis flags --- PROGRESS.md | 4 +- fetch-spl.sh | 62 ++++++++++++++ src/genesis.rs | 218 ++++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 1 + src/main.rs | 125 +++++++++++++++++++++++++++- src/release.rs | 8 +- 6 files changed, 408 insertions(+), 10 deletions(-) create mode 100755 fetch-spl.sh diff --git a/PROGRESS.md b/PROGRESS.md index e97b4ff..45820d4 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -12,9 +12,9 @@ - [x] Setup build config Local - [x] Build from local commit - [x] Build from tar (release version) -- [ ] Create Genesis +- [x] Create Genesis - [x] Generate faucet and bootstrap accounts - - [ ] Build genesis + - [x] Build genesis - [ ] Docker Build - [ ] Build Bootstrap Image - [ ] Push Image to registry diff --git a/fetch-spl.sh b/fetch-spl.sh new file mode 100755 index 0000000..bb8e84e --- /dev/null +++ b/fetch-spl.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +# Fetches the latest SPL programs and produces the solana-genesis command-line +# arguments needed to install them +# + +set -e + +upgradeableLoader=BPFLoaderUpgradeab1e11111111111111111111111 + +fetch_program() { + declare name=$1 + declare version=$2 + declare address=$3 + declare loader=$4 + + declare so=spl_$name-$version.so + + if [[ $loader == "$upgradeableLoader" ]]; then + genesis_args+=(--upgradeable-program "$address" "$loader" "$so" none) + else + genesis_args+=(--bpf-program "$address" "$loader" "$so") + fi + + if [[ -r $so ]]; then + return + fi + + if [[ -r ~/.cache/solana-spl/$so ]]; then + cp ~/.cache/solana-spl/"$so" "$so" + else + echo "Downloading $name $version" + so_name="spl_${name//-/_}.so" + ( + set -x + curl -L --retry 5 --retry-delay 2 --retry-connrefused \ + -o "$so" \ + "https://github.com/solana-labs/solana-program-library/releases/download/$name-v$version/$so_name" + ) + + mkdir -p ~/.cache/solana-spl + cp "$so" ~/.cache/solana-spl/"$so" + fi + +} + +fetch_program token 3.5.0 TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA BPFLoader2111111111111111111111111111111111 +fetch_program token-2022 0.9.0 TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb BPFLoaderUpgradeab1e11111111111111111111111 +fetch_program memo 1.0.0 Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo BPFLoader1111111111111111111111111111111111 +fetch_program memo 3.0.0 MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr BPFLoader2111111111111111111111111111111111 +fetch_program associated-token-account 1.1.2 ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL BPFLoader2111111111111111111111111111111111 +fetch_program feature-proposal 1.0.0 Feat1YXHhH6t1juaWF74WLcfv4XoNocjXA6sPWHNgAse BPFLoader2111111111111111111111111111111111 + +echo "${genesis_args[@]}" > spl-genesis-args.sh + +echo +echo "Available SPL programs:" +ls -l spl_*.so + +echo +echo "solana-genesis command-line arguments (spl-genesis-args.sh):" +cat spl-genesis-args.sh diff --git a/src/genesis.rs b/src/genesis.rs index e250b19..d4c31c6 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -1,19 +1,116 @@ use { - crate::ValidatorType, + crate::{new_spinner_progress_bar, ValidatorType, SUN}, log::*, rand::Rng, solana_core::gen_keys::GenKeys, - solana_sdk::signature::{write_keypair_file, Keypair}, - std::{error::Error, path::PathBuf, result::Result}, + solana_sdk::{ + native_token::sol_to_lamports, + signature::{write_keypair_file, Keypair}, + }, + std::{error::Error, fs::File, io::Read, path::PathBuf, process::Command, result::Result}, }; +pub const DEFAULT_FAUCET_LAMPORTS: u64 = 500000000000000000; // from agave/ +pub const DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE: u64 = 1073741824; // from agave/ +pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 1.0; +pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 10.0; +pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 1.0; +pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 10.0; + +fn fetch_spl(fetch_spl_file: &PathBuf) -> Result<(), Box> { + let output = Command::new("bash") + .arg(fetch_spl_file) + .output() // Capture the output of the script + .expect("Failed to run fetch-spl.sh script"); + + // Check if the script execution was successful + if output.status.success() { + Ok(()) + } else { + Err(format!( + "Failed to fun fetch-spl.sh script: {}", + String::from_utf8_lossy(&output.stderr) + ) + .into()) + } +} + +fn parse_spl_genesis_file(spl_file: &PathBuf) -> Result, Box> { + // Read entire file into a String + let mut file = File::open(spl_file)?; + let mut content = String::new(); + file.read_to_string(&mut content)?; + + // Split by whitespace + let mut args = Vec::new(); + let mut tokens_iter = content.split_whitespace(); + + while let Some(token) = tokens_iter.next() { + args.push(token.to_string()); + // Find flag delimiters + if token.starts_with("--") { + for next_token in tokens_iter.by_ref() { + if next_token.starts_with("--") { + args.push(next_token.to_string()); + } else { + args.push(next_token.to_string()); + break; + } + } + } + } + + Ok(args) +} + +pub struct GenesisFlags { + pub hashes_per_tick: String, + pub slots_per_epoch: Option, + pub target_lamports_per_signature: Option, + pub faucet_lamports: Option, + pub enable_warmup_epochs: bool, + pub max_genesis_archive_unpacked_size: Option, + pub cluster_type: String, + pub bootstrap_validator_sol: Option, + pub bootstrap_validator_stake_sol: Option, +} + +impl std::fmt::Display for GenesisFlags { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "GenesisFlags {{\n\ + hashes_per_tick: {:?},\n\ + slots_per_epoch: {:?},\n\ + target_lamports_per_signature: {:?},\n\ + faucet_lamports: {:?},\n\ + enable_warmup_epochs: {},\n\ + max_genesis_archive_unpacked_size: {:?},\n\ + cluster_type: {}\n\ + bootstrap_validator_sol: {:?},\n\ + bootstrap_validator_stake_sol: {:?},\n\ + }}", + self.hashes_per_tick, + self.slots_per_epoch, + self.target_lamports_per_signature, + self.faucet_lamports, + self.enable_warmup_epochs, + self.max_genesis_archive_unpacked_size, + self.cluster_type, + self.bootstrap_validator_sol, + self.bootstrap_validator_stake_sol, + ) + } +} + pub struct Genesis { config_dir: PathBuf, key_generator: GenKeys, + pub flags: GenesisFlags, } impl Genesis { - pub fn new(solana_root: PathBuf) -> Self { + pub fn new(solana_root: PathBuf, flags: GenesisFlags) -> Self { let config_dir = solana_root.join("config-k8s"); if config_dir.exists() { std::fs::remove_dir_all(&config_dir).unwrap(); @@ -25,6 +122,7 @@ impl Genesis { Self { config_dir, key_generator: GenKeys::new(seed), + flags, } } @@ -103,4 +201,116 @@ impl Genesis { } Ok(()) } + + fn setup_genesis_flags(&self) -> Vec { + let mut args = vec![ + "--bootstrap-validator-lamports".to_string(), + sol_to_lamports( + self.flags + .bootstrap_validator_sol + .unwrap_or(DEFAULT_BOOTSTRAP_NODE_SOL), + ) + .to_string(), + "--bootstrap-validator-stake-lamports".to_string(), + sol_to_lamports( + self.flags + .bootstrap_validator_stake_sol + .unwrap_or(DEFAULT_BOOTSTRAP_NODE_STAKE_SOL), + ) + .to_string(), + "--hashes-per-tick".to_string(), + self.flags.hashes_per_tick.clone(), + "--max-genesis-archive-unpacked-size".to_string(), + self.flags + .max_genesis_archive_unpacked_size + .unwrap_or(DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE) + .to_string(), + "--faucet-lamports".to_string(), + self.flags + .faucet_lamports + .unwrap_or(DEFAULT_FAUCET_LAMPORTS) + .to_string(), + "--faucet-pubkey".to_string(), + self.config_dir + .join("faucet.json") + .to_string_lossy() + .to_string(), + "--cluster-type".to_string(), + self.flags.cluster_type.to_string(), + "--ledger".to_string(), + self.config_dir + .join("bootstrap-validator") + .to_string_lossy() + .to_string(), + ]; + + if self.flags.enable_warmup_epochs { + args.push("--enable-warmup-epochs".to_string()); + } + + args.push("--bootstrap-validator".to_string()); + ["identity", "vote-account", "stake-account"] + .iter() + .for_each(|account_type| { + args.push( + self.config_dir + .join(format!("bootstrap-validator/{}.json", account_type)) + .to_string_lossy() + .to_string(), + ); + }); + + if let Some(slots_per_epoch) = self.flags.slots_per_epoch { + args.push("--slots-per-epoch".to_string()); + args.push(slots_per_epoch.to_string()); + } + + if let Some(lamports_per_signature) = self.flags.target_lamports_per_signature { + args.push("--target-lamports-per-signature".to_string()); + args.push(lamports_per_signature.to_string()); + } + + args + } + + pub fn setup_spl_args(&self, solana_root_path: PathBuf) -> Result, Box> { + let fetch_spl_file = solana_root_path.join("fetch-spl.sh"); + fetch_spl(&fetch_spl_file)?; + + // add in spl stuff + let spl_file = solana_root_path.join("spl-genesis-args.sh"); + parse_spl_genesis_file(&spl_file) + } + + pub fn generate( + &mut self, + solana_root_path: PathBuf, + build_path: PathBuf, + ) -> Result<(), Box> { + let mut args = self.setup_genesis_flags(); + let mut spl_args = self.setup_spl_args(solana_root_path)?; + args.append(&mut spl_args); + + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!("{SUN}Building Genesis...")); + + let executable_path = build_path.join("solana-genesis"); + let output = Command::new(executable_path) + .args(&args) + .output() + .expect("Failed to execute solana-genesis"); + + progress_bar.finish_and_clear(); + + if !output.status.success() { + return Err(format!( + "Failed to create genesis. err: {}", + String::from_utf8_lossy(&output.stderr) + ) + .into()); + } + info!("Genesis build complete"); + + Ok(()) + } } diff --git a/src/lib.rs b/src/lib.rs index bc68d8e..c18df08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,6 +64,7 @@ pub mod genesis; pub mod kubernetes; pub mod release; +static SUN: Emoji = Emoji("🌞 ", ""); static PACKAGE: Emoji = Emoji("📦 ", ""); static TRUCK: Emoji = Emoji("🚚 ", ""); diff --git a/src/main.rs b/src/main.rs index 9daf10a..6edb45f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use { std::fs, strum::VariantNames, validator_lab::{ - genesis::Genesis, + genesis::{Genesis, GenesisFlags}, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, SolanaRoot, ValidatorType, @@ -48,6 +48,68 @@ fn parse_matches() -> clap::ArgMatches { .args(&["local_path", "release_channel"]) .required(true), ) + // Genesis Config + .arg( + Arg::with_name("hashes_per_tick") + .long("hashes-per-tick") + .takes_value(true) + .default_value("auto") + .help("NUM_HASHES|sleep|auto - Override the default --hashes-per-tick for the cluster"), + ) + .arg( + Arg::with_name("slots_per_epoch") + .long("slots-per-epoch") + .takes_value(true) + .help("override the number of slots in an epoch"), + ) + .arg( + Arg::with_name("target_lamports_per_signature") + .long("target-lamports-per-signature") + .takes_value(true) + .help("Genesis config. target lamports per signature"), + ) + .arg( + Arg::with_name("faucet_lamports") + .long("faucet-lamports") + .takes_value(true) + .help("Override the default 500000000000000000 lamports minted in genesis"), + ) + .arg( + Arg::with_name("enable_warmup_epochs") + .long("enable-warmup-epochs") + .takes_value(true) + .possible_values(&["true", "false"]) + .default_value("true") + .help("Genesis config. enable warmup epoch. defaults to true"), + ) + .arg( + Arg::with_name("max_genesis_archive_unpacked_size") + .long("max-genesis-archive-unpacked-size") + .takes_value(true) + .help("Genesis config. max_genesis_archive_unpacked_size"), + ) + .arg( + Arg::with_name("cluster_type") + .long("cluster-type") + .possible_values(&["development", "devnet", "testnet", "mainnet-beta"]) + .takes_value(true) + .default_value("development") + .help( + "Selects the features that will be enabled for the cluster" + ), + ) + .arg( + Arg::with_name("bootstrap_validator_sol") + .long("bootstrap-validator-sol") + .takes_value(true) + .help("Genesis config. bootstrap validator sol"), + ) + .arg( + Arg::with_name("bootstrap_validator_stake_sol") + .long("bootstrap-validator-stake-sol") + .takes_value(true) + .help("Genesis config. bootstrap validator stake sol"), + ) .get_matches() } @@ -119,6 +181,56 @@ async fn main() { panic!("Error creating BuildConfig: {}", err); }); + let genesis_flags = GenesisFlags { + hashes_per_tick: matches + .value_of("hashes_per_tick") + .unwrap_or_default() + .to_string(), + slots_per_epoch: matches.value_of("slots_per_epoch").map(|value_str| { + value_str + .parse() + .expect("Invalid value for slots_per_epoch") + }), + target_lamports_per_signature: matches.value_of("target_lamports_per_signature").map( + |value_str| { + value_str + .parse() + .expect("Invalid value for target_lamports_per_signature") + }, + ), + faucet_lamports: matches.value_of("faucet_lamports").map(|value_str| { + value_str + .parse() + .expect("Invalid value for faucet_lamports") + }), + enable_warmup_epochs: matches.value_of("enable_warmup_epochs").unwrap() == "true", + max_genesis_archive_unpacked_size: matches + .value_of("max_genesis_archive_unpacked_size") + .map(|value_str| { + value_str + .parse() + .expect("Invalid value for max_genesis_archive_unpacked_size") + }), + cluster_type: matches + .value_of("cluster_type") + .unwrap_or_default() + .to_string(), + bootstrap_validator_sol: matches + .value_of("bootstrap_validator_sol") + .map(|value_str| { + value_str + .parse() + .expect("Invalid value for bootstrap_validator_sol") + }), + bootstrap_validator_stake_sol: matches.value_of("bootstrap_validator_stake_sol").map( + |value_str| { + value_str + .parse() + .expect("Invalid value for bootstrap_validator_stake_sol") + }, + ), + }; + match build_config.prepare().await { Ok(_) => info!("Validator setup prepared successfully"), Err(err) => { @@ -127,7 +239,7 @@ async fn main() { } } - let mut genesis = Genesis::new(solana_root.get_root_path()); + let mut genesis = Genesis::new(solana_root.get_root_path(), genesis_flags); match genesis.generate_faucet() { Ok(_) => (), @@ -144,4 +256,13 @@ async fn main() { return; } } + + // creates genesis and writes to binary file + match genesis.generate(solana_root.get_root_path(), build_config.build_path()) { + Ok(_) => (), + Err(err) => { + error!("generate genesis error! {}", err); + return; + } + } } diff --git a/src/release.rs b/src/release.rs index fab5628..cd03f33 100644 --- a/src/release.rs +++ b/src/release.rs @@ -23,7 +23,7 @@ pub enum BuildType { pub struct BuildConfig { deploy_method: DeployMethod, build_type: BuildType, - _build_path: PathBuf, + build_path: PathBuf, solana_root_path: PathBuf, } @@ -41,11 +41,15 @@ impl BuildConfig { Ok(BuildConfig { deploy_method, build_type, - _build_path: build_path, + build_path, solana_root_path: solana_root_path.clone(), }) } + pub fn build_path(&self) -> PathBuf { + self.build_path.clone() + } + pub async fn prepare(&self) -> Result<(), Box> { match &self.deploy_method { DeployMethod::ReleaseChannel(channel) => match self.setup_tar_deploy(channel).await { From f31b79d0e92bf058c3d3a7ff3764742f235b27c9 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 29 Mar 2024 16:10:08 +0000 Subject: [PATCH 12/49] wip. bug in docker build --- PROGRESS.md | 2 +- src/docker.rs | 169 +++++++++++++++++++++ src/lib.rs | 4 +- src/main.rs | 68 +++++++++ src/release.rs | 7 + src/scripts/bootstrap-startup-scripts.sh | 184 +++++++++++++++++++++++ src/scripts/common.sh | 123 +++++++++++++++ 7 files changed, 555 insertions(+), 2 deletions(-) create mode 100644 src/docker.rs create mode 100644 src/scripts/bootstrap-startup-scripts.sh create mode 100644 src/scripts/common.sh diff --git a/PROGRESS.md b/PROGRESS.md index 45820d4..5c5701f 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -16,7 +16,7 @@ - [x] Generate faucet and bootstrap accounts - [x] Build genesis - [ ] Docker Build - - [ ] Build Bootstrap Image + - [x] Build Bootstrap Image - [ ] Push Image to registry - [ ] Create & Deploy Secrets - [ ] Bootstrap diff --git a/src/docker.rs b/src/docker.rs new file mode 100644 index 0000000..d132cc5 --- /dev/null +++ b/src/docker.rs @@ -0,0 +1,169 @@ +use { + crate::{ + boxed_error, new_spinner_progress_bar, ValidatorType, BUILD, + }, + log::*, + std::{ + error::Error, + fs, + path::PathBuf, + process::{Command, Output, Stdio}, + }, +}; + +pub struct DockerConfig { + pub base_image: String, + pub image_name: String, + pub tag: String, + pub registry: String, + deploy_method: String, +} + +impl DockerConfig { + pub fn new( + base_image: String, + image_name: String, + tag: String, + registry: String, + deploy_method: String, + ) -> Self { + DockerConfig { + base_image, + image_name, + tag, + registry, + deploy_method, + } + } + + pub fn build_image(&self, solana_root_path: PathBuf, validator_type: &ValidatorType) -> Result<(), Box> { + let image_name = format!("{}-{}", validator_type, self.image_name); + let docker_path = solana_root_path.join(format!("{}/{}", "docker-build", validator_type)); + match self.create_base_image(solana_root_path, image_name, docker_path, validator_type) { + Ok(res) => { + if res.status.success() { + info!("Successfully created base Image"); + Ok(()) + } else { + error!("Failed to build base image"); + Err(boxed_error!(String::from_utf8_lossy(&res.stderr))) + } + } + Err(err) => Err(err), + } + } + + pub fn create_base_image( + &self, + solana_root_path: PathBuf, + image_name: String, + docker_path: PathBuf, + validator_type: &ValidatorType, + ) -> Result> { + let dockerfile_path = self.create_dockerfile(validator_type, docker_path, None)?; + + trace!("Tmp: {}", dockerfile_path.as_path().display()); + trace!("Exists: {}", dockerfile_path.as_path().exists()); + + // We use std::process::Command here because Docker-rs is very slow building dockerfiles + // when they are in large repos. Docker-rs doesn't seem to support the `--file` flag natively. + // so we result to using std::process::Command + let dockerfile = dockerfile_path.join("Dockerfile"); + let context_path = solana_root_path.display().to_string(); + + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!( + "{BUILD}Building {} docker image...", + validator_type + )); + + let command = format!( + "docker build -t {}/{}:{} -f {:?} {}", + self.registry, image_name, self.tag, dockerfile, context_path + ); + info!("command: {}", command); + let output = match Command::new("sh") + .arg("-c") + .arg(&command) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .expect("Failed to execute command") + .wait_with_output() + { + Ok(res) => Ok(res), + Err(err) => Err(Box::new(err) as Box), + }; + progress_bar.finish_and_clear(); + info!("{} image build complete", validator_type); + + output + } + + pub fn create_dockerfile( + &self, + validator_type: &ValidatorType, + docker_path: PathBuf, + content: Option<&str>, + ) -> Result> { + match validator_type { + ValidatorType::Bootstrap | ValidatorType::Standard | ValidatorType::RPC => (), + _ => { + return Err(boxed_error!(format!( + "Invalid validator type: {}. Exiting...", + validator_type + ))); + } + } + + if docker_path.exists() { + fs::remove_dir_all(&docker_path)?; + } + fs::create_dir_all(&docker_path)?; + + let solana_build_directory = if self.deploy_method == "tar" { + "solana-release" + } else { + "farf" + }; + + //TODO: I Removed some stuff from this dockerfile. may need to add some stuff back in + let dockerfile = format!( + r#" +FROM {} +RUN apt-get update +RUN apt-get install -y iputils-ping curl vim bzip2 + +RUN useradd -ms /bin/bash solana +RUN adduser solana sudo +USER solana + +RUN mkdir -p /home/solana/k8s-cluster-scripts +COPY ./src/scripts /home/solana/k8s-cluster-scripts + +RUN mkdir -p /home/solana/ledger +COPY --chown=solana:solana ./config-k8s/bootstrap-validator /home/solana/ledger + +RUN mkdir -p /home/solana/.cargo/bin + +COPY ./{solana_build_directory}/bin/ /home/solana/.cargo/bin/ +COPY ./{solana_build_directory}/version.yml /home/solana/ + +RUN mkdir -p /home/solana/config +ENV PATH="/home/solana/.cargo/bin:${{PATH}}" + +WORKDIR /home/solana + +"#, + self.base_image + ); + + debug!("dockerfile: {}", dockerfile); + std::fs::write( + docker_path.as_path().join("Dockerfile"), + content.unwrap_or(dockerfile.as_str()), + ) + .expect("saved Dockerfile"); + Ok(docker_path) + } +} diff --git a/src/lib.rs b/src/lib.rs index c18df08..483a91c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,12 +60,14 @@ impl std::fmt::Display for ValidatorType { } } +pub mod docker; pub mod genesis; pub mod kubernetes; pub mod release; -static SUN: Emoji = Emoji("🌞 ", ""); +static BUILD: Emoji = Emoji("👷 ", ""); static PACKAGE: Emoji = Emoji("📦 ", ""); +static SUN: Emoji = Emoji("🌞 ", ""); static TRUCK: Emoji = Emoji("🚚 ", ""); /// Creates a new process bar for processing that will take an unknown amount of time diff --git a/src/main.rs b/src/main.rs index 6edb45f..23cec4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use { std::fs, strum::VariantNames, validator_lab::{ + docker::DockerConfig, genesis::{Genesis, GenesisFlags}, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, @@ -110,6 +111,47 @@ fn parse_matches() -> clap::ArgMatches { .takes_value(true) .help("Genesis config. bootstrap validator stake sol"), ) + //Docker config + .arg( + Arg::with_name("docker_build") + .long("docker-build") + .requires("registry_name") + .requires("image_name") + .requires("base_image") + .requires("image_tag") + .help("Build Docker images. Build new docker images"), + ) + .arg( + Arg::with_name("registry_name") + .long("registry") + .takes_value(true) + .required(true) + .help("Registry to push docker image to"), + ) + .arg( + Arg::with_name("image_name") + .long("image-name") + .takes_value(true) + .default_value("k8s-cluster-image") + .required(true) + .help("Docker image name. Will be prepended with validator_type (bootstrap or validator)"), + ) + .arg( + Arg::with_name("base_image") + .long("base-image") + .takes_value(true) + .default_value("ubuntu:20.04") + .required(true) + .help("Docker base image"), + ) + .arg( + Arg::with_name("image_tag") + .long("tag") + .takes_value(true) + .required(true) + .default_value("latest") + .help("Docker image tag."), + ) .get_matches() } @@ -265,4 +307,30 @@ async fn main() { return; } } + + //unwraps are safe here. since their requirement is enforced by argmatches + let docker = DockerConfig::new( + matches + .value_of("base_image") + .unwrap_or_default() + .to_string(), + matches.value_of("image_name").unwrap().to_string(), + matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(), + matches.value_of("registry_name").unwrap().to_string(), + deploy_method.to_string(), + ); + + if build_config.docker_build() { + let image_type = ValidatorType::Bootstrap; + match docker.build_image(solana_root.get_root_path(), &image_type) { + Ok(_) => info!("{} image built successfully", image_type), + Err(err) => { + error!("Exiting........ {}", err); + return; + } + } + } } diff --git a/src/release.rs b/src/release.rs index cd03f33..7fcadf7 100644 --- a/src/release.rs +++ b/src/release.rs @@ -25,6 +25,7 @@ pub struct BuildConfig { build_type: BuildType, build_path: PathBuf, solana_root_path: PathBuf, + docker_build: bool, } impl BuildConfig { @@ -32,6 +33,7 @@ impl BuildConfig { deploy_method: DeployMethod, build_type: BuildType, solana_root_path: &PathBuf, + docker_build: bool, ) -> Result> { let build_path = match deploy_method { DeployMethod::Local(_) => solana_root_path.join("farf/bin"), @@ -43,6 +45,7 @@ impl BuildConfig { build_type, build_path, solana_root_path: solana_root_path.clone(), + docker_build, }) } @@ -50,6 +53,10 @@ impl BuildConfig { self.build_path.clone() } + pub fn docker_build(&self) -> bool { + self.docker_build + } + pub async fn prepare(&self) -> Result<(), Box> { match &self.deploy_method { DeployMethod::ReleaseChannel(channel) => match self.setup_tar_deploy(channel).await { diff --git a/src/scripts/bootstrap-startup-scripts.sh b/src/scripts/bootstrap-startup-scripts.sh new file mode 100644 index 0000000..56e0a7e --- /dev/null +++ b/src/scripts/bootstrap-startup-scripts.sh @@ -0,0 +1,184 @@ +#!/bin/bash +set -e + +# start faucet +nohup solana-faucet --keypair bootstrap-accounts/faucet.json & + +# Start the bootstrap validator node +# shellcheck disable=SC1091 +source /home/solana/k8s-cluster-scripts/common.sh + +program="agave-validator" + +no_restart=0 + +echo "PROGRAM: $program" + +args=() +while [[ -n $1 ]]; do + if [[ ${1:0:1} = - ]]; then + if [[ $1 = --init-complete-file ]]; then + args+=("$1" "$2") + shift 2 + elif [[ $1 = --gossip-host ]]; then # set with env variables + args+=("$1" "$2") + shift 2 + elif [[ $1 = --gossip-port ]]; then # set with env variables + args+=("$1" "$2") + shift 2 + elif [[ $1 = --dev-halt-at-slot ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + elif [[ $1 = --dynamic-port-range ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + elif [[ $1 = --limit-ledger-size ]]; then + args+=("$1" "$2") + shift 2 + elif [[ $1 = --no-rocksdb-compaction ]]; then # not enabled in net.sh + args+=("$1") + shift + elif [[ $1 = --enable-rpc-transaction-history ]]; then # enabled through full-rpc + args+=("$1") + shift + elif [[ $1 = --rpc-pubsub-enable-block-subscription ]]; then # not enabled in net.sh + args+=("$1") + shift + elif [[ $1 = --enable-cpi-and-log-storage ]]; then # not enabled in net.sh + args+=("$1") + shift + elif [[ $1 = --enable-extended-tx-metadata-storage ]]; then # enabled through full-rpc + args+=("$1") + shift + elif [[ $1 = --enable-rpc-bigtable-ledger-storage ]]; then + args+=("$1") + shift + elif [[ $1 = --tpu-disable-quic ]]; then + args+=("$1") + shift + elif [[ $1 = --tpu-enable-udp ]]; then + args+=("$1") + shift + elif [[ $1 = --rpc-send-batch-ms ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + elif [[ $1 = --rpc-send-batch-size ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + elif [[ $1 = --skip-poh-verify ]]; then + args+=("$1") + shift + elif [[ $1 = --no-restart ]]; then # not enabled in net.sh + no_restart=1 + shift + elif [[ $1 == --wait-for-supermajority ]]; then + args+=("$1" "$2") + shift 2 + elif [[ $1 == --expected-bank-hash ]]; then + args+=("$1" "$2") + shift 2 + elif [[ $1 == --accounts ]]; then + args+=("$1" "$2") + shift 2 + elif [[ $1 == --maximum-snapshots-to-retain ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + elif [[ $1 == --no-snapshot-fetch ]]; then + args+=("$1") + shift + elif [[ $1 == --accounts-db-skip-shrink ]]; then + args+=("$1") + shift + elif [[ $1 == --require-tower ]]; then + args+=("$1") + shift + elif [[ $1 = --log-messages-bytes-limit ]]; then # not enabled in net.sh + args+=("$1" "$2") + shift 2 + else + echo "Unknown argument: $1" + $program --help + exit 1 + fi + else + echo "Unknown argument: $1" + $program --help + exit 1 + fi +done + +# These keypairs are created by ./setup.sh and included in the genesis config +identity=bootstrap-accounts/identity.json +vote_account=bootstrap-accounts/vote.json + +ledger_dir=/home/solana/ledger +[[ -d "$ledger_dir" ]] || { + echo "$ledger_dir does not exist" + exit 1 +} + +args+=( + --no-os-network-limits-test \ + --no-wait-for-vote-to-start-leader \ + --snapshot-interval-slots 200 \ + --identity "$identity" \ + --vote-account "$vote_account" \ + --ledger ledger \ + --log - \ + --gossip-host "$MY_POD_IP" \ + --gossip-port 8001 \ + --rpc-port 8899 \ + --rpc-faucet-address "$MY_POD_IP":9900 \ + --no-poh-speed-test \ + --no-incremental-snapshots \ + --full-rpc-api \ + --allow-private-addr \ + --enable-rpc-transaction-history +) + +echo "Bootstrap Args" +for arg in "${args[@]}"; do + echo "$arg" +done + +pid= +kill_node() { + # Note: do not echo anything from this function to ensure $pid is actually + # killed when stdout/stderr are redirected + set +ex + if [[ -n $pid ]]; then + declare _pid=$pid + pid= + kill "$_pid" || true + wait "$_pid" || true + fi +} + +kill_node_and_exit() { + kill_node + exit +} + +trap 'kill_node_and_exit' INT TERM ERR + +while true; do + echo "$program ${args[*]}" + $program "${args[@]}" & + pid=$! + echo "pid: $pid" + + if ((no_restart)); then + wait "$pid" + exit $? + fi + + while true; do + if [[ -z $pid ]] || ! kill -0 "$pid"; then + echo "############## validator exited, restarting ##############" + break + fi + sleep 1 + done + + kill_node +done diff --git a/src/scripts/common.sh b/src/scripts/common.sh new file mode 100644 index 0000000..dd7a32d --- /dev/null +++ b/src/scripts/common.sh @@ -0,0 +1,123 @@ +# |source| this file +# +# Common utilities shared by other scripts in this directory +# +# The following directive disable complaints about unused variables in this +# file: +# shellcheck disable=2034 + +prebuild= +if [[ $1 = "--prebuild" ]]; then + prebuild=true +fi + +if [[ $(uname) != Linux ]]; then + # Protect against unsupported configurations to prevent non-obvious errors + # later. Arguably these should be fatal errors but for now prefer tolerance. + if [[ -n $SOLANA_CUDA ]]; then + echo "Warning: CUDA is not supported on $(uname)" + SOLANA_CUDA= + fi +fi + +if [[ -n $USE_INSTALL || ! -f "$SOLANA_ROOT"/Cargo.toml ]]; then + # echo "define if solana program" + solana_program() { + # echo "call if solana program" + declare program="$1" + if [[ -z $program ]]; then + printf "solana" + else + printf "solana-%s" "$program" + fi + } +else + echo "define else solana program" + solana_program() { + echo "call if solana program" + declare program="$1" + declare crate="$program" + if [[ -z $program ]]; then + crate="cli" + program="solana" + else + program="solana-$program" + fi + + if [[ -n $NDEBUG ]]; then + maybe_release=--release + fi + + # Prebuild binaries so that CI sanity check timeout doesn't include build time + if [[ $prebuild ]]; then + ( + set -x + # shellcheck disable=SC2086 # Don't want to double quote + cargo $CARGO_TOOLCHAIN build $maybe_release --bin $program + ) + fi + + printf "cargo $CARGO_TOOLCHAIN run $maybe_release --bin %s %s -- " "$program" + } +fi + +solana_bench_tps=$(solana_program bench-tps) +solana_faucet=$(solana_program faucet) +solana_validator=$(solana_program validator) +solana_validator_cuda="$solana_validator --cuda" +solana_genesis=$(solana_program genesis) +solana_gossip=$(solana_program gossip) +solana_keygen=$(solana_program keygen) +solana_ledger_tool=$(solana_program ledger-tool) +solana_cli=$(solana_program) + +export RUST_BACKTRACE=1 + +# https://gist.github.com/cdown/1163649 +urlencode() { + declare s="$1" + declare l=$((${#s} - 1)) + for i in $(seq 0 $l); do + declare c="${s:$i:1}" + case $c in + [a-zA-Z0-9.~_-]) + echo -n "$c" + ;; + *) + printf '%%%02X' "'$c" + ;; + esac + done +} + +default_arg() { + declare name=$1 + declare value=$2 + + for arg in "${args[@]}"; do + if [[ $arg = "$name" ]]; then + return + fi + done + + if [[ -n $value ]]; then + args+=("$name" "$value") + else + args+=("$name") + fi +} + +replace_arg() { + declare name=$1 + declare value=$2 + + default_arg "$name" "$value" + + declare index=0 + for arg in "${args[@]}"; do + index=$((index + 1)) + if [[ $arg = "$name" ]]; then + args[$index]="$value" + fi + done +} From fac42c44bf8abe161e5199e5ebfecdd04f20db00 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 29 Mar 2024 20:34:11 +0000 Subject: [PATCH 13/49] build docker bootstrap image --- README.md | 24 +++++ src/docker.rs | 91 ++++++++++++------- src/genesis.rs | 2 +- src/main.rs | 15 ++- src/release.rs | 2 +- ...scripts.sh => bootstrap-startup-script.sh} | 0 6 files changed, 94 insertions(+), 40 deletions(-) rename src/scripts/{bootstrap-startup-scripts.sh => bootstrap-startup-script.sh} (100%) diff --git a/README.md b/README.md index 0580e91..0d27e3f 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,27 @@ cargo run --bin cluster -- -n --release-channel # note: MUST include the "v" ``` + +#### Build from Local Repo and Configure Genesis and Bootstrap Validator Image +Example: +``` +cargo run --bin cluster -- + -n + --deploy-method local + --local-path /home/sol/solana + # genesis config. Optional: Many of these have defaults + --hashes-per-tick + --enable-warmup-epochs + --faucet-lamports + --bootstrap-validator-sol + --bootstrap-validator-stake-sol + --max-genesis-archive-unpacked-size + --target-lamports-per-signature + --slots-per-epoch + # docker config + --registry # e.g. gregcusack + --docker-build + --tag # e.g. v1 + --base-image # e.g. ubuntu:20.04 + --image-name # e.g. cluster-image +``` \ No newline at end of file diff --git a/src/docker.rs b/src/docker.rs index d132cc5..a1431f8 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,12 +1,11 @@ use { - crate::{ - boxed_error, new_spinner_progress_bar, ValidatorType, BUILD, - }, + crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD}, log::*, std::{ + env, error::Error, fs, - path::PathBuf, + path::{Path, PathBuf}, process::{Command, Output, Stdio}, }, }; @@ -16,7 +15,7 @@ pub struct DockerConfig { pub image_name: String, pub tag: String, pub registry: String, - deploy_method: String, + deploy_method: DeployMethod, } impl DockerConfig { @@ -25,7 +24,7 @@ impl DockerConfig { image_name: String, tag: String, registry: String, - deploy_method: String, + deploy_method: DeployMethod, ) -> Self { DockerConfig { base_image, @@ -36,7 +35,21 @@ impl DockerConfig { } } - pub fn build_image(&self, solana_root_path: PathBuf, validator_type: &ValidatorType) -> Result<(), Box> { + pub fn build_image( + &self, + solana_root_path: PathBuf, + validator_type: &ValidatorType, + ) -> Result<(), Box> { + match validator_type { + ValidatorType::Bootstrap => (), + ValidatorType::Standard | ValidatorType::RPC | ValidatorType::Client => { + return Err(format!( + "Build docker image for validator type: {} not supported yet", + validator_type + ) + .into()); + } + } let image_name = format!("{}-{}", validator_type, self.image_name); let docker_path = solana_root_path.join(format!("{}/{}", "docker-build", validator_type)); match self.create_base_image(solana_root_path, image_name, docker_path, validator_type) { @@ -46,16 +59,16 @@ impl DockerConfig { Ok(()) } else { error!("Failed to build base image"); - Err(boxed_error!(String::from_utf8_lossy(&res.stderr))) + Err(String::from_utf8_lossy(&res.stderr).into()) } } Err(err) => Err(err), } } - pub fn create_base_image( + fn create_base_image( &self, - solana_root_path: PathBuf, + solana_root_path: PathBuf, image_name: String, docker_path: PathBuf, validator_type: &ValidatorType, @@ -100,34 +113,46 @@ impl DockerConfig { output } - pub fn create_dockerfile( + fn copy_file_to_docker( + source_dir: &Path, + docker_dir: &Path, + file_name: &str, + ) -> std::io::Result<()> { + let source_path = source_dir.join("src/scripts").join(file_name); + let destination_path = docker_dir.join(file_name); + fs::copy(&source_path, &destination_path)?; + Ok(()) + } + + fn create_dockerfile( &self, validator_type: &ValidatorType, docker_path: PathBuf, content: Option<&str>, - ) -> Result> { - match validator_type { - ValidatorType::Bootstrap | ValidatorType::Standard | ValidatorType::RPC => (), - _ => { - return Err(boxed_error!(format!( - "Invalid validator type: {}. Exiting...", - validator_type - ))); - } - } - + ) -> Result> { if docker_path.exists() { fs::remove_dir_all(&docker_path)?; } fs::create_dir_all(&docker_path)?; - let solana_build_directory = if self.deploy_method == "tar" { - "solana-release" - } else { - "farf" - }; + if let DeployMethod::Local(_) = self.deploy_method { + if validator_type == &ValidatorType::Bootstrap { + let manifest_path = + PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")); + let files_to_copy = ["bootstrap-startup-script.sh", "common.sh"]; + for file_name in files_to_copy.iter() { + Self::copy_file_to_docker(&manifest_path, &docker_path, file_name)?; + } + } + } + + let (solana_build_directory, startup_script_directory) = + if let DeployMethod::ReleaseChannel(_) = self.deploy_method { + ("solana-release", "./src/scripts".to_string()) + } else { + ("farf", format!("./docker-build/{}", validator_type)) + }; - //TODO: I Removed some stuff from this dockerfile. may need to add some stuff back in let dockerfile = format!( r#" FROM {} @@ -139,8 +164,9 @@ RUN adduser solana sudo USER solana RUN mkdir -p /home/solana/k8s-cluster-scripts -COPY ./src/scripts /home/solana/k8s-cluster-scripts - +# TODO: this needs to be changed for non bootstrap, this should be ./src/scripts/-startup-scripts.sh +COPY {startup_script_directory}/bootstrap-startup-script.sh /home/solana/k8s-cluster-scripts + RUN mkdir -p /home/solana/ledger COPY --chown=solana:solana ./config-k8s/bootstrap-validator /home/solana/ledger @@ -160,10 +186,9 @@ WORKDIR /home/solana debug!("dockerfile: {}", dockerfile); std::fs::write( - docker_path.as_path().join("Dockerfile"), + docker_path.join("Dockerfile"), content.unwrap_or(dockerfile.as_str()), - ) - .expect("saved Dockerfile"); + )?; Ok(docker_path) } } diff --git a/src/genesis.rs b/src/genesis.rs index d4c31c6..b334aef 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -277,7 +277,7 @@ impl Genesis { let fetch_spl_file = solana_root_path.join("fetch-spl.sh"); fetch_spl(&fetch_spl_file)?; - // add in spl stuff + // add in spl let spl_file = solana_root_path.join("spl-genesis-args.sh"); parse_spl_genesis_file(&spl_file) } diff --git a/src/main.rs b/src/main.rs index 23cec4c..e186803 100644 --- a/src/main.rs +++ b/src/main.rs @@ -218,10 +218,15 @@ async fn main() { } } - let build_config = BuildConfig::new(deploy_method, build_type, &solana_root.get_root_path()) - .unwrap_or_else(|err| { - panic!("Error creating BuildConfig: {}", err); - }); + let build_config = BuildConfig::new( + deploy_method.clone(), + build_type, + &solana_root.get_root_path(), + matches.is_present("docker_build"), + ) + .unwrap_or_else(|err| { + panic!("Error creating BuildConfig: {}", err); + }); let genesis_flags = GenesisFlags { hashes_per_tick: matches @@ -320,7 +325,7 @@ async fn main() { .unwrap_or_default() .to_string(), matches.value_of("registry_name").unwrap().to_string(), - deploy_method.to_string(), + deploy_method, ); if build_config.docker_build() { diff --git a/src/release.rs b/src/release.rs index 7fcadf7..70ed131 100644 --- a/src/release.rs +++ b/src/release.rs @@ -6,7 +6,7 @@ use { strum_macros::{EnumString, IntoStaticStr, VariantNames}, }; -#[derive(Debug, Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum DeployMethod { Local(String), ReleaseChannel(String), diff --git a/src/scripts/bootstrap-startup-scripts.sh b/src/scripts/bootstrap-startup-script.sh similarity index 100% rename from src/scripts/bootstrap-startup-scripts.sh rename to src/scripts/bootstrap-startup-script.sh From c9c94a34617191710565f455f71a008d351ea668 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 29 Mar 2024 23:02:02 +0000 Subject: [PATCH 14/49] push bootstrap to dockerhub registry. modify dockerconfig. create DockerImage struct --- PROGRESS.md | 4 +- src/docker.rs | 132 ++++++++++++++++++++++++++++++++++--------------- src/genesis.rs | 2 +- src/lib.rs | 1 + src/main.rs | 27 +++++++--- src/release.rs | 2 +- 6 files changed, 118 insertions(+), 50 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 5c5701f..84521ce 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -15,9 +15,9 @@ - [x] Create Genesis - [x] Generate faucet and bootstrap accounts - [x] Build genesis -- [ ] Docker Build +- [x] Docker Build - [x] Build Bootstrap Image - - [ ] Push Image to registry + - [x] Push Image to registry - [ ] Create & Deploy Secrets - [ ] Bootstrap - [ ] Validator (regular) diff --git a/src/docker.rs b/src/docker.rs index a1431f8..b4ce2c3 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,36 +1,64 @@ use { - crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD}, + crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD, ROCKET}, log::*, std::{ env, error::Error, + fmt::{self, Display, Formatter}, fs, path::{Path, PathBuf}, - process::{Command, Output, Stdio}, + process::{Command, Stdio}, }, }; -pub struct DockerConfig { - pub base_image: String, - pub image_name: String, - pub tag: String, - pub registry: String, - deploy_method: DeployMethod, +pub struct DockerImage { + registry: String, + validator_type: ValidatorType, + image_name: String, + tag: String, } -impl DockerConfig { +impl DockerImage { + // Constructor to create a new instance of DockerImage pub fn new( - base_image: String, + registry: String, + validator_type: ValidatorType, image_name: String, tag: String, - registry: String, - deploy_method: DeployMethod, ) -> Self { - DockerConfig { - base_image, + DockerImage { + registry, + validator_type, image_name, tag, - registry, + } + } + + pub fn validator_type(&self) -> ValidatorType { + self.validator_type + } +} + +// Put DockerImage in format for building, pushing, and pulling +impl Display for DockerImage { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!( + f, + "{}/{}-{}:{}", + self.registry, self.validator_type, self.image_name, self.tag + ) + } +} + +pub struct DockerConfig { + pub base_image: String, + deploy_method: DeployMethod, +} + +impl DockerConfig { + pub fn new(base_image: String, deploy_method: DeployMethod) -> Self { + DockerConfig { + base_image, deploy_method, } } @@ -38,8 +66,9 @@ impl DockerConfig { pub fn build_image( &self, solana_root_path: PathBuf, - validator_type: &ValidatorType, + docker_image: &DockerImage, ) -> Result<(), Box> { + let validator_type = docker_image.validator_type(); match validator_type { ValidatorType::Bootstrap => (), ValidatorType::Standard | ValidatorType::RPC | ValidatorType::Client => { @@ -50,34 +79,27 @@ impl DockerConfig { .into()); } } - let image_name = format!("{}-{}", validator_type, self.image_name); + let docker_path = solana_root_path.join(format!("{}/{}", "docker-build", validator_type)); - match self.create_base_image(solana_root_path, image_name, docker_path, validator_type) { - Ok(res) => { - if res.status.success() { - info!("Successfully created base Image"); - Ok(()) - } else { - error!("Failed to build base image"); - Err(String::from_utf8_lossy(&res.stderr).into()) - } - } - Err(err) => Err(err), - } + self.create_base_image( + solana_root_path, + &docker_image, + docker_path, + &validator_type, + )?; + + Ok(()) } fn create_base_image( &self, solana_root_path: PathBuf, - image_name: String, + docker_image: &DockerImage, docker_path: PathBuf, validator_type: &ValidatorType, - ) -> Result> { + ) -> Result<(), Box> { let dockerfile_path = self.create_dockerfile(validator_type, docker_path, None)?; - trace!("Tmp: {}", dockerfile_path.as_path().display()); - trace!("Exists: {}", dockerfile_path.as_path().exists()); - // We use std::process::Command here because Docker-rs is very slow building dockerfiles // when they are in large repos. Docker-rs doesn't seem to support the `--file` flag natively. // so we result to using std::process::Command @@ -91,10 +113,10 @@ impl DockerConfig { )); let command = format!( - "docker build -t {}/{}:{} -f {:?} {}", - self.registry, image_name, self.tag, dockerfile, context_path + "docker build -t {} -f {:?} {}", + docker_image, dockerfile, context_path ); - info!("command: {}", command); + let output = match Command::new("sh") .arg("-c") .arg(&command) @@ -106,11 +128,14 @@ impl DockerConfig { { Ok(res) => Ok(res), Err(err) => Err(Box::new(err) as Box), - }; + }?; + + if !output.status.success() { + return Err(output.status.to_string().into()); + } progress_bar.finish_and_clear(); - info!("{} image build complete", validator_type); - output + Ok(()) } fn copy_file_to_docker( @@ -191,4 +216,31 @@ WORKDIR /home/solana )?; Ok(docker_path) } + + pub fn push_image(docker_image: &DockerImage) -> Result<(), Box> { + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!( + "{ROCKET}Pushing {} image to registry...", + docker_image.validator_type() + )); + let command = format!("docker push '{}'", docker_image); + let output = match Command::new("sh") + .arg("-c") + .arg(&command) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .expect("Failed to execute command") + .wait_with_output() + { + Ok(res) => Ok(res), + Err(err) => Err(Box::new(err) as Box), + }?; + + if !output.status.success() { + return Err(output.status.to_string().into()); + } + progress_bar.finish_and_clear(); + Ok(()) + } } diff --git a/src/genesis.rs b/src/genesis.rs index b334aef..2a9669a 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -145,7 +145,7 @@ impl Genesis { } info!( - "generating {} {} accounts...", + "generating {} {} account(s)...", number_of_accounts, validator_type ); diff --git a/src/lib.rs b/src/lib.rs index 483a91c..30647c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,7 @@ pub mod release; static BUILD: Emoji = Emoji("👷 ", ""); static PACKAGE: Emoji = Emoji("📦 ", ""); +static ROCKET: Emoji = Emoji("🚀 ", ""); static SUN: Emoji = Emoji("🌞 ", ""); static TRUCK: Emoji = Emoji("🚚 ", ""); diff --git a/src/main.rs b/src/main.rs index e186803..4d90f0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use { std::fs, strum::VariantNames, validator_lab::{ - docker::DockerConfig, + docker::{DockerConfig, DockerImage}, genesis::{Genesis, GenesisFlags}, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, @@ -319,19 +319,34 @@ async fn main() { .value_of("base_image") .unwrap_or_default() .to_string(), + deploy_method, + ); + + let validator_type = ValidatorType::Bootstrap; + let docker_image = DockerImage::new( + matches.value_of("registry_name").unwrap().to_string(), + validator_type, matches.value_of("image_name").unwrap().to_string(), matches .value_of("image_tag") .unwrap_or_default() .to_string(), - matches.value_of("registry_name").unwrap().to_string(), - deploy_method, ); if build_config.docker_build() { - let image_type = ValidatorType::Bootstrap; - match docker.build_image(solana_root.get_root_path(), &image_type) { - Ok(_) => info!("{} image built successfully", image_type), + match docker.build_image(solana_root.get_root_path(), &docker_image) { + Ok(_) => info!("{} image built successfully", docker_image.validator_type()), + Err(err) => { + error!("Exiting........ {}", err); + return; + } + } + + match DockerConfig::push_image(&docker_image) { + Ok(_) => info!( + "{} image pushed successfully", + docker_image.validator_type() + ), Err(err) => { error!("Exiting........ {}", err); return; diff --git a/src/release.rs b/src/release.rs index 70ed131..e173401 100644 --- a/src/release.rs +++ b/src/release.rs @@ -176,7 +176,7 @@ impl BuildConfig { release_channel, "/solana-release-x86_64-unknown-linux-gnu.tar.bz2" ); - info!("download_url: {}", download_url); + debug!("download_url: {}", download_url); download_to_temp( download_url.as_str(), From 32c833c017f079edfb559e8fada24fa197e6f8c9 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 20:16:58 +0000 Subject: [PATCH 15/49] add create and deploy bootstrap secrets --- PROGRESS.md | 2 +- src/genesis.rs | 3 +-- src/k8s_helpers.rs | 30 ++++++++++++++++++++++++++++++ src/kubernetes.rs | 32 ++++++++++++++++++++++++++++++-- src/lib.rs | 1 + src/main.rs | 21 ++++++++++++++++++++- 6 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 src/k8s_helpers.rs diff --git a/PROGRESS.md b/PROGRESS.md index 84521ce..5b6a368 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -19,7 +19,7 @@ - [x] Build Bootstrap Image - [x] Push Image to registry - [ ] Create & Deploy Secrets - - [ ] Bootstrap + - [x] Bootstrap - [ ] Validator (regular) - [ ] RPC nodes - [ ] Client diff --git a/src/genesis.rs b/src/genesis.rs index 2a9669a..e692a0a 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -110,8 +110,7 @@ pub struct Genesis { } impl Genesis { - pub fn new(solana_root: PathBuf, flags: GenesisFlags) -> Self { - let config_dir = solana_root.join("config-k8s"); + pub fn new(config_dir: PathBuf, flags: GenesisFlags) -> Self { if config_dir.exists() { std::fs::remove_dir_all(&config_dir).unwrap(); } diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs new file mode 100644 index 0000000..52b64a1 --- /dev/null +++ b/src/k8s_helpers.rs @@ -0,0 +1,30 @@ +use { + k8s_openapi::{api::core::v1::Secret, ByteString}, + kube::api::ObjectMeta, + std::{collections::BTreeMap, error::Error, path::PathBuf}, +}; + +fn create_secret(name: &str, data: BTreeMap) -> Secret { + Secret { + metadata: ObjectMeta { + name: Some(name.to_string()), + ..Default::default() + }, + data: Some(data), + ..Default::default() + } +} + +pub fn create_secret_from_files( + secret_name: &str, + key_files: &[(PathBuf, &str)], //[pathbuf, key type] +) -> Result> { + let mut data = BTreeMap::new(); + for (file_path, key_type) in key_files { + let file_content = std::fs::read(file_path) + .map_err(|err| format!("Failed to read file '{:?}': {}", file_path, err))?; + data.insert(format!("{}.json", key_type), ByteString(file_content)); + } + + Ok(create_secret(secret_name, data)) +} diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 869e901..6995d17 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,9 +1,11 @@ use { - k8s_openapi::api::core::v1::Namespace, + crate::k8s_helpers, + k8s_openapi::api::core::v1::{Namespace, Secret}, kube::{ - api::{Api, ListParams}, + api::{Api, ListParams, PostParams}, Client, }, + std::{error::Error, path::PathBuf}, }; pub struct Kubernetes { @@ -30,4 +32,30 @@ impl Kubernetes { Ok(exists) } + + pub fn create_bootstrap_secret( + &self, + secret_name: &str, + config_dir: &PathBuf, + ) -> Result> { + let faucet_key_path = config_dir.join("faucet.json"); + let identity_key_path = config_dir.join("bootstrap-validator/identity.json"); + let vote_key_path = config_dir.join("bootstrap-validator/vote-account.json"); + let stake_key_path = config_dir.join("bootstrap-validator/stake-account.json"); + + let key_files = vec![ + (faucet_key_path, "faucet"), + (identity_key_path, "identity"), + (vote_key_path, "vote"), + (stake_key_path, "stake"), + ]; + + k8s_helpers::create_secret_from_files(secret_name, &key_files) + } + + pub async fn deploy_secret(&self, secret: &Secret) -> Result { + let secrets_api: Api = + Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + secrets_api.create(&PostParams::default(), secret).await + } } diff --git a/src/lib.rs b/src/lib.rs index 30647c3..990b063 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,6 +62,7 @@ impl std::fmt::Display for ValidatorType { pub mod docker; pub mod genesis; +pub mod k8s_helpers; pub mod kubernetes; pub mod release; diff --git a/src/main.rs b/src/main.rs index 4d90f0a..c891b3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -286,7 +286,8 @@ async fn main() { } } - let mut genesis = Genesis::new(solana_root.get_root_path(), genesis_flags); + let config_directory = solana_root.get_root_path().join("config-k8s"); + let mut genesis = Genesis::new(config_directory.clone(), genesis_flags); match genesis.generate_faucet() { Ok(_) => (), @@ -353,4 +354,22 @@ async fn main() { } } } + + let bootstrap_secret = match kub_controller + .create_bootstrap_secret("bootstrap-accounts-secret", &config_directory) + { + Ok(secret) => secret, + Err(err) => { + error!("Failed to create bootstrap secret! {}", err); + return; + } + }; + + match kub_controller.deploy_secret(&bootstrap_secret).await { + Ok(_) => info!("Deployed Bootstrap Secret"), + Err(err) => { + error!("{}", err); + return; + } + } } From 5495c3a28880facf46a3591732c6928a80783500 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 20:52:23 +0000 Subject: [PATCH 16/49] add bootstrap validator selector --- PROGRESS.md | 2 +- src/k8s_helpers.rs | 6 ++++++ src/kubernetes.rs | 6 +++++- src/main.rs | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 5b6a368..8db6e91 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -24,7 +24,7 @@ - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Selector - - [ ] Bootstrap + - [x] Bootstrap - [ ] Validator (regular) - [ ] RPC nodes - [ ] Client diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index 52b64a1..b6d80d4 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -28,3 +28,9 @@ pub fn create_secret_from_files( Ok(create_secret(secret_name, data)) } + +pub fn create_selector(key: &str, value: &str) -> BTreeMap { + let mut btree = BTreeMap::new(); + btree.insert(key.to_string(), value.to_string()); + btree +} diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 6995d17..1b68f7f 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -5,7 +5,7 @@ use { api::{Api, ListParams, PostParams}, Client, }, - std::{error::Error, path::PathBuf}, + std::{collections::BTreeMap, error::Error, path::PathBuf}, }; pub struct Kubernetes { @@ -58,4 +58,8 @@ impl Kubernetes { Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); secrets_api.create(&PostParams::default(), secret).await } + + pub fn create_selector(&self, key: &str, value: &str) -> BTreeMap { + k8s_helpers::create_selector(key, value) + } } diff --git a/src/main.rs b/src/main.rs index c891b3a..79fafba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use { clap::{command, Arg, ArgGroup}, log::*, + solana_sdk::{signature::keypair::read_keypair_file, signer::Signer}, std::fs, strum::VariantNames, validator_lab::{ @@ -372,4 +373,22 @@ async fn main() { return; } } + + // Bootstrap needs two labels. Because it is going to have two services. + // One via Load Balancer, one direct + let mut bootstrap_rs_labels = + kub_controller.create_selector("validator/lb", "load-balancer-selector"); + bootstrap_rs_labels.insert( + "validator/name".to_string(), + "bootstrap-validator-selector".to_string(), + ); + bootstrap_rs_labels.insert("validator/type".to_string(), "bootstrap".to_string()); + + let identity_path = config_directory.join("bootstrap-validator/identity.json"); + let bootstrap_keypair = + read_keypair_file(identity_path).expect("Failed to read bootstrap keypair file"); + bootstrap_rs_labels.insert( + "validator/identity".to_string(), + bootstrap_keypair.pubkey().to_string(), + ); } From 2612e4eef70b1f11850f95924e15c1f26b123c94 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 21:42:53 +0000 Subject: [PATCH 17/49] wip. adding replicaset but need validator config flags --- src/k8s_helpers.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++-- src/kubernetes.rs | 69 +++++++++++++++++++++++++++++++++++++-- src/main.rs | 13 ++++++++ 3 files changed, 158 insertions(+), 4 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index b6d80d4..5297779 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -1,9 +1,20 @@ use { - k8s_openapi::{api::core::v1::Secret, ByteString}, + crate::ValidatorType, + k8s_openapi::{ + api::{ + apps::v1::{ReplicaSet, ReplicaSetSpec}, + core::v1::{ + Affinity, Container, EnvVar, PodSecurityContext, + PodSpec, PodTemplateSpec, Probe, ResourceRequirements, Secret, + Volume, VolumeMount, + }, + }, + apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, + ByteString, + }, kube::api::ObjectMeta, std::{collections::BTreeMap, error::Error, path::PathBuf}, }; - fn create_secret(name: &str, data: BTreeMap) -> Secret { Secret { metadata: ObjectMeta { @@ -34,3 +45,68 @@ pub fn create_selector(key: &str, value: &str) -> BTreeMap { btree.insert(key.to_string(), value.to_string()); btree } + +#[allow(clippy::too_many_arguments)] +pub fn create_replica_set( + name: &ValidatorType, + namespace: &str, + label_selector: &BTreeMap, + container_name: &str, + image_name: &str, + environment_variables: Vec, + command: &[String], + volumes: Option>, + volume_mounts: Option>, + readiness_probe: Option, + pod_requests: BTreeMap, +) -> Result> { + let pod_spec = PodTemplateSpec { + metadata: Some(ObjectMeta { + labels: Some(label_selector.clone()), + ..Default::default() + }), + spec: Some(PodSpec { + containers: vec![Container { + name: container_name.to_string(), + image: Some(image_name.to_string()), + image_pull_policy: Some("Always".to_string()), + env: Some(environment_variables), + command: Some(command.to_owned()), + volume_mounts, + readiness_probe, + resources: Some(ResourceRequirements { + requests: Some(pod_requests), + ..Default::default() + }), + ..Default::default() + }], + volumes, + security_context: Some(PodSecurityContext { + run_as_user: Some(1000), + run_as_group: Some(1000), + ..Default::default() + }), + ..Default::default() + }), + }; + + let replicas_set_spec = ReplicaSetSpec { + replicas: Some(1), + selector: LabelSelector { + match_labels: Some(label_selector.clone()), + ..Default::default() + }, + template: Some(pod_spec), + ..Default::default() + }; + + Ok(ReplicaSet { + metadata: ObjectMeta { + name: Some(format!("{}-replicaset", name)), + namespace: Some(namespace.to_string()), + ..Default::default() + }, + spec: Some(replicas_set_spec), + ..Default::default() + }) +} diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 1b68f7f..b1c56d4 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,10 +1,17 @@ use { - crate::k8s_helpers, - k8s_openapi::api::core::v1::{Namespace, Secret}, + crate::{k8s_helpers, ValidatorType}, + k8s_openapi::api::{ + apps::v1::ReplicaSet, + core::v1::{ + EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, + Secret, SecretVolumeSource, Volume, VolumeMount, + }, + }, kube::{ api::{Api, ListParams, PostParams}, Client, }, + log::*, std::{collections::BTreeMap, error::Error, path::PathBuf}, }; @@ -59,6 +66,64 @@ impl Kubernetes { secrets_api.create(&PostParams::default(), secret).await } + pub fn create_bootstrap_validator_replica_set( + &mut self, + container_name: &str, + image_name: &str, + secret_name: Option, + label_selector: &BTreeMap, + ) -> Result> { + let mut env_vars = vec![EnvVar { + name: "MY_POD_IP".to_string(), + value_from: Some(EnvVarSource { + field_ref: Some(ObjectFieldSelector { + field_path: "status.podIP".to_string(), + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + }]; + + + let accounts_volume = Some(vec![Volume { + name: "bootstrap-accounts-volume".into(), + secret: Some(SecretVolumeSource { + secret_name, + ..Default::default() + }), + ..Default::default() + }]); + + let accounts_volume_mount = Some(vec![VolumeMount { + name: "bootstrap-accounts-volume".to_string(), + mount_path: "/home/solana/bootstrap-accounts".to_string(), + ..Default::default() + }]); + + let mut command = + vec!["/home/solana/k8s-cluster-scripts/bootstrap-startup-script.sh".to_string()]; + command.extend(self.generate_bootstrap_command_flags()); + + for c in command.iter() { + debug!("bootstrap command: {}", c); + } + + k8s_helpers::create_replica_set( + &ValidatorType::Bootstrap, + self.namespace.as_str(), + label_selector, + container_name, + image_name, + env_vars, + &command, + accounts_volume, + accounts_volume_mount, + None, + self.pod_requests.requests.clone(), + ) + } + pub fn create_selector(&self, key: &str, value: &str) -> BTreeMap { k8s_helpers::create_selector(key, value) } diff --git a/src/main.rs b/src/main.rs index 79fafba..20b29c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -391,4 +391,17 @@ async fn main() { "validator/identity".to_string(), bootstrap_keypair.pubkey().to_string(), ); + + let bootstrap_replica_set = match kub_controller.create_bootstrap_validator_replica_set( + bootstrap_container_name, + bootstrap_image_name, + bootstrap_secret.metadata.name.clone(), + &bootstrap_rs_labels, + ) { + Ok(replica_set) => replica_set, + Err(err) => { + error!("Error creating bootstrap validator replicas_set: {}", err); + return; + } + }; } From be36f9f61e46a1474270d777ba25bdbeca655989 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 22:05:13 +0000 Subject: [PATCH 18/49] add validator config --- Cargo.lock | 1 + Cargo.toml | 1 + src/kubernetes.rs | 10 ++-- src/lib.rs | 1 + src/main.rs | 111 ++++++++++++++++++++++++++++++++++------ src/validator_config.rs | 56 ++++++++++++++++++++ 6 files changed, 159 insertions(+), 21 deletions(-) create mode 100644 src/validator_config.rs diff --git a/Cargo.lock b/Cargo.lock index 3638624..6b8cc27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7136,6 +7136,7 @@ dependencies = [ "rustc_version", "rustls", "solana-core", + "solana-ledger", "solana-logger", "solana-sdk", "strum 0.26.2", diff --git a/Cargo.toml b/Cargo.toml index c98d591..7137d4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ rand = "0.8.5" reqwest = { version = "0.11.23", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } rustls = { version = "0.21.10", default-features = false, features = ["quic"] } solana-core = "1.18.8" +solana-ledger = "1.18.8" solana-logger = "1.18.8" solana-sdk = "1.18.8" strum = "0.26.2" diff --git a/src/kubernetes.rs b/src/kubernetes.rs index b1c56d4..0a3e0ec 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,5 +1,5 @@ use { - crate::{k8s_helpers, ValidatorType}, + crate::{k8s_helpers, ValidatorType, validator_config::ValidatorConfig}, k8s_openapi::api::{ apps::v1::ReplicaSet, core::v1::{ @@ -15,16 +15,18 @@ use { std::{collections::BTreeMap, error::Error, path::PathBuf}, }; -pub struct Kubernetes { +pub struct Kubernetes<'a> { k8s_client: Client, namespace: String, + validator_config: &'a mut ValidatorConfig, } -impl Kubernetes { - pub async fn new(namespace: &str) -> Kubernetes { +impl<'a> Kubernetes<'a> { + pub async fn new(namespace: &str, validator_config: &'a mut ValidatorConfig) -> Kubernetes<'a> { Self { k8s_client: Client::try_default().await.unwrap(), namespace: namespace.to_owned(), + validator_config, } } diff --git a/src/lib.rs b/src/lib.rs index 990b063..29ca993 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,7 @@ pub mod genesis; pub mod k8s_helpers; pub mod kubernetes; pub mod release; +pub mod validator_config; static BUILD: Emoji = Emoji("👷 ", ""); static PACKAGE: Emoji = Emoji("📦 ", ""); diff --git a/src/main.rs b/src/main.rs index 20b29c5..f7521e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,17 @@ use { clap::{command, Arg, ArgGroup}, log::*, + solana_ledger::blockstore_cleanup_service::{DEFAULT_MAX_LEDGER_SHREDS, DEFAULT_MIN_MAX_LEDGER_SHREDS}, solana_sdk::{signature::keypair::read_keypair_file, signer::Signer}, std::fs, strum::VariantNames, validator_lab::{ docker::{DockerConfig, DockerImage}, - genesis::{Genesis, GenesisFlags}, + genesis::{Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL}, kubernetes::Kubernetes, release::{BuildConfig, BuildType, DeployMethod}, SolanaRoot, ValidatorType, + validator_config::ValidatorConfig, }, }; @@ -153,6 +155,53 @@ fn parse_matches() -> clap::ArgMatches { .default_value("latest") .help("Docker image tag."), ) + // Bootstrap/Validator Config + .arg( + Arg::with_name("tpu_enable_udp") + .long("tpu-enable-udp") + .help("Validator config. Enable UDP for tpu transactions."), + ) + .arg( + Arg::with_name("tpu_disable_quic") + .long("tpu-disable-quic") + .help("Validator config. Disable quic for tpu packet forwarding"), + ) + .arg( + Arg::with_name("limit_ledger_size") + .long("limit-ledger-size") + .takes_value(true) + .help("Validator Config. The `--limit-ledger-size` parameter allows you to specify how many ledger + shreds your node retains on disk. If you do not + include this parameter, the validator will keep the entire ledger until it runs + out of disk space. The default value attempts to keep the ledger disk usage + under 500GB. More or less disk usage may be requested by adding an argument to + `--limit-ledger-size` if desired. Check `agave-validator --help` for the + default limit value used by `--limit-ledger-size`. More information about + selecting a custom limit value is at : https://github.com/solana-labs/solana/blob/583cec922b6107e0f85c7e14cb5e642bc7dfb340/core/src/ledger_cleanup_service.rs#L15-L26"), + ) + .arg( + Arg::with_name("skip_poh_verify") + .long("skip-poh-verify") + .help("Validator config. If set, validators will skip verifying + the ledger they already have saved to disk at + boot (results in a much faster boot)"), + ) + .arg( + Arg::with_name("no_snapshot_fetch") + .long("no-snapshot-fetch") + .help("Validator config. If set, disables booting validators from a snapshot"), + ) + .arg( + Arg::with_name("require_tower") + .long("require-tower") + .help("Validator config. Refuse to start if saved tower state is not found. + Off by default since validator won't restart if the pod restarts"), + ) + .arg( + Arg::with_name("full_rpc") + .long("full-rpc") + .help("Validator config. Support full RPC services on all nodes"), + ) .get_matches() } @@ -203,22 +252,6 @@ async fn main() { ); } - let kub_controller = Kubernetes::new(environment_config.namespace).await; - match kub_controller.namespace_exists().await { - Ok(true) => (), - Ok(false) => { - error!( - "Namespace: '{}' doesn't exist. Exiting...", - environment_config.namespace - ); - return; - } - Err(err) => { - error!("Error: {}", err); - return; - } - } - let build_config = BuildConfig::new( deploy_method.clone(), build_type, @@ -279,6 +312,50 @@ async fn main() { ), }; + let mut validator_config = ValidatorConfig { + tpu_enable_udp: matches.is_present("tpu_enable_udp"), + tpu_disable_quic: matches.is_present("tpu_disable_quic"), + shred_version: None, // set after genesis created + bank_hash: None, // set after genesis created + max_ledger_size: if matches.is_present("limit_ledger_size") { + let limit_ledger_size = match matches.value_of("limit_ledger_size") { + Some(_) => value_t_or_exit!(matches, "limit_ledger_size", u64), + None => DEFAULT_MAX_LEDGER_SHREDS, + }; + if limit_ledger_size < DEFAULT_MIN_MAX_LEDGER_SHREDS { + error!( + "The provided --limit-ledger-size value was too small, the minimum value is {DEFAULT_MIN_MAX_LEDGER_SHREDS}" + ); + return; + } + Some(limit_ledger_size) + } else { + None + }, + skip_poh_verify: matches.is_present("skip_poh_verify"), + no_snapshot_fetch: matches.is_present("no_snapshot_fetch"), + require_tower: matches.is_present("require_tower"), + enable_full_rpc: matches.is_present("enable_full_rpc"), + entrypoints: Vec::new(), + known_validators: None, + }; + + let kub_controller = Kubernetes::new(environment_config.namespace, &mut validator_config).await; + match kub_controller.namespace_exists().await { + Ok(true) => (), + Ok(false) => { + error!( + "Namespace: '{}' doesn't exist. Exiting...", + environment_config.namespace + ); + return; + } + Err(err) => { + error!("Error: {}", err); + return; + } + } + match build_config.prepare().await { Ok(_) => info!("Validator setup prepared successfully"), Err(err) => { diff --git a/src/validator_config.rs b/src/validator_config.rs new file mode 100644 index 0000000..b60776b --- /dev/null +++ b/src/validator_config.rs @@ -0,0 +1,56 @@ +use solana_sdk::{ + hash::Hash, pubkey::Pubkey, +}; + +pub struct ValidatorConfig { + pub tpu_enable_udp: bool, + pub tpu_disable_quic: bool, + pub shred_version: Option, + pub bank_hash: Option, + pub max_ledger_size: Option, + pub skip_poh_verify: bool, + pub no_snapshot_fetch: bool, + pub require_tower: bool, + pub enable_full_rpc: bool, + pub entrypoints: Vec, + pub known_validators: Option>, +} + +impl std::fmt::Display for ValidatorConfig { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let known_validators = match &self.known_validators { + Some(validators) => validators + .iter() + .map(|v| v.to_string()) + .collect::>() + .join(", "), + None => "None".to_string(), + }; + write!( + f, + "Runtime Config\n\ + tpu_enable_udp: {}\n\ + tpu_disable_quic: {}\n\ + shred_version: {:?}\n\ + bank_hash: {:?}\n\ + max_ledger_size: {:?}\n\ + skip_poh_verify: {}\n\ + no_snapshot_fetch: {}\n\ + require_tower: {}\n\ + enable_full_rpc: {}\n\ + entrypoints: {:?}\n\ + known_validators: {:?}", + self.tpu_enable_udp, + self.tpu_disable_quic, + self.shred_version, + self.bank_hash, + self.max_ledger_size, + self.skip_poh_verify, + self.no_snapshot_fetch, + self.require_tower, + self.enable_full_rpc, + self.entrypoints.join(", "), + known_validators, + ) + } +} \ No newline at end of file From 3801270ecdb1ad78c96fc38e1e11d26e0c2abd6d Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 22:13:52 +0000 Subject: [PATCH 19/49] add pod requests. need for scheduling --- src/k8s_helpers.rs | 3 ++- src/kubernetes.rs | 36 ++++++++++++++++++++++++++++++------ src/main.rs | 28 ++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index 5297779..d45196e 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -4,7 +4,7 @@ use { api::{ apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ - Affinity, Container, EnvVar, PodSecurityContext, + Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, ResourceRequirements, Secret, Volume, VolumeMount, }, @@ -15,6 +15,7 @@ use { kube::api::ObjectMeta, std::{collections::BTreeMap, error::Error, path::PathBuf}, }; + fn create_secret(name: &str, data: BTreeMap) -> Secret { Secret { metadata: ObjectMeta { diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 0a3e0ec..cb597a5 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,11 +1,14 @@ use { crate::{k8s_helpers, ValidatorType, validator_config::ValidatorConfig}, - k8s_openapi::api::{ - apps::v1::ReplicaSet, - core::v1::{ - EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, - Secret, SecretVolumeSource, Volume, VolumeMount, + k8s_openapi::{ + api::{ + apps::v1::ReplicaSet, + core::v1::{ + EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, + Secret, SecretVolumeSource, Volume, VolumeMount, + }, }, + apimachinery::pkg::api::resource::Quantity, }, kube::{ api::{Api, ListParams, PostParams}, @@ -15,18 +18,39 @@ use { std::{collections::BTreeMap, error::Error, path::PathBuf}, }; +#[derive(Debug, Clone)] +pub struct PodRequests { + requests: BTreeMap, +} + +impl PodRequests { + pub fn new(cpu_requests: String, memory_requests: String) -> PodRequests { + PodRequests { + requests: vec![ + ("cpu".to_string(), Quantity(cpu_requests)), + ("memory".to_string(), Quantity(memory_requests)), + ] + .into_iter() + .collect(), + } + } +} + pub struct Kubernetes<'a> { k8s_client: Client, namespace: String, validator_config: &'a mut ValidatorConfig, + pod_requests: PodRequests, } impl<'a> Kubernetes<'a> { - pub async fn new(namespace: &str, validator_config: &'a mut ValidatorConfig) -> Kubernetes<'a> { + pub async fn new(namespace: &str, validator_config: &'a mut ValidatorConfig, pod_requests: PodRequests +) -> Kubernetes<'a> { Self { k8s_client: Client::try_default().await.unwrap(), namespace: namespace.to_owned(), validator_config, + pod_requests, } } diff --git a/src/main.rs b/src/main.rs index f7521e8..18ebb39 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use { validator_lab::{ docker::{DockerConfig, DockerImage}, genesis::{Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL}, - kubernetes::Kubernetes, + kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, SolanaRoot, ValidatorType, validator_config::ValidatorConfig, @@ -202,6 +202,25 @@ fn parse_matches() -> clap::ArgMatches { .long("full-rpc") .help("Validator config. Support full RPC services on all nodes"), ) + // kubernetes config + .arg( + Arg::with_name("cpu_requests") + .long("cpu-requests") + .takes_value(true) + .default_value("20") // 20 cores + .help("Kubernetes pod config. Specify minimum CPUs required for deploying validator. + can use millicore notation as well. e.g. 500m (500 millicores) == 0.5 and is equivalent to half a core. + [default: 20]"), + ) + .arg( + Arg::with_name("memory_requests") + .long("memory-requests") + .takes_value(true) + .default_value("70Gi") // 70 Gigabytes + .help("Kubernetes pod config. Specify minimum memory required for deploying validator. + Can specify unit here (B, Ki, Mi, Gi, Ti) for bytes, kilobytes, etc (2^N notation) + e.g. 1Gi == 1024Mi == 1024Ki == 1,047,576B. [default: 70Gi]"), + ) .get_matches() } @@ -340,7 +359,12 @@ async fn main() { known_validators: None, }; - let kub_controller = Kubernetes::new(environment_config.namespace, &mut validator_config).await; + let pod_requests = PodRequests::new( + matches.value_of("cpu_requests").unwrap().to_string(), + matches.value_of("memory_requests").unwrap().to_string(), + ); + + let kub_controller = Kubernetes::new(environment_config.namespace, &mut validator_config, pod_requests).await; match kub_controller.namespace_exists().await { Ok(true) => (), Ok(false) => { From b5d9dfb791bab1ddac8d1381d12d43e8c2c1b756 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 1 Apr 2024 23:09:52 +0000 Subject: [PATCH 20/49] create bootstrap validator replicaset --- src/k8s_helpers.rs | 12 +++---- src/kubernetes.rs | 78 +++++++++++++++++++++++++++++++++-------- src/main.rs | 40 ++++++++++++--------- src/validator_config.rs | 15 ++------ 4 files changed, 93 insertions(+), 52 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index d45196e..b35298f 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -1,12 +1,11 @@ use { - crate::ValidatorType, + crate::{docker::DockerImage, ValidatorType}, k8s_openapi::{ api::{ apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ - Container, EnvVar, PodSecurityContext, - PodSpec, PodTemplateSpec, Probe, ResourceRequirements, Secret, - Volume, VolumeMount, + Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, + ResourceRequirements, Secret, Volume, VolumeMount, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -52,8 +51,7 @@ pub fn create_replica_set( name: &ValidatorType, namespace: &str, label_selector: &BTreeMap, - container_name: &str, - image_name: &str, + image_name: &DockerImage, environment_variables: Vec, command: &[String], volumes: Option>, @@ -68,7 +66,7 @@ pub fn create_replica_set( }), spec: Some(PodSpec { containers: vec![Container { - name: container_name.to_string(), + name: format!("{}-{}", image_name.validator_type(), "container"), image: Some(image_name.to_string()), image_pull_policy: Some("Always".to_string()), env: Some(environment_variables), diff --git a/src/kubernetes.rs b/src/kubernetes.rs index cb597a5..538584f 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,11 +1,11 @@ use { - crate::{k8s_helpers, ValidatorType, validator_config::ValidatorConfig}, + crate::{docker::DockerImage, k8s_helpers, validator_config::ValidatorConfig, ValidatorType}, k8s_openapi::{ api::{ apps::v1::ReplicaSet, core::v1::{ - EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, - Secret, SecretVolumeSource, Volume, VolumeMount, + EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretVolumeSource, + Volume, VolumeMount, }, }, apimachinery::pkg::api::resource::Quantity, @@ -15,6 +15,7 @@ use { Client, }, log::*, + solana_sdk::{pubkey::Pubkey, signature::keypair::read_keypair_file, signer::Signer}, std::{collections::BTreeMap, error::Error, path::PathBuf}, }; @@ -44,8 +45,11 @@ pub struct Kubernetes<'a> { } impl<'a> Kubernetes<'a> { - pub async fn new(namespace: &str, validator_config: &'a mut ValidatorConfig, pod_requests: PodRequests -) -> Kubernetes<'a> { + pub async fn new( + namespace: &str, + validator_config: &'a mut ValidatorConfig, + pod_requests: PodRequests, + ) -> Kubernetes<'a> { Self { k8s_client: Client::try_default().await.unwrap(), namespace: namespace.to_owned(), @@ -67,7 +71,7 @@ impl<'a> Kubernetes<'a> { } pub fn create_bootstrap_secret( - &self, + &mut self, secret_name: &str, config_dir: &PathBuf, ) -> Result> { @@ -76,6 +80,12 @@ impl<'a> Kubernetes<'a> { let vote_key_path = config_dir.join("bootstrap-validator/vote-account.json"); let stake_key_path = config_dir.join("bootstrap-validator/stake-account.json"); + let bootstrap_keypair = read_keypair_file(identity_key_path.clone()) + .expect("Failed to read bootstrap validator keypair file"); + + //TODO: need to fix and not read the json path twice + self.add_known_validator(bootstrap_keypair.pubkey()); + let key_files = vec![ (faucet_key_path, "faucet"), (identity_key_path, "identity"), @@ -86,6 +96,17 @@ impl<'a> Kubernetes<'a> { k8s_helpers::create_secret_from_files(secret_name, &key_files) } + fn add_known_validator(&mut self, pubkey: Pubkey) { + if let Some(ref mut known_validators) = self.validator_config.known_validators { + known_validators.push(pubkey); + } else { + let new_known_validators = vec![pubkey]; + self.validator_config.known_validators = Some(new_known_validators); + } + + info!("pubkey added to known validators: {:?}", pubkey); + } + pub async fn deploy_secret(&self, secret: &Secret) -> Result { let secrets_api: Api = Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); @@ -94,12 +115,11 @@ impl<'a> Kubernetes<'a> { pub fn create_bootstrap_validator_replica_set( &mut self, - container_name: &str, - image_name: &str, + image_name: &DockerImage, secret_name: Option, label_selector: &BTreeMap, ) -> Result> { - let mut env_vars = vec![EnvVar { + let env_vars = vec![EnvVar { name: "MY_POD_IP".to_string(), value_from: Some(EnvVarSource { field_ref: Some(ObjectFieldSelector { @@ -111,7 +131,6 @@ impl<'a> Kubernetes<'a> { ..Default::default() }]; - let accounts_volume = Some(vec![Volume { name: "bootstrap-accounts-volume".into(), secret: Some(SecretVolumeSource { @@ -131,15 +150,10 @@ impl<'a> Kubernetes<'a> { vec!["/home/solana/k8s-cluster-scripts/bootstrap-startup-script.sh".to_string()]; command.extend(self.generate_bootstrap_command_flags()); - for c in command.iter() { - debug!("bootstrap command: {}", c); - } - k8s_helpers::create_replica_set( &ValidatorType::Bootstrap, self.namespace.as_str(), label_selector, - container_name, image_name, env_vars, &command, @@ -150,6 +164,40 @@ impl<'a> Kubernetes<'a> { ) } + fn generate_command_flags(&self, flags: &mut Vec) { + if self.validator_config.tpu_enable_udp { + flags.push("--tpu-enable-udp".to_string()); + } + if self.validator_config.tpu_disable_quic { + flags.push("--tpu-disable-quic".to_string()); + } + if self.validator_config.skip_poh_verify { + flags.push("--skip-poh-verify".to_string()); + } + if self.validator_config.no_snapshot_fetch { + flags.push("--no-snapshot-fetch".to_string()); + } + if self.validator_config.require_tower { + flags.push("--require-tower".to_string()); + } + if self.validator_config.enable_full_rpc { + flags.push("--enable-rpc-transaction-history".to_string()); + flags.push("--enable-extended-tx-metadata-storage".to_string()); + } + + if let Some(limit_ledger_size) = self.validator_config.max_ledger_size { + flags.push("--limit-ledger-size".to_string()); + flags.push(limit_ledger_size.to_string()); + } + } + + fn generate_bootstrap_command_flags(&self) -> Vec { + let mut flags: Vec = Vec::new(); + self.generate_command_flags(&mut flags); + + flags + } + pub fn create_selector(&self, key: &str, value: &str) -> BTreeMap { k8s_helpers::create_selector(key, value) } diff --git a/src/main.rs b/src/main.rs index 18ebb39..efd24b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,19 @@ use { - clap::{command, Arg, ArgGroup}, + clap::{command, value_t_or_exit, Arg, ArgGroup}, log::*, - solana_ledger::blockstore_cleanup_service::{DEFAULT_MAX_LEDGER_SHREDS, DEFAULT_MIN_MAX_LEDGER_SHREDS}, + solana_ledger::blockstore_cleanup_service::{ + DEFAULT_MAX_LEDGER_SHREDS, DEFAULT_MIN_MAX_LEDGER_SHREDS, + }, solana_sdk::{signature::keypair::read_keypair_file, signer::Signer}, std::fs, strum::VariantNames, validator_lab::{ docker::{DockerConfig, DockerImage}, - genesis::{Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL}, + genesis::{Genesis, GenesisFlags}, kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, - SolanaRoot, ValidatorType, validator_config::ValidatorConfig, + SolanaRoot, ValidatorType, }, }; @@ -198,7 +200,7 @@ fn parse_matches() -> clap::ArgMatches { Off by default since validator won't restart if the pod restarts"), ) .arg( - Arg::with_name("full_rpc") + Arg::with_name("enable_full_rpc") .long("full-rpc") .help("Validator config. Support full RPC services on all nodes"), ) @@ -334,8 +336,6 @@ async fn main() { let mut validator_config = ValidatorConfig { tpu_enable_udp: matches.is_present("tpu_enable_udp"), tpu_disable_quic: matches.is_present("tpu_disable_quic"), - shred_version: None, // set after genesis created - bank_hash: None, // set after genesis created max_ledger_size: if matches.is_present("limit_ledger_size") { let limit_ledger_size = match matches.value_of("limit_ledger_size") { Some(_) => value_t_or_exit!(matches, "limit_ledger_size", u64), @@ -355,7 +355,6 @@ async fn main() { no_snapshot_fetch: matches.is_present("no_snapshot_fetch"), require_tower: matches.is_present("require_tower"), enable_full_rpc: matches.is_present("enable_full_rpc"), - entrypoints: Vec::new(), known_validators: None, }; @@ -364,7 +363,12 @@ async fn main() { matches.value_of("memory_requests").unwrap().to_string(), ); - let kub_controller = Kubernetes::new(environment_config.namespace, &mut validator_config, pod_requests).await; + let mut kub_controller = Kubernetes::new( + environment_config.namespace, + &mut validator_config, + pod_requests, + ) + .await; match kub_controller.namespace_exists().await { Ok(true) => (), Ok(false) => { @@ -426,7 +430,7 @@ async fn main() { ); let validator_type = ValidatorType::Bootstrap; - let docker_image = DockerImage::new( + let bootstrap_docker_image = DockerImage::new( matches.value_of("registry_name").unwrap().to_string(), validator_type, matches.value_of("image_name").unwrap().to_string(), @@ -437,18 +441,21 @@ async fn main() { ); if build_config.docker_build() { - match docker.build_image(solana_root.get_root_path(), &docker_image) { - Ok(_) => info!("{} image built successfully", docker_image.validator_type()), + match docker.build_image(solana_root.get_root_path(), &bootstrap_docker_image) { + Ok(_) => info!( + "{} image built successfully", + bootstrap_docker_image.validator_type() + ), Err(err) => { error!("Exiting........ {}", err); return; } } - match DockerConfig::push_image(&docker_image) { + match DockerConfig::push_image(&bootstrap_docker_image) { Ok(_) => info!( "{} image pushed successfully", - docker_image.validator_type() + bootstrap_docker_image.validator_type() ), Err(err) => { error!("Exiting........ {}", err); @@ -493,9 +500,8 @@ async fn main() { bootstrap_keypair.pubkey().to_string(), ); - let bootstrap_replica_set = match kub_controller.create_bootstrap_validator_replica_set( - bootstrap_container_name, - bootstrap_image_name, + let _bootstrap_replica_set = match kub_controller.create_bootstrap_validator_replica_set( + &bootstrap_docker_image, bootstrap_secret.metadata.name.clone(), &bootstrap_rs_labels, ) { diff --git a/src/validator_config.rs b/src/validator_config.rs index b60776b..35f4a4b 100644 --- a/src/validator_config.rs +++ b/src/validator_config.rs @@ -1,18 +1,13 @@ -use solana_sdk::{ - hash::Hash, pubkey::Pubkey, -}; +use solana_sdk::pubkey::Pubkey; pub struct ValidatorConfig { pub tpu_enable_udp: bool, pub tpu_disable_quic: bool, - pub shred_version: Option, - pub bank_hash: Option, pub max_ledger_size: Option, pub skip_poh_verify: bool, pub no_snapshot_fetch: bool, pub require_tower: bool, pub enable_full_rpc: bool, - pub entrypoints: Vec, pub known_validators: Option>, } @@ -31,26 +26,20 @@ impl std::fmt::Display for ValidatorConfig { "Runtime Config\n\ tpu_enable_udp: {}\n\ tpu_disable_quic: {}\n\ - shred_version: {:?}\n\ - bank_hash: {:?}\n\ max_ledger_size: {:?}\n\ skip_poh_verify: {}\n\ no_snapshot_fetch: {}\n\ require_tower: {}\n\ enable_full_rpc: {}\n\ - entrypoints: {:?}\n\ known_validators: {:?}", self.tpu_enable_udp, self.tpu_disable_quic, - self.shred_version, - self.bank_hash, self.max_ledger_size, self.skip_poh_verify, self.no_snapshot_fetch, self.require_tower, self.enable_full_rpc, - self.entrypoints.join(", "), known_validators, ) } -} \ No newline at end of file +} From 7b43c3ea2bcdd8211ef6976bfa3a13d3f3f0ce7d Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 00:36:57 +0000 Subject: [PATCH 21/49] refactor. add validator struct to clean up main --- src/k8s_helpers.rs | 6 ----- src/kubernetes.rs | 4 --- src/lib.rs | 1 + src/main.rs | 57 +++++++++++++++++++------------------------ src/validator.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 42 deletions(-) create mode 100644 src/validator.rs diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index b35298f..fdec8ff 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -40,12 +40,6 @@ pub fn create_secret_from_files( Ok(create_secret(secret_name, data)) } -pub fn create_selector(key: &str, value: &str) -> BTreeMap { - let mut btree = BTreeMap::new(); - btree.insert(key.to_string(), value.to_string()); - btree -} - #[allow(clippy::too_many_arguments)] pub fn create_replica_set( name: &ValidatorType, diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 538584f..aaf20ff 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -197,8 +197,4 @@ impl<'a> Kubernetes<'a> { flags } - - pub fn create_selector(&self, key: &str, value: &str) -> BTreeMap { - k8s_helpers::create_selector(key, value) - } } diff --git a/src/lib.rs b/src/lib.rs index 29ca993..079c8d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,7 @@ pub mod genesis; pub mod k8s_helpers; pub mod kubernetes; pub mod release; +pub mod validator; pub mod validator_config; static BUILD: Emoji = Emoji("👷 ", ""); diff --git a/src/main.rs b/src/main.rs index efd24b3..abf5b7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ use { genesis::{Genesis, GenesisFlags}, kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, + validator::Validator, validator_config::ValidatorConfig, SolanaRoot, ValidatorType, }, @@ -429,22 +430,21 @@ async fn main() { deploy_method, ); - let validator_type = ValidatorType::Bootstrap; - let bootstrap_docker_image = DockerImage::new( + let mut bootstrap_validator = Validator::new(DockerImage::new( matches.value_of("registry_name").unwrap().to_string(), - validator_type, + ValidatorType::Bootstrap, matches.value_of("image_name").unwrap().to_string(), matches .value_of("image_tag") .unwrap_or_default() .to_string(), - ); + )); if build_config.docker_build() { - match docker.build_image(solana_root.get_root_path(), &bootstrap_docker_image) { + match docker.build_image(solana_root.get_root_path(), bootstrap_validator.image()) { Ok(_) => info!( "{} image built successfully", - bootstrap_docker_image.validator_type() + bootstrap_validator.validator_type() ), Err(err) => { error!("Exiting........ {}", err); @@ -452,10 +452,10 @@ async fn main() { } } - match DockerConfig::push_image(&bootstrap_docker_image) { + match DockerConfig::push_image(bootstrap_validator.image()) { Ok(_) => info!( "{} image pushed successfully", - bootstrap_docker_image.validator_type() + bootstrap_validator.validator_type() ), Err(err) => { error!("Exiting........ {}", err); @@ -464,17 +464,18 @@ async fn main() { } } - let bootstrap_secret = match kub_controller - .create_bootstrap_secret("bootstrap-accounts-secret", &config_directory) - { - Ok(secret) => secret, + match kub_controller.create_bootstrap_secret("bootstrap-accounts-secret", &config_directory) { + Ok(secret) => bootstrap_validator.set_secret(secret), Err(err) => { error!("Failed to create bootstrap secret! {}", err); return; } }; - match kub_controller.deploy_secret(&bootstrap_secret).await { + match kub_controller + .deploy_secret(bootstrap_validator.secret()) + .await + { Ok(_) => info!("Deployed Bootstrap Secret"), Err(err) => { error!("{}", err); @@ -482,30 +483,22 @@ async fn main() { } } - // Bootstrap needs two labels. Because it is going to have two services. - // One via Load Balancer, one direct - let mut bootstrap_rs_labels = - kub_controller.create_selector("validator/lb", "load-balancer-selector"); - bootstrap_rs_labels.insert( - "validator/name".to_string(), - "bootstrap-validator-selector".to_string(), - ); - bootstrap_rs_labels.insert("validator/type".to_string(), "bootstrap".to_string()); - + // Create bootstrap labels let identity_path = config_directory.join("bootstrap-validator/identity.json"); let bootstrap_keypair = read_keypair_file(identity_path).expect("Failed to read bootstrap keypair file"); - bootstrap_rs_labels.insert( - "validator/identity".to_string(), - bootstrap_keypair.pubkey().to_string(), - ); + bootstrap_validator.add_label("validator/lb", "load-balancer-selector"); + bootstrap_validator.add_label("validator/name", "bootstrap-validator-selector"); + bootstrap_validator.add_label("validator/type", "bootstrap"); + bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string()); - let _bootstrap_replica_set = match kub_controller.create_bootstrap_validator_replica_set( - &bootstrap_docker_image, - bootstrap_secret.metadata.name.clone(), - &bootstrap_rs_labels, + // create bootstrap replica set + match kub_controller.create_bootstrap_validator_replica_set( + bootstrap_validator.image(), + bootstrap_validator.secret().metadata.name.clone(), + bootstrap_validator.labels(), ) { - Ok(replica_set) => replica_set, + Ok(replica_set) => bootstrap_validator.set_replica_set(replica_set), Err(err) => { error!("Error creating bootstrap validator replicas_set: {}", err); return; diff --git a/src/validator.rs b/src/validator.rs new file mode 100644 index 0000000..c643a10 --- /dev/null +++ b/src/validator.rs @@ -0,0 +1,61 @@ +use { + crate::{docker::DockerImage, ValidatorType}, + k8s_openapi::api::{apps::v1::ReplicaSet, core::v1::Secret}, + std::{collections::BTreeMap, string::String}, +}; + +pub struct Validator { + validator_type: ValidatorType, + image: DockerImage, + secret: Secret, + replica_set_labels: BTreeMap, + replica_set: ReplicaSet, +} + +impl Validator { + pub fn new(image: DockerImage) -> Self { + Self { + validator_type: image.validator_type(), + image, + secret: Secret::default(), + replica_set_labels: BTreeMap::new(), + replica_set: ReplicaSet::default(), + } + } + + pub fn image(&self) -> &DockerImage { + &self.image + } + + pub fn secret(&self) -> &Secret { + &self.secret + } + + pub fn validator_type(&self) -> &ValidatorType { + &self.validator_type + } + + pub fn add_label(&mut self, key: K, value: V) + where + K: Into, + V: Into, + { + self.replica_set_labels.insert(key.into(), value.into()); + } + + pub fn labels(&self) -> &BTreeMap { + &self.replica_set_labels + } + + pub fn set_secret(&mut self, secret: Secret) { + self.secret = secret; + } + + pub fn set_replica_set(&mut self, replica_set: ReplicaSet) { + self.replica_set = replica_set; + } + + pub fn replica_set(&self) -> &ReplicaSet { + &self.replica_set + } +} From 1a0f829fabb14cc580bcebe41769f27dfd0ffb90 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 01:08:46 +0000 Subject: [PATCH 22/49] deploy bootstrap validator --- PROGRESS.md | 2 +- src/docker.rs | 2 +- src/kubernetes.rs | 11 ++++++++ src/main.rs | 34 ++++++++++++++++++------- src/scripts/bootstrap-startup-script.sh | 0 src/scripts/common.sh | 0 src/validator.rs | 4 +++ 7 files changed, 42 insertions(+), 11 deletions(-) mode change 100644 => 100755 src/scripts/bootstrap-startup-script.sh mode change 100644 => 100755 src/scripts/common.sh diff --git a/PROGRESS.md b/PROGRESS.md index 8db6e91..45e078f 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -29,7 +29,7 @@ - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Replica Set - - [ ] Bootstrap + - [x] Bootstrap - [ ] Validator (regular) - [ ] RPC nodes - [ ] Client diff --git a/src/docker.rs b/src/docker.rs index b4ce2c3..2e0eb03 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -190,7 +190,7 @@ USER solana RUN mkdir -p /home/solana/k8s-cluster-scripts # TODO: this needs to be changed for non bootstrap, this should be ./src/scripts/-startup-scripts.sh -COPY {startup_script_directory}/bootstrap-startup-script.sh /home/solana/k8s-cluster-scripts +COPY {startup_script_directory} /home/solana/k8s-cluster-scripts RUN mkdir -p /home/solana/ledger COPY --chown=solana:solana ./config-k8s/bootstrap-validator /home/solana/ledger diff --git a/src/kubernetes.rs b/src/kubernetes.rs index aaf20ff..9ab045d 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -197,4 +197,15 @@ impl<'a> Kubernetes<'a> { flags } + + pub async fn deploy_replicas_set( + &self, + replica_set: &ReplicaSet, + ) -> Result { + let api: Api = + Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + let post_params = PostParams::default(); + // Apply the ReplicaSet + api.create(&post_params, replica_set).await + } } diff --git a/src/main.rs b/src/main.rs index abf5b7f..e1ce034 100644 --- a/src/main.rs +++ b/src/main.rs @@ -380,7 +380,7 @@ async fn main() { return; } Err(err) => { - error!("Error: {}", err); + error!("Error: {err}"); return; } } @@ -388,7 +388,7 @@ async fn main() { match build_config.prepare().await { Ok(_) => info!("Validator setup prepared successfully"), Err(err) => { - error!("Error: {}", err); + error!("Error: {err}"); return; } } @@ -399,7 +399,7 @@ async fn main() { match genesis.generate_faucet() { Ok(_) => (), Err(err) => { - error!("generate faucet error! {}", err); + error!("generate faucet error! {err}"); return; } } @@ -407,7 +407,7 @@ async fn main() { match genesis.generate_accounts(ValidatorType::Bootstrap, 1) { Ok(_) => (), Err(err) => { - error!("generate accounts error! {}", err); + error!("generate accounts error! {err}"); return; } } @@ -447,7 +447,7 @@ async fn main() { bootstrap_validator.validator_type() ), Err(err) => { - error!("Exiting........ {}", err); + error!("Exiting........ {err}"); return; } } @@ -458,7 +458,7 @@ async fn main() { bootstrap_validator.validator_type() ), Err(err) => { - error!("Exiting........ {}", err); + error!("Exiting........ {err}"); return; } } @@ -467,7 +467,7 @@ async fn main() { match kub_controller.create_bootstrap_secret("bootstrap-accounts-secret", &config_directory) { Ok(secret) => bootstrap_validator.set_secret(secret), Err(err) => { - error!("Failed to create bootstrap secret! {}", err); + error!("Failed to create bootstrap secret! {err}"); return; } }; @@ -478,7 +478,7 @@ async fn main() { { Ok(_) => info!("Deployed Bootstrap Secret"), Err(err) => { - error!("{}", err); + error!("{err}"); return; } } @@ -500,7 +500,23 @@ async fn main() { ) { Ok(replica_set) => bootstrap_validator.set_replica_set(replica_set), Err(err) => { - error!("Error creating bootstrap validator replicas_set: {}", err); + error!("Error creating bootstrap validator replicas_set: {err}"); + return; + } + }; + + match kub_controller + .deploy_replicas_set(bootstrap_validator.replica_set()) + .await + { + Ok(_) => { + info!( + "{} deployed successfully", + bootstrap_validator.replica_set_name() + ); + } + Err(err) => { + error!("Error! Failed to deploy bootstrap validator replicas_set. err: {err}"); return; } }; diff --git a/src/scripts/bootstrap-startup-script.sh b/src/scripts/bootstrap-startup-script.sh old mode 100644 new mode 100755 diff --git a/src/scripts/common.sh b/src/scripts/common.sh old mode 100644 new mode 100755 diff --git a/src/validator.rs b/src/validator.rs index c643a10..c05bb2c 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -58,4 +58,8 @@ impl Validator { pub fn replica_set(&self) -> &ReplicaSet { &self.replica_set } + + pub fn replica_set_name(&self) -> &String { + self.replica_set.metadata.name.as_ref().unwrap() + } } From 0b69996d119d3f3d7c15a4ae1a946d94ab962d7b Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 01:29:37 +0000 Subject: [PATCH 23/49] wip. added bootstrap service. need lb service --- src/k8s_helpers.rs | 50 ++++++++++++++++++++++++++++++++++++++++- src/kubernetes.rs | 19 +++++++++++++++- src/main.rs | 56 +++++++++++++++++++++++++++++++++++++++++----- src/validator.rs | 24 +++++++++++++++++--- 4 files changed, 138 insertions(+), 11 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index fdec8ff..9cd6a23 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -5,7 +5,8 @@ use { apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, - ResourceRequirements, Secret, Volume, VolumeMount, + ResourceRequirements, Secret, Volume, VolumeMount, Service, ServiceSpec, + ServicePort, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -103,3 +104,50 @@ pub fn create_replica_set( ..Default::default() }) } + +pub fn create_service( + service_name: &str, + namespace: &str, + label_selector: &BTreeMap, + is_load_balancer: bool, +) -> Service { + Service { + metadata: ObjectMeta { + name: Some(service_name.to_string()), + namespace: Some(namespace.to_string()), + ..Default::default() + }, + spec: Some(ServiceSpec { + selector: Some(label_selector.clone()), + type_: if is_load_balancer { + Some("LoadBalancer".to_string()) + } else { + None + }, + cluster_ip: if is_load_balancer { + None + } else { + Some("None".to_string()) + }, + ports: Some(vec![ + ServicePort { + port: 8899, // RPC Port + name: Some("rpc-port".to_string()), + ..Default::default() + }, + ServicePort { + port: 8001, //Gossip Port + name: Some("gossip-port".to_string()), + ..Default::default() + }, + ServicePort { + port: 9900, //Faucet Port + name: Some("faucet-port".to_string()), + ..Default::default() + }, + ]), + ..Default::default() + }), + ..Default::default() + } +} \ No newline at end of file diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 9ab045d..02429e7 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -5,7 +5,7 @@ use { apps::v1::ReplicaSet, core::v1::{ EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretVolumeSource, - Volume, VolumeMount, + Volume, VolumeMount, Service, }, }, apimachinery::pkg::api::resource::Quantity, @@ -208,4 +208,21 @@ impl<'a> Kubernetes<'a> { // Apply the ReplicaSet api.create(&post_params, replica_set).await } + + pub fn create_bootstrap_service( + &self, + service_name: &str, + label_selector: &BTreeMap, + ) -> Service { + k8s_helpers::create_service(service_name, self.namespace.as_str(), label_selector, false) + } + + pub async fn deploy_service(&self, service: &Service) -> Result { + let post_params = PostParams::default(); + // Create an API instance for Services in the specified namespace + let service_api: Api = Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + + // Create the Service object in the cluster + service_api.create(&post_params, service).await + } } diff --git a/src/main.rs b/src/main.rs index e1ce034..37e9acc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use { genesis::{Genesis, GenesisFlags}, kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, - validator::Validator, + validator::{Validator, LabelType}, validator_config::ValidatorConfig, SolanaRoot, ValidatorType, }, @@ -487,16 +487,16 @@ async fn main() { let identity_path = config_directory.join("bootstrap-validator/identity.json"); let bootstrap_keypair = read_keypair_file(identity_path).expect("Failed to read bootstrap keypair file"); - bootstrap_validator.add_label("validator/lb", "load-balancer-selector"); - bootstrap_validator.add_label("validator/name", "bootstrap-validator-selector"); - bootstrap_validator.add_label("validator/type", "bootstrap"); - bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string()); + bootstrap_validator.add_label("validator/lb", "load-balancer-selector", LabelType::replica_set); + bootstrap_validator.add_label("validator/name", "bootstrap-validator-selector", LabelType::replica_set); + bootstrap_validator.add_label("validator/type", "bootstrap", LabelType::replica_set); + bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string(), LabelType::replica_set); // create bootstrap replica set match kub_controller.create_bootstrap_validator_replica_set( bootstrap_validator.image(), bootstrap_validator.secret().metadata.name.clone(), - bootstrap_validator.labels(), + bootstrap_validator.replica_set_labels(), ) { Ok(replica_set) => bootstrap_validator.set_replica_set(replica_set), Err(err) => { @@ -520,4 +520,48 @@ async fn main() { return; } }; + + bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::replica_set); + + let bootstrap_service = kub_controller + .create_bootstrap_service("bootstrap-validator-service", bootstrap_validator.service_labels()); + match kub_controller.deploy_service(&bootstrap_service).await { + Ok(_) => info!("bootstrap validator service deployed successfully"), + Err(err) => error!( + "Error! Failed to deploy bootstrap validator service. err: {:?}", + err + ), + } + + //load balancer service. only create one and use for all deployments + let load_balancer_label = + kub_controller.create_selector("app.kubernetes.io/lb", "load-balancer-selector"); + //create load balancer + let load_balancer = kub_controller.create_validator_load_balancer( + "bootstrap-and-non-voting-lb-service", + &load_balancer_label, + ); + + //deploy load balancer + match kub_controller.deploy_service(&load_balancer).await { + Ok(_) => info!("load balancer service deployed successfully"), + Err(err) => error!( + "Error! Failed to deploy load balancer service. err: {:?}", + err + ), + } + + // wait for bootstrap replicaset to deploy + while { + match kub_controller + .check_replica_set_ready(bootstrap_replica_set_name.as_str()) + .await + { + Ok(ok) => !ok, // Continue the loop if replica set is not ready: Ok(false) + Err(_) => panic!("Error occurred while checking replica set readiness"), + } + } { + info!("replica set: {} not ready...", bootstrap_replica_set_name); + thread::sleep(Duration::from_secs(1)); + } } diff --git a/src/validator.rs b/src/validator.rs index c05bb2c..56a5bda 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -4,12 +4,18 @@ use { std::{collections::BTreeMap, string::String}, }; +pub enum LabelType { + replica_set, + service, +} + pub struct Validator { validator_type: ValidatorType, image: DockerImage, secret: Secret, replica_set_labels: BTreeMap, replica_set: ReplicaSet, + service_labels: BTreeMap, } impl Validator { @@ -20,6 +26,7 @@ impl Validator { secret: Secret::default(), replica_set_labels: BTreeMap::new(), replica_set: ReplicaSet::default(), + service_labels: BTreeMap::new(), } } @@ -35,18 +42,29 @@ impl Validator { &self.validator_type } - pub fn add_label(&mut self, key: K, value: V) + pub fn add_label(&mut self, key: K, value: V, label_type: LabelType) where K: Into, V: Into, { - self.replica_set_labels.insert(key.into(), value.into()); + match label_type { + LabelType::replica_set => { + self.replica_set_labels.insert(key.into(), value.into()); + } + LabelType::service => { + self.service_labels.insert(key.into(), value.into()); + } + } } - pub fn labels(&self) -> &BTreeMap { + pub fn replica_set_labels(&self) -> &BTreeMap { &self.replica_set_labels } + pub fn service_labels(&self) -> &BTreeMap { + &self.service_labels + } + pub fn set_secret(&mut self, secret: Secret) { self.secret = secret; } From f7bff73d773e6bf141daa62067ed22c8d0b8e605 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 17:15:26 +0000 Subject: [PATCH 24/49] deploy and wait for validator ready. need readme update --- src/k8s_helpers.rs | 6 ++++++ src/kubernetes.rs | 30 ++++++++++++++++++++++++++++++ src/main.rs | 17 +++++++++-------- src/validator.rs | 16 ++++++++++++---- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index 9cd6a23..593aa3b 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -150,4 +150,10 @@ pub fn create_service( }), ..Default::default() } +} + +pub fn create_selector(key: &str, value: &str) -> BTreeMap { + let mut btree = BTreeMap::new(); + btree.insert(key.to_string(), value.to_string()); + btree } \ No newline at end of file diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 02429e7..6fad610 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -225,4 +225,34 @@ impl<'a> Kubernetes<'a> { // Create the Service object in the cluster service_api.create(&post_params, service).await } + + pub fn create_validator_load_balancer( + &self, + service_name: &str, + label_selector: &BTreeMap, + ) -> Service { + k8s_helpers::create_service(service_name, self.namespace.as_str(), label_selector, true) + } + + pub fn create_selector(&self, key: &str, value: &str) -> BTreeMap { + k8s_helpers::create_selector(key, value) + } + + pub async fn check_replica_set_ready( + &self, + replica_set_name: &str, + ) -> Result { + let replica_sets: Api = Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + let replica_set = replica_sets.get(replica_set_name).await?; + + let desired_validators = replica_set.spec.as_ref().unwrap().replicas.unwrap_or(1); + let available_validators = replica_set + .status + .as_ref() + .unwrap() + .available_replicas + .unwrap_or(0); + + Ok(available_validators >= desired_validators) + } } diff --git a/src/main.rs b/src/main.rs index 37e9acc..37263ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use { validator_config::ValidatorConfig, SolanaRoot, ValidatorType, }, + std::{thread, time::Duration}, }; fn parse_matches() -> clap::ArgMatches { @@ -487,10 +488,10 @@ async fn main() { let identity_path = config_directory.join("bootstrap-validator/identity.json"); let bootstrap_keypair = read_keypair_file(identity_path).expect("Failed to read bootstrap keypair file"); - bootstrap_validator.add_label("validator/lb", "load-balancer-selector", LabelType::replica_set); - bootstrap_validator.add_label("validator/name", "bootstrap-validator-selector", LabelType::replica_set); - bootstrap_validator.add_label("validator/type", "bootstrap", LabelType::replica_set); - bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string(), LabelType::replica_set); + bootstrap_validator.add_label("load-balancer/name", "load-balancer-selector", LabelType::ValidatorReplicaSet); + bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::ValidatorReplicaSet); + bootstrap_validator.add_label("validator/type", "bootstrap", LabelType::ValidatorReplicaSet); + bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string(), LabelType::ValidatorReplicaSet); // create bootstrap replica set match kub_controller.create_bootstrap_validator_replica_set( @@ -521,7 +522,7 @@ async fn main() { } }; - bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::replica_set); + bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::ValidatorReplicaSet); let bootstrap_service = kub_controller .create_bootstrap_service("bootstrap-validator-service", bootstrap_validator.service_labels()); @@ -535,7 +536,7 @@ async fn main() { //load balancer service. only create one and use for all deployments let load_balancer_label = - kub_controller.create_selector("app.kubernetes.io/lb", "load-balancer-selector"); + kub_controller.create_selector("load-balancer/name", "load-balancer-selector"); //create load balancer let load_balancer = kub_controller.create_validator_load_balancer( "bootstrap-and-non-voting-lb-service", @@ -554,14 +555,14 @@ async fn main() { // wait for bootstrap replicaset to deploy while { match kub_controller - .check_replica_set_ready(bootstrap_replica_set_name.as_str()) + .check_replica_set_ready(bootstrap_validator.replica_set_name().as_str()) .await { Ok(ok) => !ok, // Continue the loop if replica set is not ready: Ok(false) Err(_) => panic!("Error occurred while checking replica set readiness"), } } { - info!("replica set: {} not ready...", bootstrap_replica_set_name); + info!("replica set: {} not ready...", bootstrap_validator.replica_set_name()); thread::sleep(Duration::from_secs(1)); } } diff --git a/src/validator.rs b/src/validator.rs index 56a5bda..4718d01 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -5,8 +5,9 @@ use { }; pub enum LabelType { - replica_set, - service, + ValidatorReplicaSet, + ValidatorService, + // ValidatorLoadBalancer, } pub struct Validator { @@ -16,10 +17,16 @@ pub struct Validator { replica_set_labels: BTreeMap, replica_set: ReplicaSet, service_labels: BTreeMap, + // load_balancer_labels: Option>, } impl Validator { pub fn new(image: DockerImage) -> Self { + // let load_balancer_labels = match image.validator_type() { + // ValidatorType::Bootstrap | ValidatorType::RPC => Some(BTreeMap::new()), + // ValidatorType::Client | ValidatorType::Standard => None, + // }; + Self { validator_type: image.validator_type(), image, @@ -27,6 +34,7 @@ impl Validator { replica_set_labels: BTreeMap::new(), replica_set: ReplicaSet::default(), service_labels: BTreeMap::new(), + // load_balancer_labels, } } @@ -48,10 +56,10 @@ impl Validator { V: Into, { match label_type { - LabelType::replica_set => { + LabelType::ValidatorReplicaSet => { self.replica_set_labels.insert(key.into(), value.into()); } - LabelType::service => { + LabelType::ValidatorService => { self.service_labels.insert(key.into(), value.into()); } } From c90172b88b91d4440b33d5dfa969e97eed16d6b7 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 20:48:12 +0000 Subject: [PATCH 25/49] update readme. update progress. fix selector bug --- PROGRESS.md | 8 ++++---- README.md | 31 +++++++++++++++++++++++++++++++ src/k8s_helpers.rs | 6 +++--- src/kubernetes.rs | 8 +++++--- src/main.rs | 46 +++++++++++++++++++++++++++++++++++----------- src/validator.rs | 8 -------- 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 45e078f..5503a9b 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -34,12 +34,12 @@ - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Services - - [ ] Bootstrap + - [x] Bootstrap - [ ] Validator (regular) - [ ] RPC nodes - [ ] Client -- [ ] Check Bootstrap is deployed and running -- [ ] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes) +- [x] Check Bootstrap is deployed and running +- [x] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes) - [ ] Add metrics - [ ] Bootstrap - [ ] Validator (regular) @@ -69,7 +69,7 @@ Above, we start with bootstrap, and then we do validators (regular), and then we - Use command line flags to set type of client, tx-count, etc - [ ] Add in kubernetes deployment flags - - [ ] CPU/Memory Requests + - [x] CPU/Memory Requests - [ ] Node Affinity -> Regions - [ ] Node Affinity -> Node Type (Equinix/Lumen) diff --git a/README.md b/README.md index 0d27e3f..1ec637f 100644 --- a/README.md +++ b/README.md @@ -58,4 +58,35 @@ cargo run --bin cluster -- --tag # e.g. v1 --base-image # e.g. ubuntu:20.04 --image-name # e.g. cluster-image +``` + +## Kubernetes Cheatsheet +Create namespace: +``` +kubectl create ns +``` + +Delete namespace: +``` +kubectl delete ns +``` + +Get running pods: +``` +kubectl get pods -n +``` + +Get pod logs: +``` +kubectl logs -n +``` + +Exec into pod: +``` +kubectl exec -it -n -- /bin/bash +``` + +Get information about pod: +``` +kubectl describe pod -n ``` \ No newline at end of file diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index 593aa3b..f508946 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -5,8 +5,8 @@ use { apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, - ResourceRequirements, Secret, Volume, VolumeMount, Service, ServiceSpec, - ServicePort, + ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, Volume, + VolumeMount, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -156,4 +156,4 @@ pub fn create_selector(key: &str, value: &str) -> BTreeMap { let mut btree = BTreeMap::new(); btree.insert(key.to_string(), value.to_string()); btree -} \ No newline at end of file +} diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 6fad610..0685b96 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -5,7 +5,7 @@ use { apps::v1::ReplicaSet, core::v1::{ EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretVolumeSource, - Volume, VolumeMount, Service, + Service, Volume, VolumeMount, }, }, apimachinery::pkg::api::resource::Quantity, @@ -220,7 +220,8 @@ impl<'a> Kubernetes<'a> { pub async fn deploy_service(&self, service: &Service) -> Result { let post_params = PostParams::default(); // Create an API instance for Services in the specified namespace - let service_api: Api = Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + let service_api: Api = + Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); // Create the Service object in the cluster service_api.create(&post_params, service).await @@ -242,7 +243,8 @@ impl<'a> Kubernetes<'a> { &self, replica_set_name: &str, ) -> Result { - let replica_sets: Api = Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); + let replica_sets: Api = + Api::namespaced(self.k8s_client.clone(), self.namespace.as_str()); let replica_set = replica_sets.get(replica_set_name).await?; let desired_validators = replica_set.spec.as_ref().unwrap().replicas.unwrap_or(1); diff --git a/src/main.rs b/src/main.rs index 37263ae..591babe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,18 +5,17 @@ use { DEFAULT_MAX_LEDGER_SHREDS, DEFAULT_MIN_MAX_LEDGER_SHREDS, }, solana_sdk::{signature::keypair::read_keypair_file, signer::Signer}, - std::fs, + std::{fs, thread, time::Duration}, strum::VariantNames, validator_lab::{ docker::{DockerConfig, DockerImage}, genesis::{Genesis, GenesisFlags}, kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, - validator::{Validator, LabelType}, + validator::{LabelType, Validator}, validator_config::ValidatorConfig, SolanaRoot, ValidatorType, }, - std::{thread, time::Duration}, }; fn parse_matches() -> clap::ArgMatches { @@ -488,10 +487,26 @@ async fn main() { let identity_path = config_directory.join("bootstrap-validator/identity.json"); let bootstrap_keypair = read_keypair_file(identity_path).expect("Failed to read bootstrap keypair file"); - bootstrap_validator.add_label("load-balancer/name", "load-balancer-selector", LabelType::ValidatorReplicaSet); - bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::ValidatorReplicaSet); - bootstrap_validator.add_label("validator/type", "bootstrap", LabelType::ValidatorReplicaSet); - bootstrap_validator.add_label("validator/identity", bootstrap_keypair.pubkey().to_string(), LabelType::ValidatorReplicaSet); + bootstrap_validator.add_label( + "load-balancer/name", + "load-balancer-selector", + LabelType::ValidatorReplicaSet, + ); + bootstrap_validator.add_label( + "service/name", + "bootstrap-validator-selector", + LabelType::ValidatorReplicaSet, + ); + bootstrap_validator.add_label( + "validator/type", + "bootstrap", + LabelType::ValidatorReplicaSet, + ); + bootstrap_validator.add_label( + "validator/identity", + bootstrap_keypair.pubkey().to_string(), + LabelType::ValidatorReplicaSet, + ); // create bootstrap replica set match kub_controller.create_bootstrap_validator_replica_set( @@ -522,10 +537,16 @@ async fn main() { } }; - bootstrap_validator.add_label("service/name", "bootstrap-validator-selector", LabelType::ValidatorReplicaSet); + bootstrap_validator.add_label( + "service/name", + "bootstrap-validator-selector", + LabelType::ValidatorService, + ); - let bootstrap_service = kub_controller - .create_bootstrap_service("bootstrap-validator-service", bootstrap_validator.service_labels()); + let bootstrap_service = kub_controller.create_bootstrap_service( + "bootstrap-validator-service", + bootstrap_validator.service_labels(), + ); match kub_controller.deploy_service(&bootstrap_service).await { Ok(_) => info!("bootstrap validator service deployed successfully"), Err(err) => error!( @@ -562,7 +583,10 @@ async fn main() { Err(_) => panic!("Error occurred while checking replica set readiness"), } } { - info!("replica set: {} not ready...", bootstrap_validator.replica_set_name()); + info!( + "replica set: {} not ready...", + bootstrap_validator.replica_set_name() + ); thread::sleep(Duration::from_secs(1)); } } diff --git a/src/validator.rs b/src/validator.rs index 4718d01..41d4164 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -7,7 +7,6 @@ use { pub enum LabelType { ValidatorReplicaSet, ValidatorService, - // ValidatorLoadBalancer, } pub struct Validator { @@ -17,16 +16,10 @@ pub struct Validator { replica_set_labels: BTreeMap, replica_set: ReplicaSet, service_labels: BTreeMap, - // load_balancer_labels: Option>, } impl Validator { pub fn new(image: DockerImage) -> Self { - // let load_balancer_labels = match image.validator_type() { - // ValidatorType::Bootstrap | ValidatorType::RPC => Some(BTreeMap::new()), - // ValidatorType::Client | ValidatorType::Standard => None, - // }; - Self { validator_type: image.validator_type(), image, @@ -34,7 +27,6 @@ impl Validator { replica_set_labels: BTreeMap::new(), replica_set: ReplicaSet::default(), service_labels: BTreeMap::new(), - // load_balancer_labels, } } From 8804371e51931cce5375ae1df7411ab3cf02647e Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 22:07:28 +0000 Subject: [PATCH 26/49] add metrics --- PROGRESS.md | 2 +- README.md | 17 ++++++++ scripts/init-metrics.sh | 87 +++++++++++++++++++++++++++++++++++++++++ src/k8s_helpers.rs | 2 +- src/kubernetes.rs | 49 +++++++++++++++++++++-- src/lib.rs | 33 ++++++++++++++++ src/main.rs | 76 ++++++++++++++++++++++++++++++----- 7 files changed, 250 insertions(+), 16 deletions(-) create mode 100755 scripts/init-metrics.sh diff --git a/PROGRESS.md b/PROGRESS.md index 5503a9b..bad7044 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -41,7 +41,7 @@ - [x] Check Bootstrap is deployed and running - [x] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes) - [ ] Add metrics - - [ ] Bootstrap + - [x] Bootstrap - [ ] Validator (regular) - [ ] RPC nodes - [ ] Client diff --git a/README.md b/README.md index 1ec637f..ac0df19 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,23 @@ cargo run --bin cluster -- --image-name # e.g. cluster-image ``` +## Metrics +1) Setup metrics database: +``` +cd scripts/ +./init-metrics -c +# enter password when promted +``` +2) add the following to your `cluster` command from above +``` +--metrics-host https://internal-metrics.solana.com # need the `https://` here +--metrics-port 8086 +--metrics-db # from (1) +--metrics-username # from (1) +--metrics-password # from (1) +``` + + ## Kubernetes Cheatsheet Create namespace: ``` diff --git a/scripts/init-metrics.sh b/scripts/init-metrics.sh new file mode 100755 index 0000000..89eae4f --- /dev/null +++ b/scripts/init-metrics.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -e + +here=$(dirname "$0") +# shellcheck source=net/common.sh +source "$here"/common.sh + +usage() { + exitcode=0 + if [[ -n "$1" ]]; then + exitcode=1 + echo "Error: $*" + fi + cat <) -> Secret { +pub fn create_secret(name: &str, data: BTreeMap) -> Secret { Secret { metadata: ObjectMeta { name: Some(name.to_string()), diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 0685b96..e06f4a8 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,14 +1,17 @@ use { - crate::{docker::DockerImage, k8s_helpers, validator_config::ValidatorConfig, ValidatorType}, + crate::{ + docker::DockerImage, k8s_helpers, validator_config::ValidatorConfig, Metrics, ValidatorType, + }, k8s_openapi::{ api::{ apps::v1::ReplicaSet, core::v1::{ - EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretVolumeSource, - Service, Volume, VolumeMount, + EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretKeySelector, + SecretVolumeSource, Service, Volume, VolumeMount, }, }, apimachinery::pkg::api::resource::Quantity, + ByteString, }, kube::{ api::{Api, ListParams, PostParams}, @@ -42,6 +45,7 @@ pub struct Kubernetes<'a> { namespace: String, validator_config: &'a mut ValidatorConfig, pod_requests: PodRequests, + pub metrics: Option, } impl<'a> Kubernetes<'a> { @@ -49,12 +53,14 @@ impl<'a> Kubernetes<'a> { namespace: &str, validator_config: &'a mut ValidatorConfig, pod_requests: PodRequests, + metrics: Option, ) -> Kubernetes<'a> { Self { k8s_client: Client::try_default().await.unwrap(), namespace: namespace.to_owned(), validator_config, pod_requests, + metrics, } } @@ -119,7 +125,7 @@ impl<'a> Kubernetes<'a> { secret_name: Option, label_selector: &BTreeMap, ) -> Result> { - let env_vars = vec![EnvVar { + let mut env_vars = vec![EnvVar { name: "MY_POD_IP".to_string(), value_from: Some(EnvVarSource { field_ref: Some(ObjectFieldSelector { @@ -131,6 +137,10 @@ impl<'a> Kubernetes<'a> { ..Default::default() }]; + if self.metrics.is_some() { + env_vars.push(self.get_metrics_env_var_secret()) + } + let accounts_volume = Some(vec![Volume { name: "bootstrap-accounts-volume".into(), secret: Some(SecretVolumeSource { @@ -257,4 +267,35 @@ impl<'a> Kubernetes<'a> { Ok(available_validators >= desired_validators) } + + pub fn create_metrics_secret(&self) -> Result> { + let mut data = BTreeMap::new(); + if let Some(metrics) = &self.metrics { + data.insert( + "SOLANA_METRICS_CONFIG".to_string(), + ByteString(metrics.to_env_string().into_bytes()), + ); + } else { + return Err( + format!("Called create_metrics_secret() but metrics were not provided.").into(), + ); + } + + Ok(k8s_helpers::create_secret("solana-metrics-secret", data)) + } + + pub fn get_metrics_env_var_secret(&self) -> EnvVar { + EnvVar { + name: "SOLANA_METRICS_CONFIG".to_string(), + value_from: Some(EnvVarSource { + secret_key_ref: Some(SecretKeySelector { + name: Some("solana-metrics-secret".to_string()), + key: "SOLANA_METRICS_CONFIG".to_string(), + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + } + } } diff --git a/src/lib.rs b/src/lib.rs index 079c8d4..80d7818 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,6 +60,39 @@ impl std::fmt::Display for ValidatorType { } } +#[derive(Clone, Debug, Default)] +pub struct Metrics { + pub host: String, + pub port: String, + pub database: String, + pub username: String, + password: String, +} + +impl Metrics { + pub fn new( + host: String, + port: String, + database: String, + username: String, + password: String, + ) -> Self { + Metrics { + host, + port, + database, + username, + password, + } + } + pub fn to_env_string(&self) -> String { + format!( + "host={}:{},db={},u={},p={}", + self.host, self.port, self.database, self.username, self.password + ) + } +} + pub mod docker; pub mod genesis; pub mod k8s_helpers; diff --git a/src/main.rs b/src/main.rs index 591babe..2bf14e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use { release::{BuildConfig, BuildType, DeployMethod}, validator::{LabelType, Validator}, validator_config::ValidatorConfig, - SolanaRoot, ValidatorType, + Metrics, SolanaRoot, ValidatorType, }, }; @@ -224,6 +224,38 @@ fn parse_matches() -> clap::ArgMatches { Can specify unit here (B, Ki, Mi, Gi, Ti) for bytes, kilobytes, etc (2^N notation) e.g. 1Gi == 1024Mi == 1024Ki == 1,047,576B. [default: 70Gi]"), ) + //Metrics Config + .arg( + Arg::with_name("metrics_host") + .long("metrics-host") + .takes_value(true) + .requires_all(&["metrics_port", "metrics_db", "metrics_username", "metrics_password"]) + .help("Metrics Config. Optional: specify metrics host. e.g. https://internal-metrics.solana.com"), + ) + .arg( + Arg::with_name("metrics_port") + .long("metrics-port") + .takes_value(true) + .help("Metrics Config. Optional: specify metrics port. e.g. 8086"), + ) + .arg( + Arg::with_name("metrics_db") + .long("metrics-db") + .takes_value(true) + .help("Metrics Config. Optional: specify metrics database. e.g. k8s-cluster-"), + ) + .arg( + Arg::with_name("metrics_username") + .long("metrics-username") + .takes_value(true) + .help("Metrics Config. Optional: specify metrics username"), + ) + .arg( + Arg::with_name("metrics_password") + .long("metrics-password") + .takes_value(true) + .help("Metrics Config. Optional: Specify metrics password"), + ) .get_matches() } @@ -364,12 +396,24 @@ async fn main() { matches.value_of("memory_requests").unwrap().to_string(), ); + let metrics = matches.value_of("metrics_host").map(|host| { + Metrics::new( + host.to_string(), + matches.value_of("metrics_port").unwrap().to_string(), + matches.value_of("metrics_db").unwrap().to_string(), + matches.value_of("metrics_username").unwrap().to_string(), + matches.value_of("metrics_password").unwrap().to_string(), + ) + }); + let mut kub_controller = Kubernetes::new( environment_config.namespace, &mut validator_config, pod_requests, + metrics, ) .await; + match kub_controller.namespace_exists().await { Ok(true) => (), Ok(false) => { @@ -430,6 +474,24 @@ async fn main() { deploy_method, ); + // metrics secret create once and use by all pods + if kub_controller.metrics.is_some() { + let metrics_secret = match kub_controller.create_metrics_secret() { + Ok(secret) => secret, + Err(err) => { + error!("Failed to create metrics secret! {err}"); + return; + } + }; + match kub_controller.deploy_secret(&metrics_secret).await { + Ok(_) => (), + Err(err) => { + error!("{err}"); + return; + } + } + }; + let mut bootstrap_validator = Validator::new(DockerImage::new( matches.value_of("registry_name").unwrap().to_string(), ValidatorType::Bootstrap, @@ -549,10 +611,7 @@ async fn main() { ); match kub_controller.deploy_service(&bootstrap_service).await { Ok(_) => info!("bootstrap validator service deployed successfully"), - Err(err) => error!( - "Error! Failed to deploy bootstrap validator service. err: {:?}", - err - ), + Err(err) => error!("Error! Failed to deploy bootstrap validator service. err: {err}"), } //load balancer service. only create one and use for all deployments @@ -567,10 +626,7 @@ async fn main() { //deploy load balancer match kub_controller.deploy_service(&load_balancer).await { Ok(_) => info!("load balancer service deployed successfully"), - Err(err) => error!( - "Error! Failed to deploy load balancer service. err: {:?}", - err - ), + Err(err) => error!("Error! Failed to deploy load balancer service. err: {err}"), } // wait for bootstrap replicaset to deploy @@ -580,7 +636,7 @@ async fn main() { .await { Ok(ok) => !ok, // Continue the loop if replica set is not ready: Ok(false) - Err(_) => panic!("Error occurred while checking replica set readiness"), + Err(err) => panic!("Error occurred while checking replica set readiness: {err}"), } } { info!( From 56a6d1775bd19740922eae4c8f83eeadb8d3ec19 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 23:33:26 +0000 Subject: [PATCH 27/49] create N validator accounts --- PROGRESS.md | 2 +- README.md | 3 +++ src/main.rs | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/PROGRESS.md b/PROGRESS.md index bad7044..3f5f63f 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -46,7 +46,7 @@ - [ ] RPC nodes - [ ] Client - [ ] Create accounts - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC - [ ] Client - [ ] Add feature flags to configure: diff --git a/README.md b/README.md index ac0df19..59db1db 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ kubectl create ns ``` cargo run --bin cluster -- -n + --num_validators --local-path ``` @@ -33,6 +34,7 @@ cargo run --bin cluster -- ``` cargo run --bin cluster -- -n + --num_validators --release-channel # note: MUST include the "v" ``` @@ -41,6 +43,7 @@ Example: ``` cargo run --bin cluster -- -n + --num_validators --deploy-method local --local-path /home/sol/solana # genesis config. Optional: Many of these have defaults diff --git a/src/main.rs b/src/main.rs index 2bf14e9..8592832 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,17 @@ fn parse_matches() -> clap::ArgMatches { .default_value("default") .help("namespace to deploy test cluster"), ) + .arg( + Arg::with_name("number_of_validators") + .long("num-validators") + .takes_value(true) + .default_value("1") + .help("Number of validator replicas to deploy") + .validator(|s| match s.parse::() { + Ok(n) if n > 0 => Ok(()), + _ => Err(String::from("number_of_validators should be >= 0")), + }), + ) .arg( Arg::new("local_path") .long("local-path") @@ -275,6 +286,8 @@ async fn main() { namespace: matches.value_of("cluster_namespace").unwrap_or_default(), }; + let num_validators = value_t_or_exit!(matches, "number_of_validators", usize); + let deploy_method = if let Some(local_path) = matches.value_of("local_path") { DeployMethod::Local(local_path.to_owned()) } else if let Some(release_channel) = matches.value_of("release_channel") { @@ -465,6 +478,14 @@ async fn main() { } } + match genesis.generate_accounts(ValidatorType::Standard, num_validators) { + Ok(_) => (), + Err(err) => { + error!("generate accounts error! {err}"); + return; + } + } + //unwraps are safe here. since their requirement is enforced by argmatches let docker = DockerConfig::new( matches From a720a5c6606b10a05208c961ddfbe2eca0adce9f Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 2 Apr 2024 23:59:15 +0000 Subject: [PATCH 28/49] create and deploy validator secrets --- PROGRESS.md | 2 +- src/kubernetes.rs | 23 +++++++++++++++++++++++ src/main.rs | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/PROGRESS.md b/PROGRESS.md index 3f5f63f..9754115 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -20,7 +20,7 @@ - [x] Push Image to registry - [ ] Create & Deploy Secrets - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Selector diff --git a/src/kubernetes.rs b/src/kubernetes.rs index e06f4a8..06703f9 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -102,6 +102,29 @@ impl<'a> Kubernetes<'a> { k8s_helpers::create_secret_from_files(secret_name, &key_files) } + pub fn create_validator_secret( + &self, + validator_index: usize, + config_dir: &PathBuf, + ) -> Result> { + let secret_name = format!("validator-accounts-secret-{}", validator_index); + + let accounts = ["identity", "vote", "stake"]; + let key_files: Vec<(PathBuf, &str)> = accounts + .iter() + .map(|&account| { + let file_name = if account == "identity" { + format!("validator-{account}-{validator_index}.json") + } else { + format!("validator-{account}-account-{validator_index}.json") + }; + (config_dir.join(file_name), account) + }) + .collect(); + + k8s_helpers::create_secret_from_files(&secret_name, &key_files) + } + fn add_known_validator(&mut self, pubkey: Pubkey) { if let Some(ref mut known_validators) = self.validator_config.known_validators { known_validators.push(pubkey); diff --git a/src/main.rs b/src/main.rs index 8592832..648a392 100644 --- a/src/main.rs +++ b/src/main.rs @@ -666,4 +666,23 @@ async fn main() { ); thread::sleep(Duration::from_secs(1)); } + + // Create and deploy validators secrets + for validator_index in 0..num_validators { + let validator_secret = + match kub_controller.create_validator_secret(validator_index, &config_directory) { + Ok(secret) => secret, + Err(err) => { + error!("Failed to create validator secret! {err}"); + return; + } + }; + match kub_controller.deploy_secret(&validator_secret).await { + Ok(_) => (), + Err(err) => { + error!("{err}"); + return; + } + } + } } From c89a6c8605265d2d8d1b49b2dc19a8921f98e5b3 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 3 Apr 2024 00:16:24 +0000 Subject: [PATCH 29/49] create validator selectors --- PROGRESS.md | 2 +- src/main.rs | 51 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 9754115..7f30bca 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -25,7 +25,7 @@ - [ ] Client - [ ] Create & Deploy Selector - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Replica Set diff --git a/src/main.rs b/src/main.rs index 648a392..b36fe7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -667,22 +667,53 @@ async fn main() { thread::sleep(Duration::from_secs(1)); } - // Create and deploy validators secrets + let mut validator = Validator::new(DockerImage::new( + matches.value_of("registry_name").unwrap().to_string(), + ValidatorType::Standard, + matches.value_of("image_name").unwrap().to_string(), + matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(), + )); + + // Create and deploy validators secrets/selectors for validator_index in 0..num_validators { - let validator_secret = - match kub_controller.create_validator_secret(validator_index, &config_directory) { - Ok(secret) => secret, - Err(err) => { - error!("Failed to create validator secret! {err}"); - return; - } - }; - match kub_controller.deploy_secret(&validator_secret).await { + match kub_controller.create_validator_secret(validator_index, &config_directory) { + Ok(secret) => validator.set_secret(secret), + Err(err) => { + error!("Failed to create validator secret! {err}"); + return; + } + }; + + match kub_controller.deploy_secret(&validator.secret()).await { Ok(_) => (), Err(err) => { error!("{err}"); return; } } + + let identity_path = + config_directory.join(format!("validator-identity-{validator_index}.json")); + let validator_keypair = + read_keypair_file(identity_path).expect("Failed to read validator keypair file"); + + validator.add_label( + "validator/name", + &format!("validator-{}", validator_index), + LabelType::ValidatorReplicaSet, + ); + validator.add_label( + "validator/type", + validator.validator_type().to_string(), + LabelType::ValidatorReplicaSet, + ); + validator.add_label( + "validator/identity", + validator_keypair.pubkey().to_string(), + LabelType::ValidatorReplicaSet, + ); } } From 530505c3940835da5ea2158cab921117cb2c65ea Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 3 Apr 2024 21:17:33 +0000 Subject: [PATCH 30/49] add in build and push validator docker images --- README.md | 2 +- src/docker.rs | 19 +- src/main.rs | 58 ++-- src/scripts/validator-startup-script.sh | 398 ++++++++++++++++++++++++ 4 files changed, 431 insertions(+), 46 deletions(-) create mode 100755 src/scripts/validator-startup-script.sh diff --git a/README.md b/README.md index 59db1db..3646762 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ cargo run --bin cluster -- --target-lamports-per-signature --slots-per-epoch # docker config - --registry # e.g. gregcusack + --registry # e.g. gregregistry --docker-build --tag # e.g. v1 --base-image # e.g. ubuntu:20.04 diff --git a/src/docker.rs b/src/docker.rs index 2e0eb03..67de22f 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -70,17 +70,16 @@ impl DockerConfig { ) -> Result<(), Box> { let validator_type = docker_image.validator_type(); match validator_type { - ValidatorType::Bootstrap => (), - ValidatorType::Standard | ValidatorType::RPC | ValidatorType::Client => { + ValidatorType::Bootstrap | ValidatorType::Standard => (), + ValidatorType::RPC | ValidatorType::Client => { return Err(format!( - "Build docker image for validator type: {} not supported yet", - validator_type + "Build docker image for validator type: {validator_type} not supported yet" ) .into()); } } - let docker_path = solana_root_path.join(format!("{}/{}", "docker-build", validator_type)); + let docker_path = solana_root_path.join(format!("docker-build/{validator_type}")); self.create_base_image( solana_root_path, &docker_image, @@ -107,15 +106,9 @@ impl DockerConfig { let context_path = solana_root_path.display().to_string(); let progress_bar = new_spinner_progress_bar(); - progress_bar.set_message(format!( - "{BUILD}Building {} docker image...", - validator_type - )); + progress_bar.set_message(format!("{BUILD}Building {validator_type} docker image...")); - let command = format!( - "docker build -t {} -f {:?} {}", - docker_image, dockerfile, context_path - ); + let command = format!("docker build -t {docker_image} -f {dockerfile:?} {context_path}"); let output = match Command::new("sh") .arg("-c") diff --git a/src/main.rs b/src/main.rs index b36fe7c..884bb4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,9 +133,6 @@ fn parse_matches() -> clap::ArgMatches { Arg::with_name("docker_build") .long("docker-build") .requires("registry_name") - .requires("image_name") - .requires("base_image") - .requires("image_tag") .help("Build Docker images. Build new docker images"), ) .arg( @@ -150,7 +147,6 @@ fn parse_matches() -> clap::ArgMatches { .long("image-name") .takes_value(true) .default_value("k8s-cluster-image") - .required(true) .help("Docker image name. Will be prepended with validator_type (bootstrap or validator)"), ) .arg( @@ -158,14 +154,12 @@ fn parse_matches() -> clap::ArgMatches { .long("base-image") .takes_value(true) .default_value("ubuntu:20.04") - .required(true) .help("Docker base image"), ) .arg( Arg::with_name("image_tag") .long("tag") .takes_value(true) - .required(true) .default_value("latest") .help("Docker image tag."), ) @@ -523,26 +517,36 @@ async fn main() { .to_string(), )); + //TODO do not parse twice + let mut validator = Validator::new(DockerImage::new( + matches.value_of("registry_name").unwrap().to_string(), + ValidatorType::Standard, + matches.value_of("image_name").unwrap().to_string(), + matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(), + )); + if build_config.docker_build() { - match docker.build_image(solana_root.get_root_path(), bootstrap_validator.image()) { - Ok(_) => info!( - "{} image built successfully", - bootstrap_validator.validator_type() - ), - Err(err) => { - error!("Exiting........ {err}"); - return; + let validators = vec![&bootstrap_validator, &validator]; + for v in &validators { + match docker.build_image(solana_root.get_root_path(), v.image()) { + Ok(_) => info!("{} image built successfully", v.validator_type()), + Err(err) => { + error!("Exiting........ {err}"); + return; + } } } - match DockerConfig::push_image(bootstrap_validator.image()) { - Ok(_) => info!( - "{} image pushed successfully", - bootstrap_validator.validator_type() - ), - Err(err) => { - error!("Exiting........ {err}"); - return; + for v in &validators { + match DockerConfig::push_image(v.image()) { + Ok(_) => info!("{} image pushed successfully", v.validator_type()), + Err(err) => { + error!("Exiting........ {err}"); + return; + } } } } @@ -667,16 +671,6 @@ async fn main() { thread::sleep(Duration::from_secs(1)); } - let mut validator = Validator::new(DockerImage::new( - matches.value_of("registry_name").unwrap().to_string(), - ValidatorType::Standard, - matches.value_of("image_name").unwrap().to_string(), - matches - .value_of("image_tag") - .unwrap_or_default() - .to_string(), - )); - // Create and deploy validators secrets/selectors for validator_index in 0..num_validators { match kub_controller.create_validator_secret(validator_index, &config_directory) { diff --git a/src/scripts/validator-startup-script.sh b/src/scripts/validator-startup-script.sh new file mode 100755 index 0000000..3e58b58 --- /dev/null +++ b/src/scripts/validator-startup-script.sh @@ -0,0 +1,398 @@ +#!/bin/bash + +# Start Validator +# shellcheck disable=SC1091 +source /home/solana/k8s-cluster-scripts/common.sh + +args=( + --no-poh-speed-test + --no-os-network-limits-test +) +airdrops_enabled=1 +# next two values will be overwritten based on command line args. default is set here: k8s-cluster/src/genesis.rs +identity=validator-accounts/identity.json +vote_account=validator-accounts/vote.json +no_restart=0 +gossip_entrypoint=$BOOTSTRAP_GOSSIP_ADDRESS +ledger_dir=/home/solana/ledger +faucet_address=$LOAD_BALANCER_FAUCET_ADDRESS + +usage() { + if [[ -n $1 ]]; then + echo "$*" + echo + fi + cat <&1) + status=$? + + if [ $status -eq 0 ]; then + echo "Command succeeded: $description" + return 0 + else + echo "Command failed for: $description (Exit status $status)" + echo "$output" # Print the output which includes the error + + # Check for specific error message + if [[ "$output" == *"Vote account"*"already exists"* ]]; then + echo "Vote account already exists. Continuing without exiting." + vote_account_already_exists=true + return 0 + fi + if [[ "$output" == *"Stake account"*"already exists"* ]]; then + echo "Stake account already exists. Continuing without exiting." + stake_account_already_exists=true + return 0 + fi + + if [ "$retry_count" -lt $MAX_RETRIES ]; then + echo "Retrying in $RETRY_DELAY seconds..." + sleep $RETRY_DELAY + fi + fi + done + + echo "Max retry limit reached. Command still failed for: $description" + return 1 +} + +setup_validator() { + if ! run_solana_command "solana -u $LOAD_BALANCER_RPC_URL airdrop $node_sol $IDENTITY_FILE" "Airdrop"; then + echo "Aidrop command failed." + exit 1 + fi + + if ! run_solana_command "solana -u $LOAD_BALANCER_RPC_URL create-vote-account --allow-unsafe-authorized-withdrawer validator-accounts/vote.json $IDENTITY_FILE $IDENTITY_FILE -k $IDENTITY_FILE" "Create Vote Account"; then + if $vote_account_already_exists; then + echo "Vote account already exists. Skipping remaining commands." + else + echo "Create vote account failed." + exit 1 + fi + fi + + echo "created vote account" +} + +run_delegate_stake() { + echo "stake sol for account: $stake_sol" + if ! run_solana_command "solana -u $LOAD_BALANCER_RPC_URL create-stake-account validator-accounts/stake.json $stake_sol -k $IDENTITY_FILE" "Create Stake Account"; then + if $stake_account_already_exists; then + echo "Stake account already exists. Skipping remaining commands." + else + echo "Create stake account failed." + exit 1 + fi + fi + echo "created stake account" + + if [ "$stake_account_already_exists" != true ]; then + echo "stake account does not exist. so lets deligate" + if ! run_solana_command "solana -u $LOAD_BALANCER_RPC_URL delegate-stake validator-accounts/stake.json validator-accounts/vote.json --force -k $IDENTITY_FILE" "Delegate Stake"; then + echo "Delegate stake command failed." + exit 1 + fi + echo "delegated stake" + fi + + solana --url $LOAD_BALANCER_RPC_URL --keypair $IDENTITY_FILE stakes validator-accounts/stake.json +} + +echo "get airdrop and create vote account" +setup_validator +echo "create stake account and delegate stake" +run_delegate_stake + +echo running validator: + +echo "Validator Args" +for arg in "${args[@]}"; do + echo "$arg" +done + +while true; do + echo "$PS4$program ${args[*]}" + + $program "${args[@]}" & + pid=$! + echo "pid: $pid" + + if ((no_restart)); then + wait "$pid" + exit $? + fi + + while true; do + if [[ -z $pid ]] || ! kill -0 "$pid"; then + echo "############## validator exited, restarting ##############" + break + fi + sleep 1 + done + + kill_node +done \ No newline at end of file From 0471db4e32ab7dbc7cd59c430b5a702f6b7d2ed2 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 3 Apr 2024 00:35:27 +0000 Subject: [PATCH 31/49] wip. more work --- Cargo.lock | 1 + Cargo.toml | 1 + PROGRESS.md | 4 +- src/genesis.rs | 1 + src/k8s_helpers.rs | 27 +++++++- src/kubernetes.rs | 136 ++++++++++++++++++++++++++++++++++++++++ src/ledger_helper.rs | 31 +++++++++ src/lib.rs | 1 + src/main.rs | 69 +++++++++++++++++++- src/validator_config.rs | 9 +++ 10 files changed, 276 insertions(+), 4 deletions(-) create mode 100644 src/ledger_helper.rs diff --git a/Cargo.lock b/Cargo.lock index 6b8cc27..98c5bd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7135,6 +7135,7 @@ dependencies = [ "reqwest", "rustc_version", "rustls", + "solana-accounts-db", "solana-core", "solana-ledger", "solana-logger", diff --git a/Cargo.toml b/Cargo.toml index 7137d4c..f649bbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ log = "0.4.21" rand = "0.8.5" reqwest = { version = "0.11.23", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } rustls = { version = "0.21.10", default-features = false, features = ["quic"] } +solana-accounts-db = "1.18.8" solana-core = "1.18.8" solana-ledger = "1.18.8" solana-logger = "1.18.8" diff --git a/PROGRESS.md b/PROGRESS.md index 7f30bca..9bfffc3 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -30,7 +30,7 @@ - [ ] Client - [ ] Create & Deploy Replica Set - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Services @@ -42,7 +42,7 @@ - [x] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes) - [ ] Add metrics - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [ ] Create accounts diff --git a/src/genesis.rs b/src/genesis.rs index e692a0a..0995325 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -16,6 +16,7 @@ pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 1.0; pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 10.0; pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 1.0; pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 10.0; +pub const DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO: f64 = 10.0; fn fetch_spl(fetch_spl_file: &PathBuf) -> Result<(), Box> { let output = Command::new("bash") diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index d1289a6..aa36577 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -6,7 +6,7 @@ use { core::v1::{ Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, Volume, - VolumeMount, + VolumeMount, EnvVarSource, ObjectFieldSelector, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -157,3 +157,28 @@ pub fn create_selector(key: &str, value: &str) -> BTreeMap { btree.insert(key.to_string(), value.to_string()); btree } + +pub fn create_environment_variable( + name: &str, + value: Option, + field_path: Option, +) -> EnvVar { + match field_path { + Some(path) => EnvVar { + name: name.to_string(), + value_from: Some(EnvVarSource { + field_ref: Some(ObjectFieldSelector { + field_path: path, + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + }, + None => EnvVar { + name: name.to_string(), + value, + ..Default::default() + }, + } +} diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 06703f9..8d3bf70 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,6 +1,7 @@ use { crate::{ docker::DockerImage, k8s_helpers, validator_config::ValidatorConfig, Metrics, ValidatorType, + genesis::DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO, }, k8s_openapi::{ api::{ @@ -321,4 +322,139 @@ impl<'a> Kubernetes<'a> { ..Default::default() } } + + fn set_non_bootstrap_environment_variables(&self) -> Vec { + vec![ + k8s_helpers::create_environment_variable( + "NAMESPACE", + None, + Some("metadata.namespace".to_string()), + ), + k8s_helpers::create_environment_variable( + "BOOTSTRAP_RPC_ADDRESS", + Some("bootstrap-validator-service.$(NAMESPACE).svc.cluster.local:8899".to_string()), + None, + ), + k8s_helpers::create_environment_variable( + "BOOTSTRAP_GOSSIP_ADDRESS", + Some("bootstrap-validator-service.$(NAMESPACE).svc.cluster.local:8001".to_string()), + None, + ), + k8s_helpers::create_environment_variable( + "BOOTSTRAP_FAUCET_ADDRESS", + Some("bootstrap-validator-service.$(NAMESPACE).svc.cluster.local:9900".to_string()), + None, + ), + ] + } + + fn set_load_balancer_environment_variables(&self) -> Vec { + vec![ + k8s_helpers::create_environment_variable( + "LOAD_BALANCER_RPC_ADDRESS", + Some( + "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:8899" + .to_string(), + ), + None, + ), + k8s_helpers::create_environment_variable( + "LOAD_BALANCER_GOSSIP_ADDRESS", + Some( + "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:8001" + .to_string(), + ), + None, + ), + k8s_helpers::create_environment_variable( + "LOAD_BALANCER_FAUCET_ADDRESS", + Some( + "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:9900" + .to_string(), + ), + None, + ), + ] + } + + fn generate_validator_command_flags(&self, validator_stake: &Option) -> Vec { + let mut flags: Vec = Vec::new(); + self.generate_command_flags(&mut flags); + + flags.push("--internal-node-stake-sol".to_string()); + if let Some(stake) = validator_stake { + flags.push(stake.to_string()); + } else { + flags.push(self.validator_config.internal_node_stake_sol.to_string()); + } + + flags.push("--internal-node-sol".to_string()); + if let Some(stake) = validator_stake { + flags.push((DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO * stake).to_string()); + } else { + flags.push(self.validator_config.internal_node_sol.to_string()); + } + + if let Some(shred_version) = self.validator_config.shred_version { + flags.push("--expected-shred-version".to_string()); + flags.push(shred_version.to_string()); + } + + self.add_known_validators_if_exists(&mut flags); + + flags + } + + pub fn create_validator_replica_set( + &mut self, + container_name: &str, + validator_index: i32, + image_name: &str, + secret_name: Option, + label_selector: &BTreeMap, + validator_stake: &Option, + ) -> Result> { + let mut env_vars = self.set_non_bootstrap_environment_variables(); + if self.metrics.is_some() { + env_vars.push(self.get_metrics_env_var_secret()) + } + env_vars.append(&mut self.set_load_balancer_environment_variables()); + + let accounts_volume = Some(vec![Volume { + name: format!("validator-accounts-volume-{}", validator_index), + secret: Some(SecretVolumeSource { + secret_name, + ..Default::default() + }), + ..Default::default() + }]); + + let accounts_volume_mount = Some(vec![VolumeMount { + name: format!("validator-accounts-volume-{}", validator_index), + mount_path: "/home/solana/validator-accounts".to_string(), + ..Default::default() + }]); + + let mut command = + vec!["/home/solana/k8s-cluster-scripts/validator-startup-script.sh".to_string()]; + command.extend(self.generate_validator_command_flags(validator_stake)); + + for c in command.iter() { + debug!("validator command: {}", c); + } + + + k8s_helpers::create_replica_set( + &ValidatorType::Standard, + self.namespace.as_str(), + label_selector, + image_name, + env_vars, + &command, + accounts_volume, + accounts_volume_mount, + None, + self.pod_requests.requests.clone(), + ) + } } diff --git a/src/ledger_helper.rs b/src/ledger_helper.rs new file mode 100644 index 0000000..5223dde --- /dev/null +++ b/src/ledger_helper.rs @@ -0,0 +1,31 @@ +use { + crate::{genesis::DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, LEDGER_DIR}, + log::*, + solana_accounts_db::hardened_unpack::open_genesis_config, + solana_sdk::shred_version::compute_shred_version, + std::error::Error, +}; + +fn ledger_directory_exists() -> Result<(), Box> { + if !LEDGER_DIR.exists() { + return Err(format!( + "Ledger Directory does not exist, have you created genesis yet??" + ).into()); + } + Ok(()) +} + +pub struct LedgerHelper {} + +impl LedgerHelper { + pub fn get_shred_version() -> Result> { + ledger_directory_exists()?; + let genesis_config = open_genesis_config( + LEDGER_DIR.as_path(), + DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, + ); + let shred_version = compute_shred_version(&genesis_config?.hash(), None); + info!("Shred Version: {}", shred_version); + Ok(shred_version) + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 80d7818..234898f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,6 +97,7 @@ pub mod docker; pub mod genesis; pub mod k8s_helpers; pub mod kubernetes; +pub mod ledger_helper; pub mod release; pub mod validator; pub mod validator_config; diff --git a/src/main.rs b/src/main.rs index 884bb4b..de49915 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use { strum::VariantNames, validator_lab::{ docker::{DockerConfig, DockerImage}, - genesis::{Genesis, GenesisFlags}, + genesis::{Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL}, kubernetes::{Kubernetes, PodRequests}, release::{BuildConfig, BuildType, DeployMethod}, validator::{LabelType, Validator}, @@ -210,6 +210,18 @@ fn parse_matches() -> clap::ArgMatches { .long("full-rpc") .help("Validator config. Support full RPC services on all nodes"), ) + .arg( + Arg::with_name("internal_node_sol") + .long("internal-node-sol") + .takes_value(true) + .help("Amount to fund internal nodes in genesis config."), + ) + .arg( + Arg::with_name("internal_node_stake_sol") + .long("internal-node-stake-sol") + .takes_value(true) + .help("Amount to stake internal nodes (Sol)."), + ) // kubernetes config .arg( Arg::with_name("cpu_requests") @@ -376,6 +388,18 @@ async fn main() { let mut validator_config = ValidatorConfig { tpu_enable_udp: matches.is_present("tpu_enable_udp"), tpu_disable_quic: matches.is_present("tpu_disable_quic"), + internal_node_sol: matches + .value_of("internal_node_sol") + .unwrap_or(DEFAULT_INTERNAL_NODE_SOL.to_string().as_str()) + .parse::() + .expect("Invalid value for internal_node_stake_sol") as f64, + internal_node_stake_sol: matches + .value_of("internal_node_stake_sol") + .unwrap_or(DEFAULT_INTERNAL_NODE_STAKE_SOL.to_string().as_str()) + .parse::() + .expect("Invalid value for internal_node_stake_sol") + as f64, + shred_version: None, // set after genesis created max_ledger_size: if matches.is_present("limit_ledger_size") { let limit_ledger_size = match matches.value_of("limit_ledger_size") { Some(_) => value_t_or_exit!(matches, "limit_ledger_size", u64), @@ -480,6 +504,14 @@ async fn main() { } } + match LedgerHelper::get_shred_version() { + Ok(shred_version) => kub_controller.set_shred_version(shred_version), + Err(err) => { + error!("{}", err); + return; + } + } + //unwraps are safe here. since their requirement is enforced by argmatches let docker = DockerConfig::new( matches @@ -709,5 +741,40 @@ async fn main() { validator_keypair.pubkey().to_string(), LabelType::ValidatorReplicaSet, ); + + let validator_replica_set = match kub_controller.create_validator_replica_set( + validator_container_name, + validator_index, + validator_image_name, + validator_secret.metadata.name.clone(), + &validator_labels, + &stake, + ) { + Ok(replica_set) => replica_set, + Err(err) => { + error!("Error creating validator replicas_set: {}", err); + return; + } + }; + + let _ = match kub_controller + .deploy_replicas_set(&validator_replica_set) + .await + { + Ok(rs) => { + info!( + "validator replica set ({}) deployed successfully", + validator_index + ); + rs.metadata.name.unwrap() + } + Err(err) => { + error!( + "Error! Failed to deploy validator replica set: {}. err: {:?}", + validator_index, err + ); + return; + } + }; } } diff --git a/src/validator_config.rs b/src/validator_config.rs index 35f4a4b..e2cc7f3 100644 --- a/src/validator_config.rs +++ b/src/validator_config.rs @@ -3,6 +3,9 @@ use solana_sdk::pubkey::Pubkey; pub struct ValidatorConfig { pub tpu_enable_udp: bool, pub tpu_disable_quic: bool, + pub internal_node_sol: f64, + pub internal_node_stake_sol: f64, + pub shred_version: Option, pub max_ledger_size: Option, pub skip_poh_verify: bool, pub no_snapshot_fetch: bool, @@ -26,6 +29,9 @@ impl std::fmt::Display for ValidatorConfig { "Runtime Config\n\ tpu_enable_udp: {}\n\ tpu_disable_quic: {}\n\ + internal_node_sol: {}\n\ + internal_node_stake_sol: {}\n\ + shred_version: {:?}\n\ max_ledger_size: {:?}\n\ skip_poh_verify: {}\n\ no_snapshot_fetch: {}\n\ @@ -34,6 +40,9 @@ impl std::fmt::Display for ValidatorConfig { known_validators: {:?}", self.tpu_enable_udp, self.tpu_disable_quic, + self.internal_node_sol, + self.internal_node_stake_sol, + self.shred_version, self.max_ledger_size, self.skip_poh_verify, self.no_snapshot_fetch, From 26ddaad5e92c30cb307714e3f5a0ae67321dc416 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 3 Apr 2024 20:51:16 +0000 Subject: [PATCH 32/49] i forgot to build the validator docker images first --- PROGRESS.md | 8 +++++--- README.md | 9 +++++++- src/genesis.rs | 1 - src/k8s_helpers.rs | 18 ++++++++-------- src/kubernetes.rs | 49 ++++++++++++++++++++------------------------ src/ledger_helper.rs | 22 ++++++++++---------- src/main.rs | 28 ++++++++++++------------- 7 files changed, 67 insertions(+), 68 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 9bfffc3..a8ff8b4 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -15,9 +15,11 @@ - [x] Create Genesis - [x] Generate faucet and bootstrap accounts - [x] Build genesis -- [x] Docker Build - - [x] Build Bootstrap Image - - [x] Push Image to registry +- [x] Docker Build and Push to registry + - [x] Bootstrap + - [ ] Validator (regular) + - [ ] RPC nodes + - [ ] Client - [ ] Create & Deploy Secrets - [x] Bootstrap - [x] Validator (regular) diff --git a/README.md b/README.md index 3646762..68eb485 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Example: ``` cargo run --bin cluster -- -n - --num_validators + --num-validators --deploy-method local --local-path /home/sol/solana # genesis config. Optional: Many of these have defaults @@ -61,6 +61,13 @@ cargo run --bin cluster -- --tag # e.g. v1 --base-image # e.g. ubuntu:20.04 --image-name # e.g. cluster-image + # validator config + --full-rpc + --internal-node-sol + --internal-node-stake-sol + # kubernetes config + --cpu-requests + --memory-requests ``` ## Metrics diff --git a/src/genesis.rs b/src/genesis.rs index 0995325..e692a0a 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -16,7 +16,6 @@ pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 1.0; pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 10.0; pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 1.0; pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 10.0; -pub const DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO: f64 = 10.0; fn fetch_spl(fetch_spl_file: &PathBuf) -> Result<(), Box> { let output = Command::new("bash") diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index aa36577..9d9af58 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -1,12 +1,12 @@ use { - crate::{docker::DockerImage, ValidatorType}, + crate::docker::DockerImage, k8s_openapi::{ api::{ apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ - Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe, - ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, Volume, - VolumeMount, EnvVarSource, ObjectFieldSelector, + Container, EnvVar, EnvVarSource, ObjectFieldSelector, PodSecurityContext, PodSpec, + PodTemplateSpec, ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, + Volume, VolumeMount, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -43,15 +43,14 @@ pub fn create_secret_from_files( #[allow(clippy::too_many_arguments)] pub fn create_replica_set( - name: &ValidatorType, + name: &str, namespace: &str, label_selector: &BTreeMap, - image_name: &DockerImage, + image: &DockerImage, environment_variables: Vec, command: &[String], volumes: Option>, volume_mounts: Option>, - readiness_probe: Option, pod_requests: BTreeMap, ) -> Result> { let pod_spec = PodTemplateSpec { @@ -61,13 +60,12 @@ pub fn create_replica_set( }), spec: Some(PodSpec { containers: vec![Container { - name: format!("{}-{}", image_name.validator_type(), "container"), - image: Some(image_name.to_string()), + name: format!("{}-{}", image.validator_type(), "container"), + image: Some(image.to_string()), image_pull_policy: Some("Always".to_string()), env: Some(environment_variables), command: Some(command.to_owned()), volume_mounts, - readiness_probe, resources: Some(ResourceRequirements { requests: Some(pod_requests), ..Default::default() diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 8d3bf70..5ed4cab 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -1,7 +1,6 @@ use { crate::{ docker::DockerImage, k8s_helpers, validator_config::ValidatorConfig, Metrics, ValidatorType, - genesis::DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO, }, k8s_openapi::{ api::{ @@ -65,6 +64,10 @@ impl<'a> Kubernetes<'a> { } } + pub fn set_shred_version(&mut self, shred_version: u16) { + self.validator_config.shred_version = Some(shred_version); + } + pub async fn namespace_exists(&self) -> Result { let namespaces: Api = Api::all(self.k8s_client.clone()); let namespace_list = namespaces.list(&ListParams::default()).await?; @@ -185,7 +188,7 @@ impl<'a> Kubernetes<'a> { command.extend(self.generate_bootstrap_command_flags()); k8s_helpers::create_replica_set( - &ValidatorType::Bootstrap, + &ValidatorType::Bootstrap.to_string(), self.namespace.as_str(), label_selector, image_name, @@ -193,7 +196,6 @@ impl<'a> Kubernetes<'a> { &command, accounts_volume, accounts_volume_mount, - None, self.pod_requests.requests.clone(), ) } @@ -377,23 +379,24 @@ impl<'a> Kubernetes<'a> { ] } - fn generate_validator_command_flags(&self, validator_stake: &Option) -> Vec { + fn add_known_validators_if_exists(&self, flags: &mut Vec) { + if let Some(known_validators) = &self.validator_config.known_validators { + for key in known_validators.iter() { + flags.push("--known-validator".to_string()); + flags.push(key.to_string()); + } + } + } + + fn generate_validator_command_flags(&self) -> Vec { let mut flags: Vec = Vec::new(); self.generate_command_flags(&mut flags); flags.push("--internal-node-stake-sol".to_string()); - if let Some(stake) = validator_stake { - flags.push(stake.to_string()); - } else { - flags.push(self.validator_config.internal_node_stake_sol.to_string()); - } + flags.push(self.validator_config.internal_node_stake_sol.to_string()); flags.push("--internal-node-sol".to_string()); - if let Some(stake) = validator_stake { - flags.push((DEFAULT_INTERNAL_NODE_SOL_TO_STAKE_SOL_RATIO * stake).to_string()); - } else { - flags.push(self.validator_config.internal_node_sol.to_string()); - } + flags.push(self.validator_config.internal_node_sol.to_string()); if let Some(shred_version) = self.validator_config.shred_version { flags.push("--expected-shred-version".to_string()); @@ -407,12 +410,10 @@ impl<'a> Kubernetes<'a> { pub fn create_validator_replica_set( &mut self, - container_name: &str, - validator_index: i32, - image_name: &str, + image: &DockerImage, secret_name: Option, label_selector: &BTreeMap, - validator_stake: &Option, + validator_index: usize, ) -> Result> { let mut env_vars = self.set_non_bootstrap_environment_variables(); if self.metrics.is_some() { @@ -437,23 +438,17 @@ impl<'a> Kubernetes<'a> { let mut command = vec!["/home/solana/k8s-cluster-scripts/validator-startup-script.sh".to_string()]; - command.extend(self.generate_validator_command_flags(validator_stake)); - - for c in command.iter() { - debug!("validator command: {}", c); - } - + command.extend(self.generate_validator_command_flags()); k8s_helpers::create_replica_set( - &ValidatorType::Standard, + &format!("{}-{validator_index}", ValidatorType::Standard), self.namespace.as_str(), label_selector, - image_name, + image, env_vars, &command, accounts_volume, accounts_volume_mount, - None, self.pod_requests.requests.clone(), ) } diff --git a/src/ledger_helper.rs b/src/ledger_helper.rs index 5223dde..14ac6d2 100644 --- a/src/ledger_helper.rs +++ b/src/ledger_helper.rs @@ -1,16 +1,16 @@ use { - crate::{genesis::DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, LEDGER_DIR}, + crate::genesis::DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, log::*, solana_accounts_db::hardened_unpack::open_genesis_config, solana_sdk::shred_version::compute_shred_version, - std::error::Error, + std::{error::Error, path::PathBuf}, }; -fn ledger_directory_exists() -> Result<(), Box> { - if !LEDGER_DIR.exists() { - return Err(format!( - "Ledger Directory does not exist, have you created genesis yet??" - ).into()); +fn ledger_directory_exists(ledger_dir: &PathBuf) -> Result<(), Box> { + if !ledger_dir.exists() { + return Err( + format!("Ledger Directory does not exist, have you created genesis yet??").into(), + ); } Ok(()) } @@ -18,14 +18,14 @@ fn ledger_directory_exists() -> Result<(), Box> { pub struct LedgerHelper {} impl LedgerHelper { - pub fn get_shred_version() -> Result> { - ledger_directory_exists()?; + pub fn get_shred_version(ledger_dir: &PathBuf) -> Result> { + ledger_directory_exists(ledger_dir)?; let genesis_config = open_genesis_config( - LEDGER_DIR.as_path(), + ledger_dir.as_path(), DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, ); let shred_version = compute_shred_version(&genesis_config?.hash(), None); info!("Shred Version: {}", shred_version); Ok(shred_version) } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index de49915..cdc09b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,11 @@ use { strum::VariantNames, validator_lab::{ docker::{DockerConfig, DockerImage}, - genesis::{Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL}, + genesis::{ + Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL, + }, kubernetes::{Kubernetes, PodRequests}, + ledger_helper::LedgerHelper, release::{BuildConfig, BuildType, DeployMethod}, validator::{LabelType, Validator}, validator_config::ValidatorConfig, @@ -504,7 +507,8 @@ async fn main() { } } - match LedgerHelper::get_shred_version() { + let ledger_dir = config_directory.join("bootstrap-validator"); + match LedgerHelper::get_shred_version(&ledger_dir) { Ok(shred_version) => kub_controller.set_shred_version(shred_version), Err(err) => { error!("{}", err); @@ -728,7 +732,7 @@ async fn main() { validator.add_label( "validator/name", - &format!("validator-{}", validator_index), + &format!("validator-{validator_index}"), LabelType::ValidatorReplicaSet, ); validator.add_label( @@ -743,16 +747,14 @@ async fn main() { ); let validator_replica_set = match kub_controller.create_validator_replica_set( - validator_container_name, + validator.image(), + validator.secret().metadata.name.clone(), + validator.replica_set_labels(), validator_index, - validator_image_name, - validator_secret.metadata.name.clone(), - &validator_labels, - &stake, ) { Ok(replica_set) => replica_set, Err(err) => { - error!("Error creating validator replicas_set: {}", err); + error!("Error creating validator replicas_set: {err}"); return; } }; @@ -762,16 +764,12 @@ async fn main() { .await { Ok(rs) => { - info!( - "validator replica set ({}) deployed successfully", - validator_index - ); + info!("validator replica set ({validator_index}) deployed successfully"); rs.metadata.name.unwrap() } Err(err) => { error!( - "Error! Failed to deploy validator replica set: {}. err: {:?}", - validator_index, err + "Error! Failed to deploy validator replica set: {validator_index}. err: {err}" ); return; } From 3be12a6445bc00ab88f82adfabb6320297d7a2be Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 3 Apr 2024 22:15:36 +0000 Subject: [PATCH 33/49] working. build and deploy validators --- src/docker.rs | 9 +++-- src/kubernetes.rs | 5 +-- src/main.rs | 36 +++++++++---------- ... => bootstrap-validator-startup-script.sh} | 0 4 files changed, 28 insertions(+), 22 deletions(-) rename src/scripts/{bootstrap-startup-script.sh => bootstrap-validator-startup-script.sh} (100%) diff --git a/src/docker.rs b/src/docker.rs index 67de22f..65d913a 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -154,10 +154,15 @@ impl DockerConfig { fs::create_dir_all(&docker_path)?; if let DeployMethod::Local(_) = self.deploy_method { - if validator_type == &ValidatorType::Bootstrap { + if validator_type == &ValidatorType::Bootstrap + || validator_type == &ValidatorType::Standard + { let manifest_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")); - let files_to_copy = ["bootstrap-startup-script.sh", "common.sh"]; + let files_to_copy = [ + format!("{validator_type}-startup-script.sh"), + "common.sh".to_string(), + ]; for file_name in files_to_copy.iter() { Self::copy_file_to_docker(&manifest_path, &docker_path, file_name)?; } diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 5ed4cab..67203be 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -183,8 +183,9 @@ impl<'a> Kubernetes<'a> { ..Default::default() }]); - let mut command = - vec!["/home/solana/k8s-cluster-scripts/bootstrap-startup-script.sh".to_string()]; + let mut command = vec![ + "/home/solana/k8s-cluster-scripts/bootstrap-validator-startup-script.sh".to_string(), + ]; command.extend(self.generate_bootstrap_command_flags()); k8s_helpers::create_replica_set( diff --git a/src/main.rs b/src/main.rs index cdc09b7..e75a22c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -525,24 +525,6 @@ async fn main() { deploy_method, ); - // metrics secret create once and use by all pods - if kub_controller.metrics.is_some() { - let metrics_secret = match kub_controller.create_metrics_secret() { - Ok(secret) => secret, - Err(err) => { - error!("Failed to create metrics secret! {err}"); - return; - } - }; - match kub_controller.deploy_secret(&metrics_secret).await { - Ok(_) => (), - Err(err) => { - error!("{err}"); - return; - } - } - }; - let mut bootstrap_validator = Validator::new(DockerImage::new( matches.value_of("registry_name").unwrap().to_string(), ValidatorType::Bootstrap, @@ -587,6 +569,24 @@ async fn main() { } } + // metrics secret create once and use by all pods + if kub_controller.metrics.is_some() { + let metrics_secret = match kub_controller.create_metrics_secret() { + Ok(secret) => secret, + Err(err) => { + error!("Failed to create metrics secret! {err}"); + return; + } + }; + match kub_controller.deploy_secret(&metrics_secret).await { + Ok(_) => (), + Err(err) => { + error!("{err}"); + return; + } + } + }; + match kub_controller.create_bootstrap_secret("bootstrap-accounts-secret", &config_directory) { Ok(secret) => bootstrap_validator.set_secret(secret), Err(err) => { diff --git a/src/scripts/bootstrap-startup-script.sh b/src/scripts/bootstrap-validator-startup-script.sh similarity index 100% rename from src/scripts/bootstrap-startup-script.sh rename to src/scripts/bootstrap-validator-startup-script.sh From 06fe5e0a2793a5aab39f9dacf468aab334b5f59f Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Apr 2024 04:23:54 +0000 Subject: [PATCH 34/49] update scripts to work with agave and solana validator versions --- PROGRESS.md | 4 +-- src/genesis.rs | 8 +++--- src/kubernetes.rs | 8 ++++++ src/main.rs | 12 +++++++++ src/release.rs | 12 ++++----- .../bootstrap-validator-startup-script.sh | 18 +++++++++++-- src/scripts/validator-startup-script.sh | 25 ++++++++++++++++--- 7 files changed, 69 insertions(+), 18 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index a8ff8b4..5e7c4d0 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -17,7 +17,7 @@ - [x] Build genesis - [x] Docker Build and Push to registry - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [ ] Create & Deploy Secrets @@ -37,7 +37,7 @@ - [ ] Client - [ ] Create & Deploy Services - [x] Bootstrap - - [ ] Validator (regular) + - [x] Validator (regular) - [ ] RPC nodes - [ ] Client - [x] Check Bootstrap is deployed and running diff --git a/src/genesis.rs b/src/genesis.rs index e692a0a..03c47da 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -12,10 +12,10 @@ use { pub const DEFAULT_FAUCET_LAMPORTS: u64 = 500000000000000000; // from agave/ pub const DEFAULT_MAX_GENESIS_ARCHIVE_UNPACKED_SIZE: u64 = 1073741824; // from agave/ -pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 1.0; -pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 10.0; -pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 1.0; -pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 10.0; +pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 10.0; +pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 100.0; +pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 10.0; +pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 100.0; fn fetch_spl(fetch_spl_file: &PathBuf) -> Result<(), Box> { let output = Command::new("bash") diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 67203be..ed21c97 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -453,4 +453,12 @@ impl<'a> Kubernetes<'a> { self.pod_requests.requests.clone(), ) } + + pub fn create_validator_service( + &self, + service_name: &str, + label_selector: &BTreeMap, + ) -> Service { + k8s_helpers::create_service(service_name, self.namespace.as_str(), label_selector, false) + } } diff --git a/src/main.rs b/src/main.rs index e75a22c..ca58521 100644 --- a/src/main.rs +++ b/src/main.rs @@ -774,5 +774,17 @@ async fn main() { return; } }; + + // let service_name = format!("validator-service-{index}"); + let validator_service = kub_controller.create_validator_service( + &format!("validator-service-{validator_index}"), + validator.replica_set_labels(), + ); + match kub_controller.deploy_service(&validator_service).await { + Ok(_) => info!("validator service ({validator_index}) deployed successfully"), + Err(err) => { + error!("Error! Failed to deploy validator service: {validator_index}. err: {err}") + } + } } } diff --git a/src/release.rs b/src/release.rs index e173401..7314840 100644 --- a/src/release.rs +++ b/src/release.rs @@ -58,6 +58,10 @@ impl BuildConfig { } pub async fn prepare(&self) -> Result<(), Box> { + if self.build_type == BuildType::Skip { + info!("skipping build"); + return Ok(()); + } match &self.deploy_method { DeployMethod::ReleaseChannel(channel) => match self.setup_tar_deploy(channel).await { Ok(tar_directory) => { @@ -77,7 +81,7 @@ impl BuildConfig { async fn setup_tar_deploy(&self, release_channel: &String) -> Result> { let file_name = "solana-release"; let tar_filename = format!("{file_name}.tar.bz2"); - info!("tar file: {}", tar_filename); + info!("tar file: {tar_filename}"); self.download_release_from_channel(&tar_filename, release_channel) .await?; @@ -92,11 +96,7 @@ impl BuildConfig { } fn setup_local_deploy(&self) -> Result<(), Box> { - if self.build_type != BuildType::Skip { - self.build()?; - } else { - info!("Build skipped due to --build-type skip"); - } + self.build()?; Ok(()) } diff --git a/src/scripts/bootstrap-validator-startup-script.sh b/src/scripts/bootstrap-validator-startup-script.sh index 56e0a7e..f9c72d0 100755 --- a/src/scripts/bootstrap-validator-startup-script.sh +++ b/src/scripts/bootstrap-validator-startup-script.sh @@ -7,10 +7,24 @@ nohup solana-faucet --keypair bootstrap-accounts/faucet.json & # Start the bootstrap validator node # shellcheck disable=SC1091 source /home/solana/k8s-cluster-scripts/common.sh +no_restart=0 -program="agave-validator" +# Define the paths to the validator cli. pre 1.18 is `solana-validator`. post 1.18 is `agave-validator` +agave_validator="/home/solana/.cargo/bin/agave-validator" +solana_validator="/home/solana/.cargo/bin/solana-validator" -no_restart=0 +# Initialize program variable +program="" + +# Check if agave-validator exists and is executable +if [[ -x "$agave_validator" ]]; then + program="agave-validator" +elif [[ -x "$solana_validator" ]]; then + program="solana-validator" +else + echo "Neither agave-validator nor solana-validator could be found or is not executable." + exit 1 +fi echo "PROGRAM: $program" diff --git a/src/scripts/validator-startup-script.sh b/src/scripts/validator-startup-script.sh index 3e58b58..40295c4 100755 --- a/src/scripts/validator-startup-script.sh +++ b/src/scripts/validator-startup-script.sh @@ -9,7 +9,8 @@ args=( --no-os-network-limits-test ) airdrops_enabled=1 -# next two values will be overwritten based on command line args. default is set here: k8s-cluster/src/genesis.rs +node_sol= +stake_sol= identity=validator-accounts/identity.json vote_account=validator-accounts/vote.json no_restart=0 @@ -17,6 +18,25 @@ gossip_entrypoint=$BOOTSTRAP_GOSSIP_ADDRESS ledger_dir=/home/solana/ledger faucet_address=$LOAD_BALANCER_FAUCET_ADDRESS +# Define the paths to the validator cli. pre 1.18 is `solana-validator`. post 1.18 is `agave-validator` +agave_validator="/home/solana/.cargo/bin/agave-validator" +solana_validator="/home/solana/.cargo/bin/solana-validator" + +# Initialize program variable +program="" + +# Check if agave-validator exists and is executable +if [[ -x "$agave_validator" ]]; then + program="agave-validator" +elif [[ -x "$solana_validator" ]]; then + program="solana-validator" +else + echo "Neither agave-validator nor solana-validator could be found or is not executable." + exit 1 +fi + +echo "PROGRAM: $program" + usage() { if [[ -n $1 ]]; then echo "$*" @@ -236,9 +256,6 @@ default_arg --allow-private-addr default_arg --gossip-port 8001 default_arg --rpc-port 8899 -program="agave-validator" -echo "program: $program" - PS4="$(basename "$0"): " echo "PS4: $PS4" From ddfcdb9c25febcfa8aa41287359e0b993e55fe62 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Apr 2024 19:05:45 +0000 Subject: [PATCH 35/49] create rpc validator accounts --- PROGRESS.md | 2 +- README.md | 6 ++++++ src/main.rs | 23 ++++++++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 5e7c4d0..660348f 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -49,7 +49,7 @@ - [ ] Client - [ ] Create accounts - [x] Validator (regular) - - [ ] RPC + - [x] RPC - [ ] Client - [ ] Add feature flags to configure: - [ ] Bootstrap diff --git a/README.md b/README.md index 68eb485..b76ffe5 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,12 @@ cargo run --bin cluster -- --memory-requests ``` +#### RPC Nodes +You can add in RPC nodes. These sit behind a load balancer. Load balancer distributed loads across all RPC nodes that the bootstrap. Set the number of RPC nodes with: +``` +--num-rpc-nodes +``` + ## Metrics 1) Setup metrics database: ``` diff --git a/src/main.rs b/src/main.rs index ca58521..6f9bf64 100644 --- a/src/main.rs +++ b/src/main.rs @@ -225,6 +225,18 @@ fn parse_matches() -> clap::ArgMatches { .takes_value(true) .help("Amount to stake internal nodes (Sol)."), ) + //RPC config + .arg( + Arg::with_name("number_of_rpc_nodes") + .long("num-rpc-nodes") + .takes_value(true) + .default_value("0") + .help("Number of rpc nodes") + .validator(|s| match s.parse::() { + Ok(n) if n >= 0 => Ok(()), + _ => Err(String::from("number_of_rpc_nodes should be >= 0")), + }), + ) // kubernetes config .arg( Arg::with_name("cpu_requests") @@ -296,6 +308,7 @@ async fn main() { }; let num_validators = value_t_or_exit!(matches, "number_of_validators", usize); + let num_rpc_nodes = value_t_or_exit!(matches, "number_of_rpc_nodes", usize); let deploy_method = if let Some(local_path) = matches.value_of("local_path") { DeployMethod::Local(local_path.to_owned()) @@ -507,11 +520,19 @@ async fn main() { } } + match genesis.generate_accounts(ValidatorType::RPC, num_rpc_nodes) { + Ok(_) => (), + Err(err) => { + error!("generate non voting accounts error! {err}"); + return; + } + } + let ledger_dir = config_directory.join("bootstrap-validator"); match LedgerHelper::get_shred_version(&ledger_dir) { Ok(shred_version) => kub_controller.set_shred_version(shred_version), Err(err) => { - error!("{}", err); + error!("{err}"); return; } } From d3ef0d3c8bdcbec5c5a6328e6ded8885f72549b1 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Apr 2024 20:21:18 +0000 Subject: [PATCH 36/49] wip. just added rpc startup script --- src/scripts/rpc-startup-script.sh | 294 ++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100755 src/scripts/rpc-startup-script.sh diff --git a/src/scripts/rpc-startup-script.sh b/src/scripts/rpc-startup-script.sh new file mode 100755 index 0000000..2bddcd0 --- /dev/null +++ b/src/scripts/rpc-startup-script.sh @@ -0,0 +1,294 @@ +#!/bin/bash +set -e + +nohup solana-faucet --keypair non-voting-validator-accounts/faucet.json & + +# Start Validator +# shellcheck disable=SC1091 +source /home/solana/k8s-cluster-scripts/common.sh + +args=( + --max-genesis-archive-unpacked-size 1073741824 + --no-poh-speed-test + --no-os-network-limits-test + --no-voting +) +airdrops_enabled=1 +node_sol=500 # 500 SOL: number of SOL to airdrop the node for transaction fees and vote account rent exemption (ignored if airdrops_enabled=0) +identity=non-voting-validator-accounts/identity.json +no_restart=0 +gossip_entrypoint=$BOOTSTRAP_GOSSIP_ADDRESS +ledger_dir=/home/solana/ledger +# faucet_address=$BOOTSTRAP_FAUCET_ADDRESS +faucet_address=$LOAD_BALANCER_FAUCET_ADDRESS + +usage() { + if [[ -n $1 ]]; then + echo "$*" + echo + fi + cat < Date: Thu, 4 Apr 2024 22:53:13 +0000 Subject: [PATCH 37/49] add and deploy rpc secrets --- src/kubernetes.rs | 20 +++++++++++++++++++- src/main.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/kubernetes.rs b/src/kubernetes.rs index ed21c97..093c453 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -111,7 +111,7 @@ impl<'a> Kubernetes<'a> { validator_index: usize, config_dir: &PathBuf, ) -> Result> { - let secret_name = format!("validator-accounts-secret-{}", validator_index); + let secret_name = format!("validator-accounts-secret-{validator_index}"); let accounts = ["identity", "vote", "stake"]; let key_files: Vec<(PathBuf, &str)> = accounts @@ -461,4 +461,22 @@ impl<'a> Kubernetes<'a> { ) -> Service { k8s_helpers::create_service(service_name, self.namespace.as_str(), label_selector, false) } + + pub fn create_rpc_secret( + &self, + rpc_index: usize, + config_dir: &PathBuf, + ) -> Result> { + let secret_name = format!("rpc-node-account-secret-{rpc_index}"); + + let key_files = vec![ + ( + config_dir.join(format!("rpc-node-identity-{rpc_index}.json")), + "identity", + ), + (config_dir.join("faucet.json"), "faucet"), + ]; + + k8s_helpers::create_secret_from_files(&secret_name, &key_files) + } } diff --git a/src/main.rs b/src/main.rs index 6f9bf64..1b92b17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -567,6 +567,17 @@ async fn main() { .to_string(), )); + //TODO do not parse thrice + let mut rpc_node = Validator::new(DockerImage::new( + matches.value_of("registry_name").unwrap().to_string(), + ValidatorType::Standard, + matches.value_of("image_name").unwrap().to_string(), + matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(), + )); + if build_config.docker_build() { let validators = vec![&bootstrap_validator, &validator]; for v in &validators { @@ -728,6 +739,25 @@ async fn main() { thread::sleep(Duration::from_secs(1)); } + if num_rpc_nodes > 0 { + for rpc_index in 0..num_rpc_nodes { + match kub_controller.create_rpc_secret(rpc_index, &config_directory) { + Ok(secret) => rpc_node.set_secret(secret), + Err(err) => { + error!("Failed to create RPC node {rpc_index} secret! {err}"); + return; + } + } + match kub_controller.deploy_secret(&rpc_node.secret()).await { + Ok(_) => info!("Deployed RPC node {rpc_index} Secret"), + Err(err) => { + error!("{err}"); + return; + } + } + } + } + // Create and deploy validators secrets/selectors for validator_index in 0..num_validators { match kub_controller.create_validator_secret(validator_index, &config_directory) { @@ -739,7 +769,7 @@ async fn main() { }; match kub_controller.deploy_secret(&validator.secret()).await { - Ok(_) => (), + Ok(_) => info!("Deployed validator {validator_index} secret"), Err(err) => { error!("{err}"); return; From 75e6bfd8cd484b2fcbd22686ab3ead79a4d7a128 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Apr 2024 23:28:30 +0000 Subject: [PATCH 38/49] build and push rpc docker image --- PROGRESS.md | 4 +-- src/docker.rs | 27 +++++++++---------- src/main.rs | 8 +++--- ...p-script.sh => rpc-node-startup-script.sh} | 0 4 files changed, 18 insertions(+), 21 deletions(-) rename src/scripts/{rpc-startup-script.sh => rpc-node-startup-script.sh} (100%) diff --git a/PROGRESS.md b/PROGRESS.md index 660348f..5a5c7d9 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -18,12 +18,12 @@ - [x] Docker Build and Push to registry - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [ ] Create & Deploy Secrets - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [ ] Create & Deploy Selector - [x] Bootstrap diff --git a/src/docker.rs b/src/docker.rs index 65d913a..ab0b6af 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -70,8 +70,8 @@ impl DockerConfig { ) -> Result<(), Box> { let validator_type = docker_image.validator_type(); match validator_type { - ValidatorType::Bootstrap | ValidatorType::Standard => (), - ValidatorType::RPC | ValidatorType::Client => { + ValidatorType::Bootstrap | ValidatorType::Standard | ValidatorType::RPC => (), + ValidatorType::Client => { return Err(format!( "Build docker image for validator type: {validator_type} not supported yet" ) @@ -154,18 +154,15 @@ impl DockerConfig { fs::create_dir_all(&docker_path)?; if let DeployMethod::Local(_) = self.deploy_method { - if validator_type == &ValidatorType::Bootstrap - || validator_type == &ValidatorType::Standard - { - let manifest_path = - PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")); - let files_to_copy = [ - format!("{validator_type}-startup-script.sh"), - "common.sh".to_string(), - ]; - for file_name in files_to_copy.iter() { - Self::copy_file_to_docker(&manifest_path, &docker_path, file_name)?; - } + // Copy startup scripts into build directory + let manifest_path = + PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR")); + let files_to_copy = [ + format!("{validator_type}-startup-script.sh"), + "common.sh".to_string(), + ]; + for file_name in files_to_copy.iter() { + Self::copy_file_to_docker(&manifest_path, &docker_path, file_name)?; } } @@ -173,7 +170,7 @@ impl DockerConfig { if let DeployMethod::ReleaseChannel(_) = self.deploy_method { ("solana-release", "./src/scripts".to_string()) } else { - ("farf", format!("./docker-build/{}", validator_type)) + ("farf", format!("./docker-build/{validator_type}")) }; let dockerfile = format!( diff --git a/src/main.rs b/src/main.rs index 1b92b17..326168e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -570,7 +570,7 @@ async fn main() { //TODO do not parse thrice let mut rpc_node = Validator::new(DockerImage::new( matches.value_of("registry_name").unwrap().to_string(), - ValidatorType::Standard, + ValidatorType::RPC, matches.value_of("image_name").unwrap().to_string(), matches .value_of("image_tag") @@ -579,12 +579,12 @@ async fn main() { )); if build_config.docker_build() { - let validators = vec![&bootstrap_validator, &validator]; + let validators = vec![&bootstrap_validator, &validator, &rpc_node]; for v in &validators { match docker.build_image(solana_root.get_root_path(), v.image()) { Ok(_) => info!("{} image built successfully", v.validator_type()), Err(err) => { - error!("Exiting........ {err}"); + error!("Failed to build docker image {err}"); return; } } @@ -594,7 +594,7 @@ async fn main() { match DockerConfig::push_image(v.image()) { Ok(_) => info!("{} image pushed successfully", v.validator_type()), Err(err) => { - error!("Exiting........ {err}"); + error!("Failed to push docker image {err}"); return; } } diff --git a/src/scripts/rpc-startup-script.sh b/src/scripts/rpc-node-startup-script.sh similarity index 100% rename from src/scripts/rpc-startup-script.sh rename to src/scripts/rpc-node-startup-script.sh From f83ef38ac2eafb14b6aab19d54121a58cb6bd932 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Apr 2024 23:42:38 +0000 Subject: [PATCH 39/49] add selectors for rpc --- src/main.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main.rs b/src/main.rs index 326168e..a4ad89e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -755,6 +755,34 @@ async fn main() { return; } } + let identity_path = + config_directory.join(format!("rpc-node-identity-{rpc_index}.json")); + let rpc_keypair = + read_keypair_file(identity_path).expect("Failed to read rpc-node keypair file"); + + rpc_node.add_label( + "rpc-node/name", + &format!("rpc-node-{rpc_index}"), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "rpc-node/type", + rpc_node.validator_type().to_string(), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "rpc-node/identity", + rpc_keypair.pubkey().to_string(), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "load-balancer/name", + "load-balancer-selector", + LabelType::ValidatorReplicaSet, + ); } } From 957dee937ba71d951817761e3de5f3f0336fe4de Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 00:06:54 +0000 Subject: [PATCH 40/49] wip. need to deploy services as well. cant rpc can't contact other nodes. --- src/k8s_helpers.rs | 6 ++- src/kubernetes.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 26 ++++++++++++- 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/src/k8s_helpers.rs b/src/k8s_helpers.rs index 9d9af58..ccd5716 100644 --- a/src/k8s_helpers.rs +++ b/src/k8s_helpers.rs @@ -5,8 +5,8 @@ use { apps::v1::{ReplicaSet, ReplicaSetSpec}, core::v1::{ Container, EnvVar, EnvVarSource, ObjectFieldSelector, PodSecurityContext, PodSpec, - PodTemplateSpec, ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, - Volume, VolumeMount, + PodTemplateSpec, Probe, ResourceRequirements, Secret, Service, ServicePort, + ServiceSpec, Volume, VolumeMount, }, }, apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, @@ -52,6 +52,7 @@ pub fn create_replica_set( volumes: Option>, volume_mounts: Option>, pod_requests: BTreeMap, + readiness_probe: Option, ) -> Result> { let pod_spec = PodTemplateSpec { metadata: Some(ObjectMeta { @@ -66,6 +67,7 @@ pub fn create_replica_set( env: Some(environment_variables), command: Some(command.to_owned()), volume_mounts, + readiness_probe, resources: Some(ResourceRequirements { requests: Some(pod_requests), ..Default::default() diff --git a/src/kubernetes.rs b/src/kubernetes.rs index 093c453..bdcc373 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -6,8 +6,8 @@ use { api::{ apps::v1::ReplicaSet, core::v1::{ - EnvVar, EnvVarSource, Namespace, ObjectFieldSelector, Secret, SecretKeySelector, - SecretVolumeSource, Service, Volume, VolumeMount, + EnvVar, EnvVarSource, ExecAction, Namespace, ObjectFieldSelector, Probe, Secret, + SecretKeySelector, SecretVolumeSource, Service, Volume, VolumeMount, }, }, apimachinery::pkg::api::resource::Quantity, @@ -198,6 +198,7 @@ impl<'a> Kubernetes<'a> { accounts_volume, accounts_volume_mount, self.pod_requests.requests.clone(), + None, ) } @@ -235,6 +236,19 @@ impl<'a> Kubernetes<'a> { flags } + fn generate_rpc_command_flags(&self) -> Vec { + let mut flags: Vec = Vec::new(); + self.generate_command_flags(&mut flags); + if let Some(shred_version) = self.validator_config.shred_version { + flags.push("--expected-shred-version".to_string()); + flags.push(shred_version.to_string()); + } + + self.add_known_validators_if_exists(&mut flags); + + flags + } + pub async fn deploy_replicas_set( &self, replica_set: &ReplicaSet, @@ -451,6 +465,7 @@ impl<'a> Kubernetes<'a> { accounts_volume, accounts_volume_mount, self.pod_requests.requests.clone(), + None, ) } @@ -479,4 +494,79 @@ impl<'a> Kubernetes<'a> { k8s_helpers::create_secret_from_files(&secret_name, &key_files) } + + pub fn create_rpc_replica_set( + &mut self, + image: &DockerImage, + secret_name: Option, + label_selector: &BTreeMap, + rpc_index: usize, + ) -> Result> { + let mut env_vars = vec![EnvVar { + name: "MY_POD_IP".to_string(), + value_from: Some(EnvVarSource { + field_ref: Some(ObjectFieldSelector { + field_path: "status.podIP".to_string(), + ..Default::default() + }), + ..Default::default() + }), + ..Default::default() + }]; + env_vars.append(&mut self.set_non_bootstrap_environment_variables()); + env_vars.append(&mut self.set_load_balancer_environment_variables()); + + if self.metrics.is_some() { + env_vars.push(self.get_metrics_env_var_secret()) + } + + let accounts_volume = Some(vec![Volume { + name: format!("rpc-node-accounts-volume-{}", rpc_index), + secret: Some(SecretVolumeSource { + secret_name, + ..Default::default() + }), + ..Default::default() + }]); + + let accounts_volume_mount = Some(vec![VolumeMount { + name: format!("rpc-node-accounts-volume-{}", rpc_index), + mount_path: "/home/solana/rpc-node-accounts".to_string(), + ..Default::default() + }]); + + let mut command = + vec!["/home/solana/k8s-cluster-scripts/rpc-node-startup-script.sh".to_string()]; + command.extend(self.generate_rpc_command_flags()); + + let exec_action = ExecAction { + command: Some(vec![ + String::from("/bin/bash"), + String::from("-c"), + String::from( + "solana -u http://$MY_POD_IP:8899 balance -k rpc-node-accounts/identity.json", + ), + ]), + }; + + let readiness_probe = Probe { + exec: Some(exec_action), + initial_delay_seconds: Some(20), + period_seconds: Some(20), + ..Default::default() + }; + + k8s_helpers::create_replica_set( + &format!("{}-{rpc_index}", ValidatorType::RPC), + self.namespace.as_str(), + label_selector, + image, + env_vars, + &command, + accounts_volume, + accounts_volume_mount, + self.pod_requests.requests.clone(), + Some(readiness_probe), + ) + } } diff --git a/src/main.rs b/src/main.rs index a4ad89e..bd3bf17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -783,6 +783,31 @@ async fn main() { "load-balancer-selector", LabelType::ValidatorReplicaSet, ); + + let rpc_replica_set = match kub_controller.create_rpc_replica_set( + rpc_node.image(), + rpc_node.secret().metadata.name.clone(), + rpc_node.replica_set_labels(), + rpc_index, + ) { + Ok(replica_set) => replica_set, + Err(err) => { + error!("Error creating rpc node replicas_set: {err}"); + return; + } + }; + + // deploy rpc node replica set + let _ = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { + Ok(rs) => { + info!("non voting validator replica set ({rpc_index}) deployed successfully"); + rs.metadata.name.unwrap() + } + Err(err) => { + error!("Error! Failed to deploy non voting validator replica set: {rpc_index}. err: {err}"); + return; + } + }; } } @@ -854,7 +879,6 @@ async fn main() { } }; - // let service_name = format!("validator-service-{index}"); let validator_service = kub_controller.create_validator_service( &format!("validator-service-{validator_index}"), validator.replica_set_labels(), From 104ebc04595e1ebf07764c82f2837c0b3b32261a Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 13:45:11 +0000 Subject: [PATCH 41/49] working. bug in rpc stasrtup script --- src/main.rs | 20 ++++++++++++--- src/scripts/rpc-node-startup-script.sh | 35 +++++++++++++++++--------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index bd3bf17..9c31657 100644 --- a/src/main.rs +++ b/src/main.rs @@ -732,10 +732,7 @@ async fn main() { Err(err) => panic!("Error occurred while checking replica set readiness: {err}"), } } { - info!( - "replica set: {} not ready...", - bootstrap_validator.replica_set_name() - ); + info!("{} not ready...", bootstrap_validator.replica_set_name()); thread::sleep(Duration::from_secs(1)); } @@ -808,6 +805,21 @@ async fn main() { return; } }; + + rpc_node.add_label( + "service/name", + &format!("rpc-node-selector-{rpc_index}"), + LabelType::ValidatorService, + ); + + let rpc_service = kub_controller.create_validator_service( + format!("rpc-node-selector-{rpc_index}").as_str(), + rpc_node.service_labels(), + ); + match kub_controller.deploy_service(&rpc_service).await { + Ok(_) => info!("rpc node service deployed successfully"), + Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), + } } } diff --git a/src/scripts/rpc-node-startup-script.sh b/src/scripts/rpc-node-startup-script.sh index 2bddcd0..7cde965 100755 --- a/src/scripts/rpc-node-startup-script.sh +++ b/src/scripts/rpc-node-startup-script.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -nohup solana-faucet --keypair non-voting-validator-accounts/faucet.json & +nohup solana-faucet --keypair rpc-node-accounts/faucet.json & # Start Validator # shellcheck disable=SC1091 @@ -15,13 +15,33 @@ args=( ) airdrops_enabled=1 node_sol=500 # 500 SOL: number of SOL to airdrop the node for transaction fees and vote account rent exemption (ignored if airdrops_enabled=0) -identity=non-voting-validator-accounts/identity.json +identity=rpc-node-accounts/identity.json no_restart=0 gossip_entrypoint=$BOOTSTRAP_GOSSIP_ADDRESS ledger_dir=/home/solana/ledger # faucet_address=$BOOTSTRAP_FAUCET_ADDRESS faucet_address=$LOAD_BALANCER_FAUCET_ADDRESS + +# Define the paths to the validator cli. pre 1.18 is `solana-validator`. post 1.18 is `agave-validator` +agave_validator="/home/solana/.cargo/bin/agave-validator" +solana_validator="/home/solana/.cargo/bin/solana-validator" + +# Initialize program variable +program="" + +# Check if agave-validator exists and is executable +if [[ -x "$agave_validator" ]]; then + program="agave-validator" +elif [[ -x "$solana_validator" ]]; then + program="solana-validator" +else + echo "Neither agave-validator nor solana-validator could be found or is not executable." + exit 1 +fi + +echo "program: $program" + usage() { if [[ -n $1 ]]; then echo "$*" @@ -230,15 +250,6 @@ default_arg --allow-private-addr default_arg --gossip-port 8001 default_arg --rpc-port 8899 -program= -if [[ -n $SOLANA_CUDA ]]; then - program="agave-validator --cuda" -else - program="agave-validator" -fi - -echo "program: $program" - # set -e PS4="$(basename "$0"): " echo "PS4: $PS4" @@ -284,7 +295,7 @@ while true; do while true; do if [[ -z $pid ]] || ! kill -0 "$pid"; then - echo "############## non voting validator exited, restarting ##############" + echo "############## rpc node exited, restarting ##############" break fi sleep 1 From 553ee0e71434c1175db44e5ba4a87c910e56ce2d Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 14:50:04 +0000 Subject: [PATCH 42/49] wait for >= 1 rpc node to deploy before launching validators --- PROGRESS.md | 8 ++++---- src/kubernetes.rs | 9 +++------ src/main.rs | 45 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 5a5c7d9..468c54f 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -28,24 +28,24 @@ - [ ] Create & Deploy Selector - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [ ] Create & Deploy Replica Set - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [ ] Create & Deploy Services - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [x] Check Bootstrap is deployed and running - [x] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes) - [ ] Add metrics - [x] Bootstrap - [x] Validator (regular) - - [ ] RPC nodes + - [x] RPC nodes - [ ] Client - [ ] Create accounts - [x] Validator (regular) diff --git a/src/kubernetes.rs b/src/kubernetes.rs index bdcc373..887621d 100644 --- a/src/kubernetes.rs +++ b/src/kubernetes.rs @@ -370,24 +370,21 @@ impl<'a> Kubernetes<'a> { k8s_helpers::create_environment_variable( "LOAD_BALANCER_RPC_ADDRESS", Some( - "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:8899" - .to_string(), + "bootstrap-and-rpc-lb-service.$(NAMESPACE).svc.cluster.local:8899".to_string(), ), None, ), k8s_helpers::create_environment_variable( "LOAD_BALANCER_GOSSIP_ADDRESS", Some( - "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:8001" - .to_string(), + "bootstrap-and-rpc-lb-service.$(NAMESPACE).svc.cluster.local:8001".to_string(), ), None, ), k8s_helpers::create_environment_variable( "LOAD_BALANCER_FAUCET_ADDRESS", Some( - "bootstrap-and-non-voting-lb-service.$(NAMESPACE).svc.cluster.local:9900" - .to_string(), + "bootstrap-and-rpc-lb-service.$(NAMESPACE).svc.cluster.local:9900".to_string(), ), None, ), diff --git a/src/main.rs b/src/main.rs index 9c31657..933e7a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -523,7 +523,7 @@ async fn main() { match genesis.generate_accounts(ValidatorType::RPC, num_rpc_nodes) { Ok(_) => (), Err(err) => { - error!("generate non voting accounts error! {err}"); + error!("generate rpc accounts error! {err}"); return; } } @@ -711,10 +711,8 @@ async fn main() { let load_balancer_label = kub_controller.create_selector("load-balancer/name", "load-balancer-selector"); //create load balancer - let load_balancer = kub_controller.create_validator_load_balancer( - "bootstrap-and-non-voting-lb-service", - &load_balancer_label, - ); + let load_balancer = kub_controller + .create_validator_load_balancer("bootstrap-and-rpc-lb-service", &load_balancer_label); //deploy load balancer match kub_controller.deploy_service(&load_balancer).await { @@ -737,6 +735,7 @@ async fn main() { } if num_rpc_nodes > 0 { + let mut rpc_nodes = vec![]; for rpc_index in 0..num_rpc_nodes { match kub_controller.create_rpc_secret(rpc_index, &config_directory) { Ok(secret) => rpc_node.set_secret(secret), @@ -795,16 +794,17 @@ async fn main() { }; // deploy rpc node replica set - let _ = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { + let rpc_node_name = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { Ok(rs) => { - info!("non voting validator replica set ({rpc_index}) deployed successfully"); + info!("rpc node replica set ({rpc_index}) deployed successfully"); rs.metadata.name.unwrap() } Err(err) => { - error!("Error! Failed to deploy non voting validator replica set: {rpc_index}. err: {err}"); + error!("Error! Failed to deploy rpc node replica set: {rpc_index}. err: {err}"); return; } }; + rpc_nodes.push(rpc_node_name); rpc_node.add_label( "service/name", @@ -821,6 +821,35 @@ async fn main() { Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), } } + + // wait for at least one rpc node to deploy + loop { + let mut one_rpc_node_ready = false; + for rpc_node in &rpc_nodes { + match kub_controller + .check_replica_set_ready(rpc_node.as_str()) + .await + { + Ok(ready) => { + if ready { + one_rpc_node_ready = true; + break; + } + } // Continue the loop if replica set is not ready: Ok(false) + Err(err) => panic!( + "Error occurred while checking rpc node replica set readiness: {err}" + ), + } + } + + if one_rpc_node_ready { + break; + } + + info!("no rpc replica sets ready yet"); + thread::sleep(Duration::from_secs(10)); + } + info!(">= 1 rpc node ready"); } // Create and deploy validators secrets/selectors From 47aefa9d74ce87f52ba177af2b2b0e748f43af36 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 16:35:37 +0000 Subject: [PATCH 43/49] add in create client accounts --- Cargo.lock | 2 + Cargo.toml | 2 + PROGRESS.md | 2 +- src/client_config.rs | 4 ++ src/genesis.rs | 101 ++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 2 + src/main.rs | 37 +++++++++++++++- 7 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 src/client_config.rs diff --git a/Cargo.lock b/Cargo.lock index 98c5bd7..038b2c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7123,6 +7123,7 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" name = "validator-lab" version = "0.0.1" dependencies = [ + "anyhow", "bzip2", "clap 3.2.25", "console", @@ -7132,6 +7133,7 @@ dependencies = [ "kube", "log", "rand 0.8.5", + "rayon", "reqwest", "rustc_version", "rustls", diff --git a/Cargo.toml b/Cargo.toml index f649bbc..c5e032d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ license = "Apache-2.0" edition = "2021" [dependencies] +anyhow = "1.0.80" bzip2 = "0.4.4" clap = { version = "3.2.22", features = ["cargo"] } console = "0.15.8" @@ -17,6 +18,7 @@ k8s-openapi ={ version = "0.20.0", features = ["v1_28"] } kube = "0.87.2" log = "0.4.21" rand = "0.8.5" +rayon = "1.9.0" reqwest = { version = "0.11.23", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] } rustls = { version = "0.21.10", default-features = false, features = ["quic"] } solana-accounts-db = "1.18.8" diff --git a/PROGRESS.md b/PROGRESS.md index 468c54f..48665eb 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -50,7 +50,7 @@ - [ ] Create accounts - [x] Validator (regular) - [x] RPC - - [ ] Client + - [x] Client - [ ] Add feature flags to configure: - [ ] Bootstrap - [ ] Validator (regular) diff --git a/src/client_config.rs b/src/client_config.rs new file mode 100644 index 0000000..a4d206e --- /dev/null +++ b/src/client_config.rs @@ -0,0 +1,4 @@ +#[derive(Clone, Debug)] +pub struct ClientConfig { + pub num_clients: usize, +} diff --git a/src/genesis.rs b/src/genesis.rs index 03c47da..0b6ac34 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -1,13 +1,22 @@ use { - crate::{new_spinner_progress_bar, ValidatorType, SUN}, + crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, SUN, WRITING}, + anyhow::Error as AnyHowError, log::*, rand::Rng, + rayon::prelude::*, solana_core::gen_keys::GenKeys, solana_sdk::{ native_token::sol_to_lamports, signature::{write_keypair_file, Keypair}, }, - std::{error::Error, fs::File, io::Read, path::PathBuf, process::Command, result::Result}, + std::{ + error::Error, + fs::{File, OpenOptions}, + io::{self, BufRead, BufWriter, Read, Write}, + path::PathBuf, + process::Command, + result::Result, + }, }; pub const DEFAULT_FAUCET_LAMPORTS: u64 = 500000000000000000; // from agave/ @@ -16,6 +25,7 @@ pub const DEFAULT_INTERNAL_NODE_STAKE_SOL: f64 = 10.0; pub const DEFAULT_INTERNAL_NODE_SOL: f64 = 100.0; pub const DEFAULT_BOOTSTRAP_NODE_STAKE_SOL: f64 = 10.0; pub const DEFAULT_BOOTSTRAP_NODE_SOL: f64 = 100.0; +pub const DEFAULT_CLIENT_LAMPORTS_PER_SIGNATURE: u64 = 42; fn fetch_spl(fetch_spl_file: &PathBuf) -> Result<(), Box> { let output = Command::new("bash") @@ -63,6 +73,34 @@ fn parse_spl_genesis_file(spl_file: &PathBuf) -> Result, Box io::Result<()> { + // Open the bench-tps-i.yml file for reading. + let input = File::open(in_file)?; + let reader = io::BufReader::new(input); + + // Open (or create) client-accounts.yml + let output = OpenOptions::new() + .create(true) + .append(true) + .open(out_file)?; + let mut writer = BufWriter::new(output); + + // Enumerate the lines of the input file, starting from 1. + for (index, line) in reader.lines().enumerate().map(|(i, l)| (i + 1, l)) { + let line = line?; + + // Skip first line since it is a header aka "---" in a yaml + if (index as u64) > 1 { + writeln!(writer, "{line}")?; + } + } + + Ok(()) +} + pub struct GenesisFlags { pub hashes_per_tick: String, pub slots_per_epoch: Option, @@ -312,4 +350,63 @@ impl Genesis { Ok(()) } + + pub fn create_client_accounts( + &mut self, + number_of_clients: usize, + target_lamports_per_signature: u64, + config_dir: &PathBuf, + deploy_method: &DeployMethod, + solana_root_path: &PathBuf, + ) -> Result<(), Box> { + let client_accounts_file = config_dir.join("client-accounts.yml"); + + info!("generating {number_of_clients} client accounts..."); + let _ = (0..number_of_clients).into_par_iter().try_for_each(|i| { + info!("client account: {i}"); + let mut args = Vec::new(); + let account_path = config_dir.join(format!("bench-tps-{i}.yml")); + args.push("--write-client-keys".to_string()); + args.push(account_path.to_string_lossy().to_string()); + args.push("--target-lamports-per-signature".to_string()); + args.push(target_lamports_per_signature.to_string()); + + let executable_path = if let DeployMethod::ReleaseChannel(_) = deploy_method { + solana_root_path.join("solana-release/bin/solana-bench-tps") + } else { + solana_root_path.join("farf/bin/solana-bench-tps") + }; + + Self::create_client_account(&args, &executable_path) + }); + + let progress_bar = new_spinner_progress_bar(); + progress_bar.set_message(format!("{WRITING}Writing client accounts...")); + for i in 0..number_of_clients { + let account_path = config_dir.join(format!("bench-tps-{i}.yml")); + append_client_accounts_to_file(&account_path, &client_accounts_file)?; + } + progress_bar.finish_and_clear(); + info!("client-accounts.yml creation for genesis complete"); + + Ok(()) + } + + fn create_client_account( + args: &Vec, + executable_path: &PathBuf, + ) -> Result<(), AnyHowError> { + let output = Command::new(executable_path) + .args(args) + .output() + .expect("Failed to execute solana-bench-tps"); + + if !output.status.success() { + return Err(AnyHowError::msg(format!( + "Failed to create client accounts. err: {}", + String::from_utf8_lossy(&output.stderr) + ))); + } + Ok(()) + } } diff --git a/src/lib.rs b/src/lib.rs index 234898f..f7f8bdc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,6 +93,7 @@ impl Metrics { } } +pub mod client_config; pub mod docker; pub mod genesis; pub mod k8s_helpers; @@ -107,6 +108,7 @@ static PACKAGE: Emoji = Emoji("📦 ", ""); static ROCKET: Emoji = Emoji("🚀 ", ""); static SUN: Emoji = Emoji("🌞 ", ""); static TRUCK: Emoji = Emoji("🚚 ", ""); +static WRITING: Emoji = Emoji("🖊️ ", ""); /// Creates a new process bar for processing that will take an unknown amount of time pub fn new_spinner_progress_bar() -> ProgressBar { diff --git a/src/main.rs b/src/main.rs index 933e7a4..802c0f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,9 +8,11 @@ use { std::{fs, thread, time::Duration}, strum::VariantNames, validator_lab::{ + client_config::ClientConfig, docker::{DockerConfig, DockerImage}, genesis::{ - Genesis, GenesisFlags, DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL, + Genesis, GenesisFlags, DEFAULT_CLIENT_LAMPORTS_PER_SIGNATURE, + DEFAULT_INTERNAL_NODE_SOL, DEFAULT_INTERNAL_NODE_STAKE_SOL, }, kubernetes::{Kubernetes, PodRequests}, ledger_helper::LedgerHelper, @@ -237,6 +239,19 @@ fn parse_matches() -> clap::ArgMatches { _ => Err(String::from("number_of_rpc_nodes should be >= 0")), }), ) + // Client Configurations + .arg( + Arg::with_name("number_of_clients") + .long("num-clients") + .short('c') + .takes_value(true) + .default_value("0") + .help("Number of clients ") + .validator(|s| match s.parse::() { + Ok(n) if n >= 0 => Ok(()), + _ => Err(String::from("number_of_clients should be >= 0")), + }), + ) // kubernetes config .arg( Arg::with_name("cpu_requests") @@ -309,6 +324,9 @@ async fn main() { let num_validators = value_t_or_exit!(matches, "number_of_validators", usize); let num_rpc_nodes = value_t_or_exit!(matches, "number_of_rpc_nodes", usize); + let client_config = ClientConfig { + num_clients: value_t_or_exit!(matches, "number_of_clients", usize), + }; let deploy_method = if let Some(local_path) = matches.value_of("local_path") { DeployMethod::Local(local_path.to_owned()) @@ -503,6 +521,23 @@ async fn main() { } } + // only create client accounts once + if client_config.num_clients > 0 { + match genesis.create_client_accounts( + client_config.num_clients, + DEFAULT_CLIENT_LAMPORTS_PER_SIGNATURE, + &config_directory, + &deploy_method, + &solana_root.get_root_path(), + ) { + Ok(_) => info!("Client accounts created successfully"), + Err(err) => { + error!("generate client accounts error! {err}"); + return; + } + } + } + // creates genesis and writes to binary file match genesis.generate(solana_root.get_root_path(), build_config.build_path()) { Ok(_) => (), From dc54636ad3aa3b7e70226065714d606c87f3aced Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 18:34:52 +0000 Subject: [PATCH 44/49] wip. getting client-accounts into genesis and bootstrap --- src/docker.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/genesis.rs | 12 +++++++- src/main.rs | 2 +- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/docker.rs b/src/docker.rs index ab0b6af..095a432 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -65,7 +65,7 @@ impl DockerConfig { pub fn build_image( &self, - solana_root_path: PathBuf, + solana_root_path: &PathBuf, docker_image: &DockerImage, ) -> Result<(), Box> { let validator_type = docker_image.validator_type(); @@ -85,19 +85,45 @@ impl DockerConfig { &docker_image, docker_path, &validator_type, + None, )?; Ok(()) } + pub fn build_client_images( + &self, + solana_root_path: &PathBuf, + docker_image: &DockerImage, + client_count: i32, + ) -> Result<(), Box> { + for i in 0..client_count { + let docker_path = solana_root_path.join(format!( + "docker-build/{}-{}", + docker_image.validator_type(), + i + )); + self.create_base_image( + solana_root_path, + docker_image, + docker_path, + &ValidatorType::Client, + Some(i), + )? + } + Ok(()) + } + fn create_base_image( &self, - solana_root_path: PathBuf, + solana_root_path: &PathBuf, docker_image: &DockerImage, docker_path: PathBuf, validator_type: &ValidatorType, + index: Option, ) -> Result<(), Box> { - let dockerfile_path = self.create_dockerfile(validator_type, docker_path, None)?; + let dockerfile_path = + self.create_dockerfile(validator_type, docker_path, solana_root_path, None, index)?; // We use std::process::Command here because Docker-rs is very slow building dockerfiles // when they are in large repos. Docker-rs doesn't seem to support the `--file` flag natively. @@ -146,7 +172,9 @@ impl DockerConfig { &self, validator_type: &ValidatorType, docker_path: PathBuf, + solana_root_path: &PathBuf, content: Option<&str>, + index: Option, ) -> Result> { if docker_path.exists() { fs::remove_dir_all(&docker_path)?; @@ -204,6 +232,11 @@ WORKDIR /home/solana self.base_image ); + let dockerfile = format!( + "{dockerfile}\n{}", + self.insert_client_accounts_if_present(solana_root_path, index) + ); + debug!("dockerfile: {}", dockerfile); std::fs::write( docker_path.join("Dockerfile"), @@ -212,6 +245,49 @@ WORKDIR /home/solana Ok(docker_path) } + // TODO: don't think validator and rpcs need client-accounts.yml. think only bootstrap + fn insert_client_accounts_if_present( + &self, + solana_root_path: &PathBuf, + index: Option, + ) -> String { + match index { + Some(i) => { + // client image + if solana_root_path + .join(format!("config-k8s/bench-tps-{i}.yml")) + .exists() + { + info!("some (i)"); + format!( + r#" + COPY --chown=solana:solana ./config-k8s/bench-tps-{i}.yml /home/solana/client-accounts.yml + "#, + ) + } else { + info!("some(i). but path doesn't exist"); + "".to_string() + } + } + None => { + // bootstrap image + if solana_root_path + .join("config-k8s/client-accounts.yml") + .exists() + { + info!("index is None. path exists"); + r#" + COPY --chown=solana:solana ./config-k8s/client-accounts.yml /home/solana + "# + .to_string() + } else { + info!("index is none. path doesn't exist"); + "".to_string() + } + } + } + } + pub fn push_image(docker_image: &DockerImage) -> Result<(), Box> { let progress_bar = new_spinner_progress_bar(); progress_bar.set_message(format!( diff --git a/src/genesis.rs b/src/genesis.rs index 0b6ac34..9fa7c4b 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -307,6 +307,16 @@ impl Genesis { args.push(lamports_per_signature.to_string()); } + if self.config_dir.join("client-accounts.yml").exists() { + args.push("--primordial-accounts-file".to_string()); + args.push( + self.config_dir + .join("client-accounts.yml") + .to_string_lossy() + .to_string(), + ); + } + args } @@ -361,7 +371,7 @@ impl Genesis { ) -> Result<(), Box> { let client_accounts_file = config_dir.join("client-accounts.yml"); - info!("generating {number_of_clients} client accounts..."); + info!("generating {number_of_clients} client account(s)..."); let _ = (0..number_of_clients).into_par_iter().try_for_each(|i| { info!("client account: {i}"); let mut args = Vec::new(); diff --git a/src/main.rs b/src/main.rs index 802c0f3..1c931ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -616,7 +616,7 @@ async fn main() { if build_config.docker_build() { let validators = vec![&bootstrap_validator, &validator, &rpc_node]; for v in &validators { - match docker.build_image(solana_root.get_root_path(), v.image()) { + match docker.build_image(&solana_root.get_root_path(), v.image()) { Ok(_) => info!("{} image built successfully", v.validator_type()), Err(err) => { error!("Failed to build docker image {err}"); From 121cea9ef4cccfde93e9117a679b700b21863eb1 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Apr 2024 19:04:01 +0000 Subject: [PATCH 45/49] wip. need new client image for each client. has to have client data data for each client in each docker iamge --- src/docker.rs | 28 +++++++++++++++++++++++----- src/main.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/docker.rs b/src/docker.rs index 095a432..5d44a18 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,6 +1,7 @@ use { crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD, ROCKET}, log::*, + rayon::prelude::*, std::{ env, error::Error, @@ -95,7 +96,7 @@ impl DockerConfig { &self, solana_root_path: &PathBuf, docker_image: &DockerImage, - client_count: i32, + client_count: usize, ) -> Result<(), Box> { for i in 0..client_count { let docker_path = solana_root_path.join(format!( @@ -120,7 +121,7 @@ impl DockerConfig { docker_image: &DockerImage, docker_path: PathBuf, validator_type: &ValidatorType, - index: Option, + index: Option, ) -> Result<(), Box> { let dockerfile_path = self.create_dockerfile(validator_type, docker_path, solana_root_path, None, index)?; @@ -174,7 +175,7 @@ impl DockerConfig { docker_path: PathBuf, solana_root_path: &PathBuf, content: Option<&str>, - index: Option, + index: Option, ) -> Result> { if docker_path.exists() { fs::remove_dir_all(&docker_path)?; @@ -249,7 +250,7 @@ WORKDIR /home/solana fn insert_client_accounts_if_present( &self, solana_root_path: &PathBuf, - index: Option, + index: Option, ) -> String { match index { Some(i) => { @@ -294,7 +295,7 @@ WORKDIR /home/solana "{ROCKET}Pushing {} image to registry...", docker_image.validator_type() )); - let command = format!("docker push '{}'", docker_image); + let command = format!("docker push '{docker_image}'"); let output = match Command::new("sh") .arg("-c") .arg(&command) @@ -314,4 +315,21 @@ WORKDIR /home/solana progress_bar.finish_and_clear(); Ok(()) } + + // need a new image for each client + pub fn push_client_images(&self, num_clients: i32) -> Result<(), Box> { + info!("Pushing client images..."); + (0..num_clients).into_par_iter().try_for_each(|i| { + let image = format!( + "{}/{}-{}-{}:{}", + self.image_config.registry, + ValidatorType::Client, + "image", + i, + self.image_config.tag + ); + + Self::push_image(image, format!("client-{}", i).as_str()) + }) + } } diff --git a/src/main.rs b/src/main.rs index 1c931ab..ae82539 100644 --- a/src/main.rs +++ b/src/main.rs @@ -613,6 +613,18 @@ async fn main() { .to_string(), )); + //TODO do not parse four times + // we need a new image for each client!!! + let mut client = Validator::new(DockerImage::new( + matches.value_of("registry_name").unwrap().to_string(), + ValidatorType::Client, + matches.value_of("image_name").unwrap().to_string(), + matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(), + )); + if build_config.docker_build() { let validators = vec![&bootstrap_validator, &validator, &rpc_node]; for v in &validators { @@ -634,6 +646,25 @@ async fn main() { } } } + + if client_config.num_clients > 0 { + // need new image for each client + match docker.build_client_images(&solana_root.get_root_path(), &client.image(), client_config.num_clients) { + Ok(_) => info!("Client image built successfully"), + Err(err) => { + error!("Failed to build client image {err}"); + return; + } + } + + match docker.push_client_images(client_config.num_clients) { + Ok(_) => info!("Client image pushed successfully"), + Err(err) => { + error!("Exiting........ {}", err); + return; + } + } + } } // metrics secret create once and use by all pods From 23242bdc1f898f6a8c7bbdd1d7757c6cf2aed99d Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 8 Apr 2024 18:34:30 +0000 Subject: [PATCH 46/49] wip. need to build client docker image --- src/docker.rs | 61 ++++++++++++++++++++++++--------------------------- src/main.rs | 40 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/docker.rs b/src/docker.rs index 5d44a18..c022417 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -92,26 +92,23 @@ impl DockerConfig { Ok(()) } - pub fn build_client_images( + pub fn build_client_image( &self, solana_root_path: &PathBuf, docker_image: &DockerImage, - client_count: usize, + client_index: usize, ) -> Result<(), Box> { - for i in 0..client_count { - let docker_path = solana_root_path.join(format!( - "docker-build/{}-{}", - docker_image.validator_type(), - i - )); - self.create_base_image( - solana_root_path, - docker_image, - docker_path, - &ValidatorType::Client, - Some(i), - )? - } + let docker_path = solana_root_path.join(format!( + "docker-build/{}-{client_index}", + docker_image.validator_type(), + )); + self.create_base_image( + solana_root_path, + docker_image, + docker_path, + &ValidatorType::Client, + Some(client_index), + )?; Ok(()) } @@ -316,20 +313,20 @@ WORKDIR /home/solana Ok(()) } - // need a new image for each client - pub fn push_client_images(&self, num_clients: i32) -> Result<(), Box> { - info!("Pushing client images..."); - (0..num_clients).into_par_iter().try_for_each(|i| { - let image = format!( - "{}/{}-{}-{}:{}", - self.image_config.registry, - ValidatorType::Client, - "image", - i, - self.image_config.tag - ); - - Self::push_image(image, format!("client-{}", i).as_str()) - }) - } + // // need a new image for each client + // pub fn push_client_images(&self, num_clients: i32) -> Result<(), Box> { + // info!("Pushing client images..."); + // (0..num_clients).into_par_iter().try_for_each(|i| { + // let image = format!( + // "{}/{}-{}-{}:{}", + // self.image_config.registry, + // ValidatorType::Client, + // "image", + // i, + // self.image_config.tag + // ); + + // Self::push_image(image, format!("client-{}", i).as_str()) + // }) + // } } diff --git a/src/main.rs b/src/main.rs index ae82539..6c7e9c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -542,7 +542,7 @@ async fn main() { match genesis.generate(solana_root.get_root_path(), build_config.build_path()) { Ok(_) => (), Err(err) => { - error!("generate genesis error! {}", err); + error!("generate genesis error! {err}"); return; } } @@ -647,9 +647,10 @@ async fn main() { } } - if client_config.num_clients > 0 { + for client_index in 0..client_config.num_clients { + info!("here!"); // need new image for each client - match docker.build_client_images(&solana_root.get_root_path(), &client.image(), client_config.num_clients) { + match docker.build_client_image(&solana_root.get_root_path(), &client.image(), client_index) { Ok(_) => info!("Client image built successfully"), Err(err) => { error!("Failed to build client image {err}"); @@ -657,14 +658,33 @@ async fn main() { } } - match docker.push_client_images(client_config.num_clients) { - Ok(_) => info!("Client image pushed successfully"), - Err(err) => { - error!("Exiting........ {}", err); - return; - } - } + // match docker.push_client_images(client_config.num_clients) { + // Ok(_) => info!("Client image pushed successfully"), + // Err(err) => { + // error!("Exiting........ {}", err); + // return; + // } + // } } + + // if client_config.num_clients > 0 { + // // need new image for each client + // match docker.build_client_images(&solana_root.get_root_path(), &client.image(), client_config.num_clients) { + // Ok(_) => info!("Client image built successfully"), + // Err(err) => { + // error!("Failed to build client image {err}"); + // return; + // } + // } + + // match docker.push_client_images(client_config.num_clients) { + // Ok(_) => info!("Client image pushed successfully"), + // Err(err) => { + // error!("Exiting........ {}", err); + // return; + // } + // } + // } } // metrics secret create once and use by all pods From 0f444c60a27c6b1f3b846c19673544d6611e0030 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 8 Apr 2024 21:45:18 +0000 Subject: [PATCH 47/49] not copying client stuff in correctly in docker. wip --- src/docker.rs | 58 ++-- src/main.rs | 490 +++++++++++++-------------- src/scripts/client-startup-script.sh | 119 +++++++ 3 files changed, 397 insertions(+), 270 deletions(-) create mode 100644 src/scripts/client-startup-script.sh diff --git a/src/docker.rs b/src/docker.rs index c022417..41c58d1 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -92,26 +92,6 @@ impl DockerConfig { Ok(()) } - pub fn build_client_image( - &self, - solana_root_path: &PathBuf, - docker_image: &DockerImage, - client_index: usize, - ) -> Result<(), Box> { - let docker_path = solana_root_path.join(format!( - "docker-build/{}-{client_index}", - docker_image.validator_type(), - )); - self.create_base_image( - solana_root_path, - docker_image, - docker_path, - &ValidatorType::Client, - Some(client_index), - )?; - Ok(()) - } - fn create_base_image( &self, solana_root_path: &PathBuf, @@ -196,7 +176,15 @@ impl DockerConfig { if let DeployMethod::ReleaseChannel(_) = self.deploy_method { ("solana-release", "./src/scripts".to_string()) } else { - ("farf", format!("./docker-build/{validator_type}")) + if validator_type == &ValidatorType::Client { + if let Some(i) = index { + ("farf", format!("./docker-build/client-{i}")) + } else { + ("farf", format!("./docker-build/{validator_type}")) + } + } else { + ("farf", format!("./docker-build/{validator_type}")) + } }; let dockerfile = format!( @@ -251,10 +239,10 @@ WORKDIR /home/solana ) -> String { match index { Some(i) => { + let p = solana_root_path.join(format!("config-k8s/bench-tps-{i}.yml")); + let p_string = p.to_string_lossy().to_string(); // client image - if solana_root_path - .join(format!("config-k8s/bench-tps-{i}.yml")) - .exists() + if p.exists() { info!("some (i)"); format!( @@ -313,8 +301,28 @@ WORKDIR /home/solana Ok(()) } + pub fn build_client_image( + &self, + solana_root_path: &PathBuf, + docker_image: &DockerImage, + client_index: usize, + ) -> Result<(), Box> { + let docker_path = solana_root_path.join(format!( + "docker-build/{}-{client_index}", + docker_image.validator_type(), + )); + self.create_base_image( + solana_root_path, + docker_image, + docker_path, + &ValidatorType::Client, + Some(client_index), + )?; + Ok(()) + } + // // need a new image for each client - // pub fn push_client_images(&self, num_clients: i32) -> Result<(), Box> { + // pub fn push_client_images(&self, num_clients: i32, client_image: &DockerImage) -> Result<(), Box> { // info!("Pushing client images..."); // (0..num_clients).into_par_iter().try_for_each(|i| { // let image = format!( diff --git a/src/main.rs b/src/main.rs index 6c7e9c6..78d0a18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -591,27 +591,27 @@ async fn main() { .to_string(), )); - //TODO do not parse twice - let mut validator = Validator::new(DockerImage::new( - matches.value_of("registry_name").unwrap().to_string(), - ValidatorType::Standard, - matches.value_of("image_name").unwrap().to_string(), - matches - .value_of("image_tag") - .unwrap_or_default() - .to_string(), - )); - - //TODO do not parse thrice - let mut rpc_node = Validator::new(DockerImage::new( - matches.value_of("registry_name").unwrap().to_string(), - ValidatorType::RPC, - matches.value_of("image_name").unwrap().to_string(), - matches - .value_of("image_tag") - .unwrap_or_default() - .to_string(), - )); + // //TODO do not parse twice + // let mut validator = Validator::new(DockerImage::new( + // matches.value_of("registry_name").unwrap().to_string(), + // ValidatorType::Standard, + // matches.value_of("image_name").unwrap().to_string(), + // matches + // .value_of("image_tag") + // .unwrap_or_default() + // .to_string(), + // )); + + // //TODO do not parse thrice + // let mut rpc_node = Validator::new(DockerImage::new( + // matches.value_of("registry_name").unwrap().to_string(), + // ValidatorType::RPC, + // matches.value_of("image_name").unwrap().to_string(), + // matches + // .value_of("image_tag") + // .unwrap_or_default() + // .to_string(), + // )); //TODO do not parse four times // we need a new image for each client!!! @@ -626,26 +626,26 @@ async fn main() { )); if build_config.docker_build() { - let validators = vec![&bootstrap_validator, &validator, &rpc_node]; - for v in &validators { - match docker.build_image(&solana_root.get_root_path(), v.image()) { - Ok(_) => info!("{} image built successfully", v.validator_type()), - Err(err) => { - error!("Failed to build docker image {err}"); - return; - } - } - } + // let validators = vec![&bootstrap_validator];//, &validator, &rpc_node]; + // for v in &validators { + // match docker.build_image(&solana_root.get_root_path(), v.image()) { + // Ok(_) => info!("{} image built successfully", v.validator_type()), + // Err(err) => { + // error!("Failed to build docker image {err}"); + // return; + // } + // } + // } - for v in &validators { - match DockerConfig::push_image(v.image()) { - Ok(_) => info!("{} image pushed successfully", v.validator_type()), - Err(err) => { - error!("Failed to push docker image {err}"); - return; - } - } - } + // for v in &validators { + // match DockerConfig::push_image(v.image()) { + // Ok(_) => info!("{} image pushed successfully", v.validator_type()), + // Err(err) => { + // error!("Failed to push docker image {err}"); + // return; + // } + // } + // } for client_index in 0..client_config.num_clients { info!("here!"); @@ -657,16 +657,16 @@ async fn main() { return; } } - - // match docker.push_client_images(client_config.num_clients) { - // Ok(_) => info!("Client image pushed successfully"), - // Err(err) => { - // error!("Exiting........ {}", err); - // return; - // } - // } } + // match docker.push_client_images(client_config.num_clients, client.image()) { + // Ok(_) => info!("Client image pushed successfully"), + // Err(err) => { + // error!("Exiting........ {}", err); + // return; + // } + // } + // if client_config.num_clients > 0 { // // need new image for each client // match docker.build_client_images(&solana_root.get_root_path(), &client.image(), client_config.num_clients) { @@ -820,201 +820,201 @@ async fn main() { thread::sleep(Duration::from_secs(1)); } - if num_rpc_nodes > 0 { - let mut rpc_nodes = vec![]; - for rpc_index in 0..num_rpc_nodes { - match kub_controller.create_rpc_secret(rpc_index, &config_directory) { - Ok(secret) => rpc_node.set_secret(secret), - Err(err) => { - error!("Failed to create RPC node {rpc_index} secret! {err}"); - return; - } - } - match kub_controller.deploy_secret(&rpc_node.secret()).await { - Ok(_) => info!("Deployed RPC node {rpc_index} Secret"), - Err(err) => { - error!("{err}"); - return; - } - } - let identity_path = - config_directory.join(format!("rpc-node-identity-{rpc_index}.json")); - let rpc_keypair = - read_keypair_file(identity_path).expect("Failed to read rpc-node keypair file"); - - rpc_node.add_label( - "rpc-node/name", - &format!("rpc-node-{rpc_index}"), - LabelType::ValidatorReplicaSet, - ); - - rpc_node.add_label( - "rpc-node/type", - rpc_node.validator_type().to_string(), - LabelType::ValidatorReplicaSet, - ); - - rpc_node.add_label( - "rpc-node/identity", - rpc_keypair.pubkey().to_string(), - LabelType::ValidatorReplicaSet, - ); - - rpc_node.add_label( - "load-balancer/name", - "load-balancer-selector", - LabelType::ValidatorReplicaSet, - ); - - let rpc_replica_set = match kub_controller.create_rpc_replica_set( - rpc_node.image(), - rpc_node.secret().metadata.name.clone(), - rpc_node.replica_set_labels(), - rpc_index, - ) { - Ok(replica_set) => replica_set, - Err(err) => { - error!("Error creating rpc node replicas_set: {err}"); - return; - } - }; - - // deploy rpc node replica set - let rpc_node_name = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { - Ok(rs) => { - info!("rpc node replica set ({rpc_index}) deployed successfully"); - rs.metadata.name.unwrap() - } - Err(err) => { - error!("Error! Failed to deploy rpc node replica set: {rpc_index}. err: {err}"); - return; - } - }; - rpc_nodes.push(rpc_node_name); - - rpc_node.add_label( - "service/name", - &format!("rpc-node-selector-{rpc_index}"), - LabelType::ValidatorService, - ); - - let rpc_service = kub_controller.create_validator_service( - format!("rpc-node-selector-{rpc_index}").as_str(), - rpc_node.service_labels(), - ); - match kub_controller.deploy_service(&rpc_service).await { - Ok(_) => info!("rpc node service deployed successfully"), - Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), - } - } - - // wait for at least one rpc node to deploy - loop { - let mut one_rpc_node_ready = false; - for rpc_node in &rpc_nodes { - match kub_controller - .check_replica_set_ready(rpc_node.as_str()) - .await - { - Ok(ready) => { - if ready { - one_rpc_node_ready = true; - break; - } - } // Continue the loop if replica set is not ready: Ok(false) - Err(err) => panic!( - "Error occurred while checking rpc node replica set readiness: {err}" - ), - } - } - - if one_rpc_node_ready { - break; - } - - info!("no rpc replica sets ready yet"); - thread::sleep(Duration::from_secs(10)); - } - info!(">= 1 rpc node ready"); - } - - // Create and deploy validators secrets/selectors - for validator_index in 0..num_validators { - match kub_controller.create_validator_secret(validator_index, &config_directory) { - Ok(secret) => validator.set_secret(secret), - Err(err) => { - error!("Failed to create validator secret! {err}"); - return; - } - }; - - match kub_controller.deploy_secret(&validator.secret()).await { - Ok(_) => info!("Deployed validator {validator_index} secret"), - Err(err) => { - error!("{err}"); - return; - } - } - - let identity_path = - config_directory.join(format!("validator-identity-{validator_index}.json")); - let validator_keypair = - read_keypair_file(identity_path).expect("Failed to read validator keypair file"); - - validator.add_label( - "validator/name", - &format!("validator-{validator_index}"), - LabelType::ValidatorReplicaSet, - ); - validator.add_label( - "validator/type", - validator.validator_type().to_string(), - LabelType::ValidatorReplicaSet, - ); - validator.add_label( - "validator/identity", - validator_keypair.pubkey().to_string(), - LabelType::ValidatorReplicaSet, - ); - - let validator_replica_set = match kub_controller.create_validator_replica_set( - validator.image(), - validator.secret().metadata.name.clone(), - validator.replica_set_labels(), - validator_index, - ) { - Ok(replica_set) => replica_set, - Err(err) => { - error!("Error creating validator replicas_set: {err}"); - return; - } - }; - - let _ = match kub_controller - .deploy_replicas_set(&validator_replica_set) - .await - { - Ok(rs) => { - info!("validator replica set ({validator_index}) deployed successfully"); - rs.metadata.name.unwrap() - } - Err(err) => { - error!( - "Error! Failed to deploy validator replica set: {validator_index}. err: {err}" - ); - return; - } - }; - - let validator_service = kub_controller.create_validator_service( - &format!("validator-service-{validator_index}"), - validator.replica_set_labels(), - ); - match kub_controller.deploy_service(&validator_service).await { - Ok(_) => info!("validator service ({validator_index}) deployed successfully"), - Err(err) => { - error!("Error! Failed to deploy validator service: {validator_index}. err: {err}") - } - } - } + // if num_rpc_nodes > 0 { + // let mut rpc_nodes = vec![]; + // for rpc_index in 0..num_rpc_nodes { + // match kub_controller.create_rpc_secret(rpc_index, &config_directory) { + // Ok(secret) => rpc_node.set_secret(secret), + // Err(err) => { + // error!("Failed to create RPC node {rpc_index} secret! {err}"); + // return; + // } + // } + // match kub_controller.deploy_secret(&rpc_node.secret()).await { + // Ok(_) => info!("Deployed RPC node {rpc_index} Secret"), + // Err(err) => { + // error!("{err}"); + // return; + // } + // } + // let identity_path = + // config_directory.join(format!("rpc-node-identity-{rpc_index}.json")); + // let rpc_keypair = + // read_keypair_file(identity_path).expect("Failed to read rpc-node keypair file"); + + // rpc_node.add_label( + // "rpc-node/name", + // &format!("rpc-node-{rpc_index}"), + // LabelType::ValidatorReplicaSet, + // ); + + // rpc_node.add_label( + // "rpc-node/type", + // rpc_node.validator_type().to_string(), + // LabelType::ValidatorReplicaSet, + // ); + + // rpc_node.add_label( + // "rpc-node/identity", + // rpc_keypair.pubkey().to_string(), + // LabelType::ValidatorReplicaSet, + // ); + + // rpc_node.add_label( + // "load-balancer/name", + // "load-balancer-selector", + // LabelType::ValidatorReplicaSet, + // ); + + // let rpc_replica_set = match kub_controller.create_rpc_replica_set( + // rpc_node.image(), + // rpc_node.secret().metadata.name.clone(), + // rpc_node.replica_set_labels(), + // rpc_index, + // ) { + // Ok(replica_set) => replica_set, + // Err(err) => { + // error!("Error creating rpc node replicas_set: {err}"); + // return; + // } + // }; + + // // deploy rpc node replica set + // let rpc_node_name = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { + // Ok(rs) => { + // info!("rpc node replica set ({rpc_index}) deployed successfully"); + // rs.metadata.name.unwrap() + // } + // Err(err) => { + // error!("Error! Failed to deploy rpc node replica set: {rpc_index}. err: {err}"); + // return; + // } + // }; + // rpc_nodes.push(rpc_node_name); + + // rpc_node.add_label( + // "service/name", + // &format!("rpc-node-selector-{rpc_index}"), + // LabelType::ValidatorService, + // ); + + // let rpc_service = kub_controller.create_validator_service( + // format!("rpc-node-selector-{rpc_index}").as_str(), + // rpc_node.service_labels(), + // ); + // match kub_controller.deploy_service(&rpc_service).await { + // Ok(_) => info!("rpc node service deployed successfully"), + // Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), + // } + // } + + // // wait for at least one rpc node to deploy + // loop { + // let mut one_rpc_node_ready = false; + // for rpc_node in &rpc_nodes { + // match kub_controller + // .check_replica_set_ready(rpc_node.as_str()) + // .await + // { + // Ok(ready) => { + // if ready { + // one_rpc_node_ready = true; + // break; + // } + // } // Continue the loop if replica set is not ready: Ok(false) + // Err(err) => panic!( + // "Error occurred while checking rpc node replica set readiness: {err}" + // ), + // } + // } + + // if one_rpc_node_ready { + // break; + // } + + // info!("no rpc replica sets ready yet"); + // thread::sleep(Duration::from_secs(10)); + // } + // info!(">= 1 rpc node ready"); + // } + + // // Create and deploy validators secrets/selectors + // for validator_index in 0..num_validators { + // match kub_controller.create_validator_secret(validator_index, &config_directory) { + // Ok(secret) => validator.set_secret(secret), + // Err(err) => { + // error!("Failed to create validator secret! {err}"); + // return; + // } + // }; + + // match kub_controller.deploy_secret(&validator.secret()).await { + // Ok(_) => info!("Deployed validator {validator_index} secret"), + // Err(err) => { + // error!("{err}"); + // return; + // } + // } + + // let identity_path = + // config_directory.join(format!("validator-identity-{validator_index}.json")); + // let validator_keypair = + // read_keypair_file(identity_path).expect("Failed to read validator keypair file"); + + // validator.add_label( + // "validator/name", + // &format!("validator-{validator_index}"), + // LabelType::ValidatorReplicaSet, + // ); + // validator.add_label( + // "validator/type", + // validator.validator_type().to_string(), + // LabelType::ValidatorReplicaSet, + // ); + // validator.add_label( + // "validator/identity", + // validator_keypair.pubkey().to_string(), + // LabelType::ValidatorReplicaSet, + // ); + + // let validator_replica_set = match kub_controller.create_validator_replica_set( + // validator.image(), + // validator.secret().metadata.name.clone(), + // validator.replica_set_labels(), + // validator_index, + // ) { + // Ok(replica_set) => replica_set, + // Err(err) => { + // error!("Error creating validator replicas_set: {err}"); + // return; + // } + // }; + + // let _ = match kub_controller + // .deploy_replicas_set(&validator_replica_set) + // .await + // { + // Ok(rs) => { + // info!("validator replica set ({validator_index}) deployed successfully"); + // rs.metadata.name.unwrap() + // } + // Err(err) => { + // error!( + // "Error! Failed to deploy validator replica set: {validator_index}. err: {err}" + // ); + // return; + // } + // }; + + // let validator_service = kub_controller.create_validator_service( + // &format!("validator-service-{validator_index}"), + // validator.replica_set_labels(), + // ); + // match kub_controller.deploy_service(&validator_service).await { + // Ok(_) => info!("validator service ({validator_index}) deployed successfully"), + // Err(err) => { + // error!("Error! Failed to deploy validator service: {validator_index}. err: {err}") + // } + // } + // } } diff --git a/src/scripts/client-startup-script.sh b/src/scripts/client-startup-script.sh new file mode 100644 index 0000000..b4c648a --- /dev/null +++ b/src/scripts/client-startup-script.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +clientToRun="$1" +benchTpsExtraArgs="$2" +clientType= + +# check if benchTpsExtraArgs is set. if not then it will get set to client-type. Which then needs to get handled appropriately +if [[ "$benchTpsExtraArgs" == "tpu-client" || "$benchTpsExtraArgs" == "rpc-client" ]]; then + clientType=$benchTpsExtraArgs + benchTpsExtraArgs= + shift 2 +else + clientType="${3:-tpu-client}" + shift 3 + # Convert string to array + IFS=' ' read -r -a argsArray <<< "$benchTpsExtraArgs" + + # Loop through the array and check for the specific flag + for arg in "${argsArray[@]}"; do + if [ "$arg" == "--use-rpc-client" ]; then + clientType="rpc-client" + break + elif [ "$arg" == "--use-tpu-client" ]; then + clientType="tpu-client" + break + fi + done +fi + +runtime_args=() +while [[ -n $1 ]]; do + if [[ ${1:0:1} = - ]]; then + if [[ $1 = --target-node ]]; then + echo "WARNING: --target-node not supported yet...not included" + shift 2 + elif [[ $1 = --duration ]]; then + runtime_args+=("$1" "$2") + shift 2 + elif [[ $1 = --num-nodes ]]; then + runtime_args+=("$1" "$2") + shift 2 + else + echo "Unknown argument: $1" + solana-bench-tps --help + exit 1 + fi + else + echo "Unknown argument: $1" + solana-bench-tps --help + exit 1 + fi +done + +echo "get airdrop for client" +solana airdrop 5000000 -k ./client-accounts/identity.json -u "http://$LOAD_BALANCER_RPC_ADDRESS" + +missing() { + echo "Error: $1 not specified" + exit 1 +} + +threadCount=$(nproc) +if [[ $threadCount -gt 4 ]]; then + threadCount=4 +fi + +echo "threadCount: $threadCount" + +RPC_CLIENT=false +case "$clientType" in + tpu-client) + RPC_CLIENT=false + ;; + rpc-client) + RPC_CLIENT=true + ;; + *) + echo "Unexpected clientType: \"$clientType\"" + exit 1 + ;; +esac +case $clientToRun in +bench-tps) + args=() + + if ${RPC_CLIENT}; then + args+=(--use-rpc-client) + fi + + entrypointIp="${BOOTSTRAP_GOSSIP_ADDRESS:0:-5}" + url="$entrypointIp:8899" + + args+=(--bind-address "$entrypointIp") + args+=(--client-node-id ./client-accounts/identity.json) + + clientCommand="\ + solana-bench-tps \ + --sustained \ + --threads $threadCount \ + $benchTpsExtraArgs \ + --read-client-keys ./client-accounts.yml \ + --url "http://$url" + ${args[*]} \ + ${runtime_args[*]} \ + " + ;; +idle) + # In net/remote/remote-client.sh, we add faucet keypair here + # but in this case we already do that in the docker container + # by default + while true; do sleep 3600; done + ;; +*) + echo "Unknown client name: $clientToRun" + exit 1 +esac + +echo "client command to run: $clientCommand" +$clientCommand From 03d0e489b479f923c3f329846982566fa7e4e545 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 9 Apr 2024 02:51:04 +0000 Subject: [PATCH 48/49] wip. can build clients. need to push now --- src/docker.rs | 58 +++--- src/main.rs | 513 +++++++++++++++++++++++++------------------------- 2 files changed, 292 insertions(+), 279 deletions(-) diff --git a/src/docker.rs b/src/docker.rs index 41c58d1..8c364a4 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -17,6 +17,7 @@ pub struct DockerImage { validator_type: ValidatorType, image_name: String, tag: String, + client_index: Option, } impl DockerImage { @@ -26,12 +27,14 @@ impl DockerImage { validator_type: ValidatorType, image_name: String, tag: String, + client_index: Option, ) -> Self { DockerImage { registry, validator_type, image_name, tag, + client_index, } } @@ -43,11 +46,18 @@ impl DockerImage { // Put DockerImage in format for building, pushing, and pulling impl Display for DockerImage { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!( - f, - "{}/{}-{}:{}", - self.registry, self.validator_type, self.image_name, self.tag - ) + match self.client_index { + Some(index) => write!( + f, + "{}/{}-{}-{}:{}", + self.registry, self.validator_type, index, self.image_name, self.tag + ), + None => write!( + f, + "{}/{}-{}:{}", + self.registry, self.validator_type, self.image_name, self.tag + ), + } } } @@ -172,20 +182,26 @@ impl DockerConfig { } } - let (solana_build_directory, startup_script_directory) = - if let DeployMethod::ReleaseChannel(_) = self.deploy_method { - ("solana-release", "./src/scripts".to_string()) - } else { - if validator_type == &ValidatorType::Client { - if let Some(i) = index { - ("farf", format!("./docker-build/client-{i}")) + let solana_build_directory = match self.deploy_method { + DeployMethod::ReleaseChannel(_) => "solana-release", + DeployMethod::Local(_) => "farf", + }; + + let startup_script_directory = match self.deploy_method { + DeployMethod::ReleaseChannel(_) => "./src/scripts".to_string(), + DeployMethod::Local(_) => match validator_type { + ValidatorType::Bootstrap | ValidatorType::RPC | ValidatorType::Standard => { + format!("./docker-build/{validator_type}") + } + ValidatorType::Client => { + if index.is_some() { + format!("./docker-build/client-{}", index.unwrap()) } else { - ("farf", format!("./docker-build/{validator_type}")) + return Err("Error! Client index is None".into()); } - } else { - ("farf", format!("./docker-build/{validator_type}")) } - }; + }, + }; let dockerfile = format!( r#" @@ -239,19 +255,17 @@ WORKDIR /home/solana ) -> String { match index { Some(i) => { - let p = solana_root_path.join(format!("config-k8s/bench-tps-{i}.yml")); - let p_string = p.to_string_lossy().to_string(); // client image - if p.exists() + if solana_root_path + .join(format!("config-k8s/bench-tps-{i}.yml")) + .exists() { - info!("some (i)"); format!( r#" COPY --chown=solana:solana ./config-k8s/bench-tps-{i}.yml /home/solana/client-accounts.yml "#, ) } else { - info!("some(i). but path doesn't exist"); "".to_string() } } @@ -261,13 +275,11 @@ WORKDIR /home/solana .join("config-k8s/client-accounts.yml") .exists() { - info!("index is None. path exists"); r#" COPY --chown=solana:solana ./config-k8s/client-accounts.yml /home/solana "# .to_string() } else { - info!("index is none. path doesn't exist"); "".to_string() } } diff --git a/src/main.rs b/src/main.rs index 78d0a18..2fb47e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -581,82 +581,83 @@ async fn main() { deploy_method, ); + let registry_name = matches.value_of("registry_name").unwrap().to_string(); + let image_name = matches.value_of("image_name").unwrap().to_string(); + let image_tag = matches + .value_of("image_tag") + .unwrap_or_default() + .to_string(); + let mut bootstrap_validator = Validator::new(DockerImage::new( - matches.value_of("registry_name").unwrap().to_string(), + registry_name.clone(), ValidatorType::Bootstrap, - matches.value_of("image_name").unwrap().to_string(), - matches - .value_of("image_tag") - .unwrap_or_default() - .to_string(), + image_name.clone(), + image_tag.clone(), + None, )); - // //TODO do not parse twice - // let mut validator = Validator::new(DockerImage::new( - // matches.value_of("registry_name").unwrap().to_string(), - // ValidatorType::Standard, - // matches.value_of("image_name").unwrap().to_string(), - // matches - // .value_of("image_tag") - // .unwrap_or_default() - // .to_string(), - // )); - - // //TODO do not parse thrice - // let mut rpc_node = Validator::new(DockerImage::new( - // matches.value_of("registry_name").unwrap().to_string(), - // ValidatorType::RPC, - // matches.value_of("image_name").unwrap().to_string(), - // matches - // .value_of("image_tag") - // .unwrap_or_default() - // .to_string(), - // )); - - //TODO do not parse four times - // we need a new image for each client!!! - let mut client = Validator::new(DockerImage::new( - matches.value_of("registry_name").unwrap().to_string(), - ValidatorType::Client, - matches.value_of("image_name").unwrap().to_string(), - matches - .value_of("image_tag") - .unwrap_or_default() - .to_string(), + let mut validator = Validator::new(DockerImage::new( + registry_name.clone(), + ValidatorType::Standard, + image_name.clone(), + image_tag.clone(), + None, + )); + + let mut rpc_node = Validator::new(DockerImage::new( + registry_name.clone(), + ValidatorType::RPC, + image_name.clone(), + image_tag.clone(), + None, )); if build_config.docker_build() { - // let validators = vec![&bootstrap_validator];//, &validator, &rpc_node]; - // for v in &validators { - // match docker.build_image(&solana_root.get_root_path(), v.image()) { - // Ok(_) => info!("{} image built successfully", v.validator_type()), - // Err(err) => { - // error!("Failed to build docker image {err}"); - // return; - // } - // } - // } + let validators = vec![&bootstrap_validator]; //, &validator]; //, &rpc_node]; + for v in &validators { + match docker.build_image(&solana_root.get_root_path(), v.image()) { + Ok(_) => info!("{} image built successfully", v.validator_type()), + Err(err) => { + error!("Failed to build docker image {err}"); + return; + } + } + } - // for v in &validators { - // match DockerConfig::push_image(v.image()) { - // Ok(_) => info!("{} image pushed successfully", v.validator_type()), - // Err(err) => { - // error!("Failed to push docker image {err}"); - // return; - // } - // } - // } + for v in &validators { + match DockerConfig::push_image(v.image()) { + Ok(_) => info!("{} image pushed successfully", v.validator_type()), + Err(err) => { + error!("Failed to push docker image {err}"); + return; + } + } + } + let mut clients = vec![]; for client_index in 0..client_config.num_clients { - info!("here!"); + let client = Validator::new(DockerImage::new( + registry_name.clone(), + ValidatorType::Client, + image_name.clone(), + image_tag.clone(), + Some(client_index), + )); + // need new image for each client - match docker.build_client_image(&solana_root.get_root_path(), &client.image(), client_index) { + match docker.build_client_image( + &solana_root.get_root_path(), + &client.image(), + client_index, + ) { Ok(_) => info!("Client image built successfully"), Err(err) => { error!("Failed to build client image {err}"); return; } } + + clients.push(client); } // match docker.push_client_images(client_config.num_clients, client.image()) { @@ -820,201 +821,201 @@ async fn main() { thread::sleep(Duration::from_secs(1)); } - // if num_rpc_nodes > 0 { - // let mut rpc_nodes = vec![]; - // for rpc_index in 0..num_rpc_nodes { - // match kub_controller.create_rpc_secret(rpc_index, &config_directory) { - // Ok(secret) => rpc_node.set_secret(secret), - // Err(err) => { - // error!("Failed to create RPC node {rpc_index} secret! {err}"); - // return; - // } - // } - // match kub_controller.deploy_secret(&rpc_node.secret()).await { - // Ok(_) => info!("Deployed RPC node {rpc_index} Secret"), - // Err(err) => { - // error!("{err}"); - // return; - // } - // } - // let identity_path = - // config_directory.join(format!("rpc-node-identity-{rpc_index}.json")); - // let rpc_keypair = - // read_keypair_file(identity_path).expect("Failed to read rpc-node keypair file"); - - // rpc_node.add_label( - // "rpc-node/name", - // &format!("rpc-node-{rpc_index}"), - // LabelType::ValidatorReplicaSet, - // ); - - // rpc_node.add_label( - // "rpc-node/type", - // rpc_node.validator_type().to_string(), - // LabelType::ValidatorReplicaSet, - // ); - - // rpc_node.add_label( - // "rpc-node/identity", - // rpc_keypair.pubkey().to_string(), - // LabelType::ValidatorReplicaSet, - // ); - - // rpc_node.add_label( - // "load-balancer/name", - // "load-balancer-selector", - // LabelType::ValidatorReplicaSet, - // ); - - // let rpc_replica_set = match kub_controller.create_rpc_replica_set( - // rpc_node.image(), - // rpc_node.secret().metadata.name.clone(), - // rpc_node.replica_set_labels(), - // rpc_index, - // ) { - // Ok(replica_set) => replica_set, - // Err(err) => { - // error!("Error creating rpc node replicas_set: {err}"); - // return; - // } - // }; - - // // deploy rpc node replica set - // let rpc_node_name = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { - // Ok(rs) => { - // info!("rpc node replica set ({rpc_index}) deployed successfully"); - // rs.metadata.name.unwrap() - // } - // Err(err) => { - // error!("Error! Failed to deploy rpc node replica set: {rpc_index}. err: {err}"); - // return; - // } - // }; - // rpc_nodes.push(rpc_node_name); - - // rpc_node.add_label( - // "service/name", - // &format!("rpc-node-selector-{rpc_index}"), - // LabelType::ValidatorService, - // ); - - // let rpc_service = kub_controller.create_validator_service( - // format!("rpc-node-selector-{rpc_index}").as_str(), - // rpc_node.service_labels(), - // ); - // match kub_controller.deploy_service(&rpc_service).await { - // Ok(_) => info!("rpc node service deployed successfully"), - // Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), - // } - // } - - // // wait for at least one rpc node to deploy - // loop { - // let mut one_rpc_node_ready = false; - // for rpc_node in &rpc_nodes { - // match kub_controller - // .check_replica_set_ready(rpc_node.as_str()) - // .await - // { - // Ok(ready) => { - // if ready { - // one_rpc_node_ready = true; - // break; - // } - // } // Continue the loop if replica set is not ready: Ok(false) - // Err(err) => panic!( - // "Error occurred while checking rpc node replica set readiness: {err}" - // ), - // } - // } - - // if one_rpc_node_ready { - // break; - // } - - // info!("no rpc replica sets ready yet"); - // thread::sleep(Duration::from_secs(10)); - // } - // info!(">= 1 rpc node ready"); - // } - - // // Create and deploy validators secrets/selectors - // for validator_index in 0..num_validators { - // match kub_controller.create_validator_secret(validator_index, &config_directory) { - // Ok(secret) => validator.set_secret(secret), - // Err(err) => { - // error!("Failed to create validator secret! {err}"); - // return; - // } - // }; - - // match kub_controller.deploy_secret(&validator.secret()).await { - // Ok(_) => info!("Deployed validator {validator_index} secret"), - // Err(err) => { - // error!("{err}"); - // return; - // } - // } - - // let identity_path = - // config_directory.join(format!("validator-identity-{validator_index}.json")); - // let validator_keypair = - // read_keypair_file(identity_path).expect("Failed to read validator keypair file"); - - // validator.add_label( - // "validator/name", - // &format!("validator-{validator_index}"), - // LabelType::ValidatorReplicaSet, - // ); - // validator.add_label( - // "validator/type", - // validator.validator_type().to_string(), - // LabelType::ValidatorReplicaSet, - // ); - // validator.add_label( - // "validator/identity", - // validator_keypair.pubkey().to_string(), - // LabelType::ValidatorReplicaSet, - // ); - - // let validator_replica_set = match kub_controller.create_validator_replica_set( - // validator.image(), - // validator.secret().metadata.name.clone(), - // validator.replica_set_labels(), - // validator_index, - // ) { - // Ok(replica_set) => replica_set, - // Err(err) => { - // error!("Error creating validator replicas_set: {err}"); - // return; - // } - // }; - - // let _ = match kub_controller - // .deploy_replicas_set(&validator_replica_set) - // .await - // { - // Ok(rs) => { - // info!("validator replica set ({validator_index}) deployed successfully"); - // rs.metadata.name.unwrap() - // } - // Err(err) => { - // error!( - // "Error! Failed to deploy validator replica set: {validator_index}. err: {err}" - // ); - // return; - // } - // }; - - // let validator_service = kub_controller.create_validator_service( - // &format!("validator-service-{validator_index}"), - // validator.replica_set_labels(), - // ); - // match kub_controller.deploy_service(&validator_service).await { - // Ok(_) => info!("validator service ({validator_index}) deployed successfully"), - // Err(err) => { - // error!("Error! Failed to deploy validator service: {validator_index}. err: {err}") - // } - // } - // } + if num_rpc_nodes > 0 { + let mut rpc_nodes = vec![]; + for rpc_index in 0..num_rpc_nodes { + match kub_controller.create_rpc_secret(rpc_index, &config_directory) { + Ok(secret) => rpc_node.set_secret(secret), + Err(err) => { + error!("Failed to create RPC node {rpc_index} secret! {err}"); + return; + } + } + match kub_controller.deploy_secret(&rpc_node.secret()).await { + Ok(_) => info!("Deployed RPC node {rpc_index} Secret"), + Err(err) => { + error!("{err}"); + return; + } + } + let identity_path = + config_directory.join(format!("rpc-node-identity-{rpc_index}.json")); + let rpc_keypair = + read_keypair_file(identity_path).expect("Failed to read rpc-node keypair file"); + + rpc_node.add_label( + "rpc-node/name", + &format!("rpc-node-{rpc_index}"), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "rpc-node/type", + rpc_node.validator_type().to_string(), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "rpc-node/identity", + rpc_keypair.pubkey().to_string(), + LabelType::ValidatorReplicaSet, + ); + + rpc_node.add_label( + "load-balancer/name", + "load-balancer-selector", + LabelType::ValidatorReplicaSet, + ); + + let rpc_replica_set = match kub_controller.create_rpc_replica_set( + rpc_node.image(), + rpc_node.secret().metadata.name.clone(), + rpc_node.replica_set_labels(), + rpc_index, + ) { + Ok(replica_set) => replica_set, + Err(err) => { + error!("Error creating rpc node replicas_set: {err}"); + return; + } + }; + + // deploy rpc node replica set + let rpc_node_name = match kub_controller.deploy_replicas_set(&rpc_replica_set).await { + Ok(rs) => { + info!("rpc node replica set ({rpc_index}) deployed successfully"); + rs.metadata.name.unwrap() + } + Err(err) => { + error!("Error! Failed to deploy rpc node replica set: {rpc_index}. err: {err}"); + return; + } + }; + rpc_nodes.push(rpc_node_name); + + rpc_node.add_label( + "service/name", + &format!("rpc-node-selector-{rpc_index}"), + LabelType::ValidatorService, + ); + + let rpc_service = kub_controller.create_validator_service( + format!("rpc-node-selector-{rpc_index}").as_str(), + rpc_node.service_labels(), + ); + match kub_controller.deploy_service(&rpc_service).await { + Ok(_) => info!("rpc node service deployed successfully"), + Err(err) => error!("Error! Failed to deploy rpc node service. err: {err}"), + } + } + + // wait for at least one rpc node to deploy + loop { + let mut one_rpc_node_ready = false; + for rpc_node in &rpc_nodes { + match kub_controller + .check_replica_set_ready(rpc_node.as_str()) + .await + { + Ok(ready) => { + if ready { + one_rpc_node_ready = true; + break; + } + } // Continue the loop if replica set is not ready: Ok(false) + Err(err) => panic!( + "Error occurred while checking rpc node replica set readiness: {err}" + ), + } + } + + if one_rpc_node_ready { + break; + } + + info!("no rpc replica sets ready yet"); + thread::sleep(Duration::from_secs(10)); + } + info!(">= 1 rpc node ready"); + } + + // Create and deploy validators secrets/selectors + for validator_index in 0..num_validators { + match kub_controller.create_validator_secret(validator_index, &config_directory) { + Ok(secret) => validator.set_secret(secret), + Err(err) => { + error!("Failed to create validator secret! {err}"); + return; + } + }; + + match kub_controller.deploy_secret(&validator.secret()).await { + Ok(_) => info!("Deployed validator {validator_index} secret"), + Err(err) => { + error!("{err}"); + return; + } + } + + let identity_path = + config_directory.join(format!("validator-identity-{validator_index}.json")); + let validator_keypair = + read_keypair_file(identity_path).expect("Failed to read validator keypair file"); + + validator.add_label( + "validator/name", + &format!("validator-{validator_index}"), + LabelType::ValidatorReplicaSet, + ); + validator.add_label( + "validator/type", + validator.validator_type().to_string(), + LabelType::ValidatorReplicaSet, + ); + validator.add_label( + "validator/identity", + validator_keypair.pubkey().to_string(), + LabelType::ValidatorReplicaSet, + ); + + let validator_replica_set = match kub_controller.create_validator_replica_set( + validator.image(), + validator.secret().metadata.name.clone(), + validator.replica_set_labels(), + validator_index, + ) { + Ok(replica_set) => replica_set, + Err(err) => { + error!("Error creating validator replicas_set: {err}"); + return; + } + }; + + let _ = match kub_controller + .deploy_replicas_set(&validator_replica_set) + .await + { + Ok(rs) => { + info!("validator replica set ({validator_index}) deployed successfully"); + rs.metadata.name.unwrap() + } + Err(err) => { + error!( + "Error! Failed to deploy validator replica set: {validator_index}. err: {err}" + ); + return; + } + }; + + let validator_service = kub_controller.create_validator_service( + &format!("validator-service-{validator_index}"), + validator.replica_set_labels(), + ); + match kub_controller.deploy_service(&validator_service).await { + Ok(_) => info!("validator service ({validator_index}) deployed successfully"), + Err(err) => { + error!("Error! Failed to deploy validator service: {validator_index}. err: {err}") + } + } + } } From 37bbe858b40459e833bfaa298499015c53508aac Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 9 Apr 2024 04:51:21 +0000 Subject: [PATCH 49/49] push client images (threaded). working --- PROGRESS.md | 2 +- src/docker.rs | 52 ++++++++++++++++++++++---------------------- src/lib.rs | 29 +++++++++++++++++++++++++ src/main.rs | 56 ++++++++++++++++-------------------------------- src/validator.rs | 1 + 5 files changed, 75 insertions(+), 65 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 48665eb..a4b5ca0 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -19,7 +19,7 @@ - [x] Bootstrap - [x] Validator (regular) - [x] RPC nodes - - [ ] Client + - [x] Client - [ ] Create & Deploy Secrets - [x] Bootstrap - [x] Validator (regular) diff --git a/src/docker.rs b/src/docker.rs index 8c364a4..6fff118 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,5 +1,8 @@ use { - crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD, ROCKET}, + crate::{ + new_spinner_progress_bar, release::DeployMethod, validator::Validator, + DockerPushThreadError, ValidatorType, BUILD, ROCKET, + }, log::*, rayon::prelude::*, std::{ @@ -12,6 +15,7 @@ use { }, }; +#[derive(Clone)] pub struct DockerImage { registry: String, validator_type: ValidatorType, @@ -286,14 +290,13 @@ WORKDIR /home/solana } } - pub fn push_image(docker_image: &DockerImage) -> Result<(), Box> { + pub fn push_image(docker_image: &DockerImage) -> Result<(), Box> { let progress_bar = new_spinner_progress_bar(); progress_bar.set_message(format!( - "{ROCKET}Pushing {} image to registry...", - docker_image.validator_type() + "{ROCKET}Pushing {docker_image} image to registry...", )); let command = format!("docker push '{docker_image}'"); - let output = match Command::new("sh") + let output = Command::new("sh") .arg("-c") .arg(&command) .stdout(Stdio::null()) @@ -301,13 +304,12 @@ WORKDIR /home/solana .spawn() .expect("Failed to execute command") .wait_with_output() - { - Ok(res) => Ok(res), - Err(err) => Err(Box::new(err) as Box), - }?; + .expect("Failed to push image"); if !output.status.success() { - return Err(output.status.to_string().into()); + return Err(Box::new(DockerPushThreadError::from( + output.status.to_string(), + ))); } progress_bar.finish_and_clear(); Ok(()) @@ -333,20 +335,18 @@ WORKDIR /home/solana Ok(()) } - // // need a new image for each client - // pub fn push_client_images(&self, num_clients: i32, client_image: &DockerImage) -> Result<(), Box> { - // info!("Pushing client images..."); - // (0..num_clients).into_par_iter().try_for_each(|i| { - // let image = format!( - // "{}/{}-{}-{}:{}", - // self.image_config.registry, - // ValidatorType::Client, - // "image", - // i, - // self.image_config.tag - // ); - - // Self::push_image(image, format!("client-{}", i).as_str()) - // }) - // } + pub fn push_images(&self, validators: &[&Validator]) -> Result<(), Box> { + info!("Pushing images..."); + validators + .par_iter() + .try_for_each(|validator| Self::push_image(validator.image())) + } + + // need a new image for each client + pub fn push_client_images(&self, clients: &[Validator]) -> Result<(), Box> { + info!("Pushing client images..."); + clients + .par_iter() + .try_for_each(|client| Self::push_image(client.image())) + } } diff --git a/src/lib.rs b/src/lib.rs index f7f8bdc..9f6714f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ use { reqwest::Client, std::{ env, + error::Error, + fmt::{self, Display, Formatter}, fs::File, io::{BufReader, Cursor, Read}, path::{Path, PathBuf}, @@ -93,6 +95,33 @@ impl Metrics { } } +#[derive(Debug)] +struct DockerPushThreadError { + message: String, +} + +impl Display for DockerPushThreadError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.message) + } +} + +impl Error for DockerPushThreadError {} + +impl From for DockerPushThreadError { + fn from(message: String) -> Self { + DockerPushThreadError { message } + } +} + +impl From<&str> for DockerPushThreadError { + fn from(message: &str) -> Self { + DockerPushThreadError { + message: message.to_string(), + } + } +} + pub mod client_config; pub mod docker; pub mod genesis; diff --git a/src/main.rs b/src/main.rs index 2fb47e5..796dfab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -613,7 +613,7 @@ async fn main() { )); if build_config.docker_build() { - let validators = vec![&bootstrap_validator]; //, &validator]; //, &rpc_node]; + let validators = vec![&bootstrap_validator, &validator, &rpc_node]; for v in &validators { match docker.build_image(&solana_root.get_root_path(), v.image()) { Ok(_) => info!("{} image built successfully", v.validator_type()), @@ -624,16 +624,6 @@ async fn main() { } } - for v in &validators { - match DockerConfig::push_image(v.image()) { - Ok(_) => info!("{} image pushed successfully", v.validator_type()), - Err(err) => { - error!("Failed to push docker image {err}"); - return; - } - } - } - let mut clients = vec![]; for client_index in 0..client_config.num_clients { let client = Validator::new(DockerImage::new( @@ -644,7 +634,8 @@ async fn main() { Some(client_index), )); - // need new image for each client + // need new image for each client since they each hold + // their own client-accounts.yml match docker.build_client_image( &solana_root.get_root_path(), &client.image(), @@ -660,32 +651,21 @@ async fn main() { clients.push(client); } - // match docker.push_client_images(client_config.num_clients, client.image()) { - // Ok(_) => info!("Client image pushed successfully"), - // Err(err) => { - // error!("Exiting........ {}", err); - // return; - // } - // } - - // if client_config.num_clients > 0 { - // // need new image for each client - // match docker.build_client_images(&solana_root.get_root_path(), &client.image(), client_config.num_clients) { - // Ok(_) => info!("Client image built successfully"), - // Err(err) => { - // error!("Failed to build client image {err}"); - // return; - // } - // } - - // match docker.push_client_images(client_config.num_clients) { - // Ok(_) => info!("Client image pushed successfully"), - // Err(err) => { - // error!("Exiting........ {}", err); - // return; - // } - // } - // } + match docker.push_images(&validators) { + Ok(_) => info!("Validator images pushed successfully"), + Err(err) => { + error!("Failed to push Validator docker image {err}"); + return; + } + } + + match docker.push_client_images(&clients) { + Ok(_) => info!("Client image pushed successfully"), + Err(err) => { + error!("Failed to push Client docker image {err}"); + return; + } + } } // metrics secret create once and use by all pods diff --git a/src/validator.rs b/src/validator.rs index 41d4164..8b7421c 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -9,6 +9,7 @@ pub enum LabelType { ValidatorService, } +#[derive(Clone)] pub struct Validator { validator_type: ValidatorType, image: DockerImage,