From 98d72fc908e4d576083de36804716129b4857e57 Mon Sep 17 00:00:00 2001 From: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:32:06 -0700 Subject: [PATCH] 1.19.4 (#812) * start 1.19.4 * deploy 1.19.4-dev-1 * try smaller binaries with cargo strip * deploy 1.19.4-dev-2 * smaller binaries with cargo strip * Fix Submit Dialog Button Behavior with 500 Errors on Duplicate Names (#819) * Implement enhanced error handling and messaging for resource creation * Implement improved error handling for resource creation across alerter, build, and sync * Implement error handling improvements for resource copying and validation feedback * Adjust error handling for resource creation to distinguish validation errors from unexpected system errors * Refactor resource creation error handling by removing redundant match statements and simplifying the error propagation in multiple API modules. * fmt * bump indexmap * fix account selector showing empty when account no longer found * clean up theme logic, ensure monaco and others get up to date current theme * enforce disable_non_admin_create for tags. Clean up status code responses * update server cache concurrency controller * deploy 1.19.4-dev-3 * Allow signing in by pressing enter (#830) * Improve dialog overflow handling to prevent clipping of content (#828) * Add Email notification entry to community.md (#824) * Add clickable file path to show/hide file contents in StackInfo (#827) * add clickable file path to show/hide file contents in StackInfo Also added CopyButton due to the new functionality making the file path not selectable. * Move clicking interaction to CardHeader * Avoid sync edge cases of having toggle show function capturing showContents from outside Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * Format previous change * Add `default_show_contents` to `handleToggleShow` --------- Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * deploy 1.19.4-dev-4 * avoid stake info ShowHideButton double toggle * Allow multiple simultaneous Action runs for use with Args * deploy 1.19.4-dev-5 * feat: persist all table sorting states including unsorted (#832) - Always save sorting state to localStorage, even when empty/unsorted - Fixes issue where 'unsorted' state was not persisted across page reloads - Ensures consistent and predictable sorting behavior for all DataTable components * autofocus on login username field (#837) * Fix unnecessary auth queries flooding console on login page (#842) * Refactor authentication error handling to use serror::Result and status codes * Enable user query only when JWT is present * Enable query execution in useRead only if JWT is present * Revert backend auth changes - keep PR focused on frontend only * Fix unnecessary API queries to unreachable servers flooding console (#843) * Implement server availability checks in various components * Refactor server availability check to ensure only healthy servers are identified * cargo fmt * fmt * Auth error handling with status codes (#841) * Refactor authentication error handling to use serror::Result and status codes * Refactor error messages * Refactor authentication error handling to include status codes and improve error messages * clean up * clean * fmt * invalid user id also UNAUTHORIZED * deploy 1.19.4-dev-6 * deploy 1.19.4-dev-7 --------- Co-authored-by: Marcel Pfennig <82059270+MP-Tool@users.noreply.github.com> Co-authored-by: jack <45038833+jackra1n@users.noreply.github.com> Co-authored-by: Guten Co-authored-by: Paulo Roberto Albuquerque Co-authored-by: Lorenzo Farnararo <2814802+baldarn@users.noreply.github.com> --- Cargo.lock | 738 ++++++++++-------- Cargo.toml | 29 +- bin/binaries.Dockerfile | 4 +- bin/chef.binaries.Dockerfile | 4 +- bin/cli/aio.Dockerfile | 3 +- bin/core/aio.Dockerfile | 4 +- bin/core/src/api/auth.rs | 11 +- bin/core/src/api/execute/action.rs | 7 +- bin/core/src/api/execute/deployment.rs | 16 +- bin/core/src/api/execute/maintenance.rs | 6 +- bin/core/src/api/execute/server.rs | 42 +- bin/core/src/api/execute/stack.rs | 4 +- bin/core/src/api/execute/sync.rs | 6 +- bin/core/src/api/read/action.rs | 4 +- bin/core/src/api/read/sync.rs | 4 +- bin/core/src/api/write/action.rs | 10 +- bin/core/src/api/write/alerter.rs | 10 +- bin/core/src/api/write/build.rs | 10 +- bin/core/src/api/write/builder.rs | 10 +- bin/core/src/api/write/deployment.rs | 17 +- bin/core/src/api/write/procedure.rs | 11 +- bin/core/src/api/write/repo.rs | 7 +- bin/core/src/api/write/server.rs | 11 +- bin/core/src/api/write/stack.rs | 11 +- bin/core/src/api/write/sync.rs | 16 +- bin/core/src/api/write/tag.rs | 15 +- bin/core/src/api/write/user.rs | 4 +- bin/core/src/api/write/user_group.rs | 37 +- bin/core/src/api/write/variable.rs | 47 +- bin/core/src/helpers/action_state.rs | 40 +- bin/core/src/helpers/query.rs | 49 +- bin/core/src/monitor/mod.rs | 42 +- bin/core/src/resource/deployment.rs | 2 +- bin/core/src/resource/mod.rs | 30 +- bin/core/src/resource/server.rs | 4 +- bin/core/src/resource/stack.rs | 2 +- bin/core/src/resource/sync.rs | 4 +- bin/core/src/stack/execute.rs | 2 +- bin/core/src/state.rs | 1 + bin/core/src/sync/execute.rs | 1 + bin/core/src/sync/resources.rs | 1 + bin/periphery/aio.Dockerfile | 3 +- client/core/rs/src/busy.rs | 2 +- .../rs/src/deserializers/forgiving_vec.rs | 11 +- client/core/rs/src/entities/action.rs | 4 +- client/core/ts/package.json | 2 +- client/core/ts/src/types.ts | 4 +- docsite/docs/ecosystem/community.md | 3 +- frontend/public/client/types.d.ts | 4 +- frontend/src/components/group-actions.tsx | 4 +- frontend/src/components/layouts.tsx | 7 +- frontend/src/components/monaco.tsx | 20 +- .../src/components/resources/action/index.tsx | 11 +- frontend/src/components/resources/common.tsx | 37 +- .../src/components/resources/server/index.tsx | 94 ++- .../resources/server/monitoring-table.tsx | 15 +- .../resources/server/stat-chart.tsx | 10 +- .../src/components/resources/server/stats.tsx | 15 +- .../src/components/resources/stack/info.tsx | 84 +- frontend/src/components/terminal/index.tsx | 10 +- frontend/src/components/topbar/components.tsx | 116 +-- frontend/src/lib/hooks.ts | 7 + frontend/src/pages/login.tsx | 10 +- frontend/src/ui/data-table.tsx | 4 +- frontend/src/ui/theme.tsx | 61 +- 65 files changed, 1017 insertions(+), 797 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30f79f7b3..6252d7eed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,12 +39,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -118,15 +112,13 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "async-compression" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6448dfb3960f0b038e88c781ead1e7eb7929dfc3a71a1336ec9086c00f6d1e75" +checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" dependencies = [ "compression-codecs", "compression-core", - "flate2", "futures-core", - "memchr", "pin-project-lite", "tokio", ] @@ -139,7 +131,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -150,7 +142,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -180,9 +172,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.5" +version = "1.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c478f5b10ce55c9a33f87ca3404ca92768b144fc1bfdede7c0121214a8283a25" +checksum = "8bc1b40fb26027769f16960d2f4a6bc20c4bb755d403e552c8c1a73af433c246" dependencies = [ "aws-credential-types", "aws-runtime", @@ -210,9 +202,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1541072f81945fa1251f8795ef6c92c4282d74d59f88498ae7d4bf00f0ebdad9" +checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -222,9 +214,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "94b8ff6c09cd57b16da53641caa860168b88c172a5ee163b0288d3d6eea12786" dependencies = [ "aws-lc-sys", "zeroize", @@ -232,9 +224,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "0e44d16778acaf6a9ec9899b92cebd65580b83f685446bf2e1f5d3d732f99dcd" dependencies = [ "bindgen", "cc", @@ -269,9 +261,9 @@ dependencies = [ [[package]] name = "aws-sdk-ec2" -version = "1.161.0" +version = "1.167.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239393d2a430bd37a7a39d8467674b816f1c864e4bfe874b01a0c9e0d49be4ff" +checksum = "9ce4671cc408e56e7777fa37b611a203ebea22bc295f7611455bf6a4a4d27c4a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -292,9 +284,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.81.0" +version = "1.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ede098271e3471036c46957cba2ba30888f53bda2515bf04b560614a30a36e" +checksum = "357a841807f6b52cb26123878b3326921e2a25faca412fabdd32bd35b7edd5d3" dependencies = [ "aws-credential-types", "aws-runtime", @@ -314,9 +306,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.82.0" +version = "1.85.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43326f724ba2cc957e6f3deac0ca1621a3e5d4146f5970c24c8a108dac33070f" +checksum = "67e05f33b6c9026fecfe9b3b6740f34d41bc6ff641a6a32dabaab60209245b75" dependencies = [ "aws-credential-types", "aws-runtime", @@ -336,9 +328,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.84.0" +version = "1.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91abcdbfb48c38a0419eb75e0eac772a4783a96750392680e4f3c25a8a0535b9" +checksum = "e7d835f123f307cafffca7b9027c14979f1d403b417d8541d67cf252e8a21e35" dependencies = [ "aws-credential-types", "aws-runtime", @@ -412,9 +404,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fdbad9bd9dbcc6c5e68c311a841b54b70def3ca3b674c42fbebb265980539f8" +checksum = "147e8eea63a40315d704b97bf9bc9b8c1402ae94f89d5ad6f7550d963309da1b" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -442,9 +434,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.61.4" +version = "0.61.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16e040799d29c17412943bdbf488fd75db04112d0c0d4b9290bacf5ae0014b9" +checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" dependencies = [ "aws-smithy-types", ] @@ -470,9 +462,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.9.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d57c8b53a72d15c8e190475743acf34e4996685e346a3448dd54ef696fc6e0" +checksum = "4fa63ad37685ceb7762fa4d73d06f1d5493feb88e3f27259b9ed277f4c01b185" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -647,7 +639,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -742,25 +734,22 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.5" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cexpr", "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", "quote", "regex", - "rustc-hash 1.1.0", + "rustc-hash", "shlex", - "syn 2.0.106", - "which", + "syn", ] [[package]] @@ -771,9 +760,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitvec" @@ -863,7 +852,7 @@ dependencies = [ "getrandom 0.2.16", "getrandom 0.3.3", "hex", - "indexmap 2.11.0", + "indexmap 2.11.1", "js-sys", "once_cell", "rand 0.9.2", @@ -907,7 +896,7 @@ dependencies = [ [[package]] name = "cache" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "tokio", @@ -915,10 +904,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.34" +version = "1.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -953,17 +943,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -999,9 +988,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -1009,9 +998,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -1021,14 +1010,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1063,9 +1052,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.4" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" +checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b" dependencies = [ "crossterm", "unicode-segmentation", @@ -1074,7 +1063,7 @@ dependencies = [ [[package]] name = "command" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "komodo_client", "run_command", @@ -1083,29 +1072,27 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46cc6539bf1c592cff488b9f253b30bc0ec50d15407c2cf45e27bd8f308d5905" +checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" dependencies = [ "compression-core", "flate2", - "futures-core", "memchr", - "pin-project-lite", ] [[package]] name = "compression-core" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2957e823c15bde7ecf1e8b64e537aa03a6be5fda0e2334e99887669e75b12e01" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "config" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "colored", - "indexmap 2.11.0", + "indexmap 2.11.1", "regex", "serde", "serde_json", @@ -1210,12 +1197,13 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "crossterm_winapi", + "document-features", "parking_lot 0.12.4", "rustix", "winapi", @@ -1282,7 +1270,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1306,7 +1294,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.106", + "syn", ] [[package]] @@ -1317,7 +1305,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1342,7 +1330,7 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "database" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "async-compression", @@ -1371,9 +1359,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", "serde", @@ -1387,7 +1375,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1398,7 +1386,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1419,7 +1407,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1429,7 +1417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.106", + "syn", ] [[package]] @@ -1449,7 +1437,7 @@ checksum = "9e520b61247a9470ec86a98baf2aebae5c6dd0f25f02b1c87cafe45b06c160e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1460,7 +1448,7 @@ checksum = "12c90da6aa09bad94e4411461560183be70bb33bc30efb2ce941492f22ed6850" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1473,7 +1461,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.106", + "syn", ] [[package]] @@ -1494,7 +1482,7 @@ checksum = "1bceb8b4ad480f8cf02ae4efb42c95add230544b4239d543cbd9f9141d838581" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1517,7 +1505,16 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", ] [[package]] @@ -1636,12 +1633,12 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] name = "environment" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "formatting", @@ -1651,7 +1648,7 @@ dependencies = [ [[package]] name = "environment_file" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "thiserror 2.0.16", ] @@ -1673,12 +1670,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -1714,6 +1711,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" + [[package]] name = "flate2" version = "1.1.2" @@ -1741,7 +1744,7 @@ dependencies = [ [[package]] name = "formatting" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "serror", ] @@ -1824,7 +1827,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -1891,7 +1894,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.5+wasi-0.2.4", "wasm-bindgen", ] @@ -1903,7 +1906,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "cache", @@ -1944,7 +1947,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.0", + "indexmap 2.11.1", "slab", "tokio", "tokio-util", @@ -1963,7 +1966,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.11.0", + "indexmap 2.11.1", "slab", "tokio", "tokio-util", @@ -2096,15 +2099,6 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "http" version = "0.2.12" @@ -2331,9 +2325,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2341,7 +2335,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.0", ] [[package]] @@ -2479,9 +2473,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" dependencies = [ "equivalent", "hashbrown 0.15.5", @@ -2511,7 +2505,7 @@ dependencies = [ [[package]] name = "interpolate" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "komodo_client", @@ -2524,7 +2518,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -2583,9 +2577,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -2617,9 +2611,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" dependencies = [ "once_cell", "wasm-bindgen", @@ -2642,7 +2636,7 @@ dependencies = [ [[package]] name = "komodo_cli" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "chrono", @@ -2667,7 +2661,7 @@ dependencies = [ [[package]] name = "komodo_client" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "async_timing_util", @@ -2679,7 +2673,7 @@ dependencies = [ "derive_variants", "envy", "futures", - "indexmap 2.11.0", + "indexmap 2.11.1", "ipnetwork", "mongo_indexed", "partial_derive2", @@ -2702,7 +2696,7 @@ dependencies = [ [[package]] name = "komodo_core" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "arc-swap", @@ -2734,7 +2728,7 @@ dependencies = [ "git", "hex", "hmac", - "indexmap 2.11.0", + "indexmap 2.11.1", "interpolate", "jsonwebtoken", "komodo_client", @@ -2772,7 +2766,7 @@ dependencies = [ [[package]] name = "komodo_periphery" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "arc-swap", @@ -2827,12 +2821,6 @@ dependencies = [ "spin", ] -[[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.175" @@ -2863,9 +2851,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -2873,6 +2861,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + [[package]] name = "lock_api" version = "0.4.13" @@ -2885,16 +2879,16 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" dependencies = [ "serde", ] [[package]] name = "logger" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "komodo_client", @@ -2931,7 +2925,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -2945,7 +2939,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -2956,7 +2950,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -2967,7 +2961,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -3054,14 +3048,32 @@ checksum = "cf8405357bf431a2e73d83057f2960e9349ab946389dd78af655832921434949" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] -name = "mongodb" -version = "3.2.5" +name = "mongocrypt" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3788f35159bbcf461227af84711950525343b64451fdd90de4e237a0b8a13" +checksum = "22426d6318d19c5c0773f783f85375265d6a8f0fa76a733da8dc4355516ec63d" +dependencies = [ + "bson", + "mongocrypt-sys", + "once_cell", + "serde", +] + +[[package]] +name = "mongocrypt-sys" +version = "0.1.4+1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda42df21d035f88030aad8e877492fac814680e1d7336a57b2a091b989ae388" + +[[package]] +name = "mongodb" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f272c59e54a3c85f5902c6b8e7b1653a6b6681f45e4c42d6581301119a4b8" dependencies = [ "async-trait", "base64 0.13.1", @@ -3080,14 +3092,15 @@ dependencies = [ "hmac", "macro_magic", "md-5", + "mongocrypt", "mongodb-internal-macros", "once_cell", "pbkdf2", "percent-encoding", "rand 0.8.5", "rustc_version_runtime", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", + "rustls 0.23.31", + "rustversion", "serde", "serde_bytes", "serde_with", @@ -3099,23 +3112,23 @@ dependencies = [ "take_mut", "thiserror 1.0.69", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.2", "tokio-util", "typed-builder", "uuid", - "webpki-roots 0.25.4", + "webpki-roots 0.26.11", ] [[package]] name = "mongodb-internal-macros" -version = "3.2.5" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdfb13b7c0436b3e395f4ce5f4366431b9c9db47adc4cb33afc6b5b913d44969" +checksum = "63981427a0f26b89632fd2574280e069d09fb2912a3138da15de0174d11dd077" dependencies = [ "macro_magic", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -3139,7 +3152,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -3185,12 +3198,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3282,7 +3294,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -3492,12 +3504,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "p256" version = "0.13.2" @@ -3598,7 +3604,7 @@ checksum = "3a506f66d52e40b2385d7b9f776fd5243d6cff16ba79147f859aa4e27d2d27cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -3637,7 +3643,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "periphery_client" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "komodo_client", @@ -3688,7 +3694,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -3747,9 +3753,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3776,7 +3782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn", ] [[package]] @@ -3817,23 +3823,23 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases 0.2.1", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash", "rustls 0.23.31", - "socket2 0.5.10", + "socket2 0.6.0", "thiserror 2.0.16", "tokio", "tracing", @@ -3842,16 +3848,16 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", "getrandom 0.3.3", "lru-slab", "rand 0.9.2", "ring", - "rustc-hash 2.1.1", + "rustc-hash", "rustls 0.23.31", "rustls-pki-types", "slab", @@ -3863,16 +3869,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.0", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3970,7 +3976,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -3990,7 +3996,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -4142,9 +4148,9 @@ dependencies = [ [[package]] name = "resolv-conf" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" +checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" [[package]] name = "resolver_api" @@ -4163,12 +4169,12 @@ checksum = "e45ff368040e7f3787e97e6f3a97718ca08e0553587747bd4d0bf3ca2b899963" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] name = "response" -version = "1.19.3" +version = "1.19.4-dev-7" dependencies = [ "anyhow", "axum", @@ -4245,12 +4251,6 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -4278,15 +4278,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -4312,7 +4312,7 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.5", "subtle", "zeroize", ] @@ -4338,7 +4338,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.3.0", + "security-framework 3.4.0", ] [[package]] @@ -4381,9 +4381,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "b5a37813727b78798e53c2bec3f5e8fe12a6d6f8389bf9ca7802add4c9905ad8" dependencies = [ "aws-lc-rs", "ring", @@ -4405,11 +4405,11 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -4461,7 +4461,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.106", + "syn", ] [[package]] @@ -4500,7 +4500,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -4509,11 +4509,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -4522,9 +4522,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -4532,16 +4532,17 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.222" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "aab69e3f5be1836a1fe0aca0b286e5a5b38f262d6c9e8acd2247818751fcc8fb" dependencies = [ + "serde_core", "serde_derive", ] @@ -4557,22 +4558,32 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "fe07b5d88710e3b807c16a06ccbc9dfecd5fff6a4d2745c59e3e26774f10de6a" dependencies = [ "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.222" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8ebec5eea07db7df9342aa712db2138f019d9ab3454a60a680579a6f841b80" +dependencies = [ + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.222" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "b5f61630fe26d0ff555e6c37dc445ab2f15871c8a11ace3cf471b3195d3e4f49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -4583,30 +4594,32 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.1", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "a30a8abed938137c7183c173848e3c9b3517f5e038226849a4ecc9b21a4b4e2a" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -4637,7 +4650,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -4671,7 +4684,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.0", + "indexmap 2.11.1", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -4690,7 +4703,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -4699,7 +4712,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.1", "itoa", "ryu", "serde", @@ -4708,9 +4721,9 @@ dependencies = [ [[package]] name = "serial2" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26e1e5956803a69ddd72ce2de337b577898801528749565def03515f82bad5bb" +checksum = "349bb79c63bd2690fe4ca8ef7072a6d9ca36b3a1687a08393e733ea56d573911" dependencies = [ "cfg-if", "libc", @@ -4719,9 +4732,9 @@ dependencies = [ [[package]] name = "serror" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b4167e91cc6ad0f816a0a9297ec203813d426a647c73448b2dad80239e615de" +checksum = "bee3f9a0b6dee3c0e8c581dddc560f66f20a1c5c20f6609e827167265ac84eb6" dependencies = [ "anyhow", "axum", @@ -4936,7 +4949,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.106", + "syn", ] [[package]] @@ -4948,7 +4961,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -4966,17 +4979,6 @@ dependencies = [ "thiserror 2.0.16", ] -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.106" @@ -5005,7 +5007,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5028,7 +5030,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -5081,7 +5083,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5092,7 +5094,7 @@ checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5106,12 +5108,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde", @@ -5121,15 +5122,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -5197,7 +5198,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5280,7 +5281,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.11.1", "serde", "serde_spanned", "toml_datetime", @@ -5361,7 +5362,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.11.0", + "indexmap 2.11.1", "pin-project-lite", "slab", "sync_wrapper", @@ -5378,7 +5379,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-core", "futures-util", @@ -5432,7 +5433,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5486,9 +5487,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "nu-ansi-term", "serde", @@ -5545,13 +5546,22 @@ dependencies = [ [[package]] name = "typed-builder" -version = "0.10.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +checksum = "cd9d30e3a08026c78f246b173243cf07b3696d274debd26680773b6773c2afc7" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c36781cc0e46a83726d9879608e4cf6c2505237e263a8eb8c24502989cfdb28" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -5579,7 +5589,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a615d6c2764852a2e88a4f16e9ce1ea49bb776b5872956309e170d63a042a34f" dependencies = [ "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5596,9 +5606,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-normalization" @@ -5677,9 +5687,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -5729,44 +5739,54 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.5+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" dependencies = [ - "wit-bindgen-rt", + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.106", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" dependencies = [ "cfg-if", "js-sys", @@ -5777,9 +5797,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5787,22 +5807,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" dependencies = [ "unicode-ident", ] @@ -5837,9 +5857,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" dependencies = [ "js-sys", "wasm-bindgen", @@ -5857,9 +5877,12 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] [[package]] name = "webpki-roots" @@ -5870,18 +5893,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "widestring" version = "1.2.0" @@ -5926,9 +5937,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -5938,7 +5949,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", ] [[package]] @@ -5949,9 +5960,22 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] @@ -5960,8 +5984,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", "windows-threading", ] @@ -5973,7 +5997,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5984,7 +6008,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -5993,14 +6017,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", ] [[package]] @@ -6009,9 +6039,9 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -6020,7 +6050,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -6029,7 +6068,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -6068,6 +6116,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -6105,7 +6162,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -6122,7 +6179,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -6289,13 +6346,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" [[package]] name = "writeable" @@ -6338,28 +6392,28 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] [[package]] @@ -6379,7 +6433,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", "synstructure", ] @@ -6419,5 +6473,5 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 6ff486fb1..29f78ee0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,16 @@ members = [ ] [workspace.package] -version = "1.19.3" +version = "1.19.4-dev-7" edition = "2024" authors = ["mbecker20 "] license = "GPL-3.0-or-later" repository = "https://github.com/moghtech/komodo" homepage = "https://komo.do" +[profile.release] +strip = "debuginfo" + [workspace.dependencies] # LOCAL komodo_client = { path = "client/core/rs" } @@ -33,7 +36,7 @@ git = { path = "lib/git" } # MOGH run_command = { version = "0.0.6", features = ["async_tokio"] } -serror = { version = "0.5.0", default-features = false } +serror = { version = "0.5.1", default-features = false } slack = { version = "0.4.0", package = "slack_client_rs", default-features = false, features = ["rustls"] } derive_default_builder = "0.1.8" derive_empty_traits = "0.1.0" @@ -65,12 +68,12 @@ axum = { version = "0.8.4", features = ["ws", "json", "macros"] } # SER/DE ipnetwork = { version = "0.21.1", features = ["serde"] } -indexmap = { version = "2.11.0", features = ["serde"] } +indexmap = { version = "2.11.1", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } strum = { version = "0.27.2", features = ["derive"] } bson = { version = "2.15.0" } # must keep in sync with mongodb version serde_yaml_ng = "0.10.0" -serde_json = "1.0.143" +serde_json = "1.0.145" serde_qs = "0.15.0" toml = "0.9.5" @@ -81,19 +84,19 @@ thiserror = "2.0.16" # LOGGING opentelemetry-otlp = { version = "0.30.0", features = ["tls-roots", "reqwest-rustls"] } opentelemetry_sdk = { version = "0.30.0", features = ["rt-tokio"] } -tracing-subscriber = { version = "0.3.19", features = ["json"] } +tracing-subscriber = { version = "0.3.20", features = ["json"] } opentelemetry-semantic-conventions = "0.30.0" tracing-opentelemetry = "0.31.0" opentelemetry = "0.30.0" tracing = "0.1.41" # CONFIG -clap = { version = "4.5.45", features = ["derive"] } +clap = { version = "4.5.47", features = ["derive"] } dotenvy = "0.15.7" envy = "0.4.2" # CRYPTO / AUTH -uuid = { version = "1.18.0", features = ["v4", "fast-rng", "serde"] } +uuid = { version = "1.18.1", features = ["v4", "fast-rng", "serde"] } jsonwebtoken = { version = "9.3.1", default-features = false } openidconnect = "4.0.1" urlencoding = "2.1.3" @@ -112,20 +115,20 @@ bollard = "0.19.2" sysinfo = "0.37.0" # CLOUD -aws-config = "1.8.5" -aws-sdk-ec2 = "1.161.0" -aws-credential-types = "1.2.5" +aws-config = "1.8.6" +aws-sdk-ec2 = "1.167.0" +aws-credential-types = "1.2.6" ## CRON english-to-cron = "0.1.6" chrono-tz = "0.10.4" -chrono = "0.4.41" +chrono = "0.4.42" croner = "3.0.0" # MISC -async-compression = { version = "0.4.28", features = ["tokio", "gzip"] } +async-compression = { version = "0.4.30", features = ["tokio", "gzip"] } derive_builder = "0.20.2" -comfy-table = "7.1.4" +comfy-table = "7.2.1" typeshare = "1.0.4" octorust = "0.10.0" dashmap = "6.1.0" diff --git a/bin/binaries.Dockerfile b/bin/binaries.Dockerfile index 06980db07..dc74a04b6 100644 --- a/bin/binaries.Dockerfile +++ b/bin/binaries.Dockerfile @@ -2,6 +2,7 @@ ## for a specific architecture. FROM rust:1.89.0-bullseye AS builder +RUN cargo install cargo-strip WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -16,7 +17,8 @@ COPY ./bin/cli ./bin/cli RUN \ cargo build -p komodo_core --release && \ cargo build -p komodo_periphery --release && \ - cargo build -p komodo_cli --release + cargo build -p komodo_cli --release && \ + cargo strip # Copy just the binaries to scratch image FROM scratch diff --git a/bin/chef.binaries.Dockerfile b/bin/chef.binaries.Dockerfile index d4c74903a..d2d2423fb 100644 --- a/bin/chef.binaries.Dockerfile +++ b/bin/chef.binaries.Dockerfile @@ -12,6 +12,7 @@ COPY . . RUN cargo chef prepare --recipe-path recipe.json FROM chef AS builder +RUN cargo install cargo-strip COPY --from=planner /builder/recipe.json recipe.json # Build JUST dependencies - cached layer RUN cargo chef cook --release --recipe-path recipe.json @@ -20,7 +21,8 @@ COPY . . RUN \ cargo build --release --bin core && \ cargo build --release --bin periphery && \ - cargo build --release --bin km + cargo build --release --bin km && \ + cargo strip # Copy just the binaries to scratch image FROM scratch diff --git a/bin/cli/aio.Dockerfile b/bin/cli/aio.Dockerfile index 882034344..f86c2d807 100644 --- a/bin/cli/aio.Dockerfile +++ b/bin/cli/aio.Dockerfile @@ -1,4 +1,5 @@ FROM rust:1.89.0-bullseye AS builder +RUN cargo install cargo-strip WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -8,7 +9,7 @@ COPY ./client/periphery ./client/periphery COPY ./bin/cli ./bin/cli # Compile bin -RUN cargo build -p komodo_cli --release +RUN cargo build -p komodo_cli --release && cargo strip # Copy binaries to distroless base FROM gcr.io/distroless/cc diff --git a/bin/core/aio.Dockerfile b/bin/core/aio.Dockerfile index d94057da7..c22b1a2f2 100644 --- a/bin/core/aio.Dockerfile +++ b/bin/core/aio.Dockerfile @@ -2,6 +2,7 @@ # Build Core FROM rust:1.89.0-bullseye AS core-builder +RUN cargo install cargo-strip WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -13,7 +14,8 @@ COPY ./bin/cli ./bin/cli # Compile app RUN cargo build -p komodo_core --release && \ - cargo build -p komodo_cli --release + cargo build -p komodo_cli --release && \ + cargo strip # Build Frontend FROM node:20.12-alpine AS frontend-builder diff --git a/bin/core/src/api/auth.rs b/bin/core/src/api/auth.rs index d8b8d6209..9ba89dfef 100644 --- a/bin/core/src/api/auth.rs +++ b/bin/core/src/api/auth.rs @@ -3,11 +3,12 @@ use std::{sync::OnceLock, time::Instant}; use axum::{Router, extract::Path, http::HeaderMap, routing::post}; use derive_variants::{EnumVariants, ExtractVariant}; use komodo_client::{api::auth::*, entities::user::User}; +use reqwest::StatusCode; use resolver_api::Resolve; use response::Response; use serde::{Deserialize, Serialize}; use serde_json::json; -use serror::Json; +use serror::{AddStatusCode, Json}; use typeshare::typeshare; use uuid::Uuid; @@ -152,7 +153,11 @@ impl Resolve for GetUser { self, AuthArgs { headers }: &AuthArgs, ) -> serror::Result { - let user_id = get_user_id_from_headers(headers).await?; - Ok(get_user(&user_id).await?) + let user_id = get_user_id_from_headers(headers) + .await + .status_code(StatusCode::UNAUTHORIZED)?; + get_user(&user_id) + .await + .status_code(StatusCode::UNAUTHORIZED) } } diff --git a/bin/core/src/api/execute/action.rs b/bin/core/src/api/execute/action.rs index 3b34eca2b..e86912cff 100644 --- a/bin/core/src/api/execute/action.rs +++ b/bin/core/src/api/execute/action.rs @@ -92,8 +92,11 @@ impl Resolve for RunAction { // This will set action state back to default when dropped. // Will also check to ensure action not already busy before updating. - let _action_guard = - action_state.update(|state| state.running = true)?; + let _action_guard = action_state.update_custom( + |state| state.running += 1, + |state| state.running -= 1, + false, + )?; let mut update = update.clone(); diff --git a/bin/core/src/api/execute/deployment.rs b/bin/core/src/api/execute/deployment.rs index da8231ac2..1cdbebb37 100644 --- a/bin/core/src/api/execute/deployment.rs +++ b/bin/core/src/api/execute/deployment.rs @@ -222,7 +222,7 @@ impl Resolve for Deploy { } }; - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -343,7 +343,7 @@ pub async fn pull_deployment_inner( Err(e) => Log::error("Pull image", format_serror(&e.into())), }; - update_cache_for_server(server).await; + update_cache_for_server(server, true).await; anyhow::Ok(log) } .await; @@ -428,7 +428,7 @@ impl Resolve for StartDeployment { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -477,7 +477,7 @@ impl Resolve for RestartDeployment { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -524,7 +524,7 @@ impl Resolve for PauseDeployment { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -573,7 +573,7 @@ impl Resolve for UnpauseDeployment { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -628,7 +628,7 @@ impl Resolve for StopDeployment { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -711,7 +711,7 @@ impl Resolve for DestroyDeployment { update.logs.push(log); update.finalize(); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update_update(update.clone()).await?; Ok(update) diff --git a/bin/core/src/api/execute/maintenance.rs b/bin/core/src/api/execute/maintenance.rs index 4ad70f74f..072c5443d 100644 --- a/bin/core/src/api/execute/maintenance.rs +++ b/bin/core/src/api/execute/maintenance.rs @@ -49,7 +49,7 @@ impl Resolve for ClearRepoCache { if !user.admin { return Err( anyhow!("This method is admin only.") - .status_code(StatusCode::UNAUTHORIZED), + .status_code(StatusCode::FORBIDDEN), ); } @@ -124,7 +124,7 @@ impl Resolve for BackupCoreDatabase { if !user.admin { return Err( anyhow!("This method is admin only.") - .status_code(StatusCode::UNAUTHORIZED), + .status_code(StatusCode::FORBIDDEN), ); } @@ -173,7 +173,7 @@ impl Resolve for GlobalAutoUpdate { if !user.admin { return Err( anyhow!("This method is admin only.") - .status_code(StatusCode::UNAUTHORIZED), + .status_code(StatusCode::FORBIDDEN), ); } diff --git a/bin/core/src/api/execute/server.rs b/bin/core/src/api/execute/server.rs index 262d025db..73ec06c5a 100644 --- a/bin/core/src/api/execute/server.rs +++ b/bin/core/src/api/execute/server.rs @@ -66,7 +66,7 @@ impl Resolve for StartContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -122,7 +122,7 @@ impl Resolve for RestartContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -176,7 +176,7 @@ impl Resolve for PauseContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -232,7 +232,7 @@ impl Resolve for UnpauseContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -288,7 +288,7 @@ impl Resolve for StopContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -350,7 +350,7 @@ impl Resolve for DestroyContainer { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -401,7 +401,7 @@ impl Resolve for StartAllContainers { ); } - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -453,7 +453,7 @@ impl Resolve for RestartAllContainers { ); } - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -503,7 +503,7 @@ impl Resolve for PauseAllContainers { ); } - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -555,7 +555,7 @@ impl Resolve for UnpauseAllContainers { ); } - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -605,7 +605,7 @@ impl Resolve for StopAllContainers { ); } - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -660,7 +660,7 @@ impl Resolve for PruneContainers { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -711,7 +711,7 @@ impl Resolve for DeleteNetwork { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -765,7 +765,7 @@ impl Resolve for PruneNetworks { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -813,7 +813,7 @@ impl Resolve for DeleteImage { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -865,7 +865,7 @@ impl Resolve for PruneImages { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -916,7 +916,7 @@ impl Resolve for DeleteVolume { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -968,7 +968,7 @@ impl Resolve for PruneVolumes { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -1020,7 +1020,7 @@ impl Resolve for PruneDockerBuilders { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -1072,7 +1072,7 @@ impl Resolve for PruneBuildx { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -1123,7 +1123,7 @@ impl Resolve for PruneSystem { }; update.logs.push(log); - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; diff --git a/bin/core/src/api/execute/stack.rs b/bin/core/src/api/execute/stack.rs index 765d5f66e..7efe1fe50 100644 --- a/bin/core/src/api/execute/stack.rs +++ b/bin/core/src/api/execute/stack.rs @@ -260,7 +260,7 @@ impl Resolve for DeployStack { } // Ensure cached stack state up to date by updating server cache - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; @@ -761,7 +761,7 @@ pub async fn pull_stack_inner( .await?; // Ensure cached stack state up to date by updating server cache - update_cache_for_server(server).await; + update_cache_for_server(server, true).await; Ok(res) } diff --git a/bin/core/src/api/execute/sync.rs b/bin/core/src/api/execute/sync.rs index bc2579e91..707a6bf9e 100644 --- a/bin/core/src/api/execute/sync.rs +++ b/bin/core/src/api/execute/sync.rs @@ -77,10 +77,8 @@ impl Resolve for RunSync { }; // get the action state for the sync (or insert default). - let action_state = action_states() - .resource_sync - .get_or_insert_default(&sync.id) - .await; + let action_state = + action_states().sync.get_or_insert_default(&sync.id).await; // This will set action state back to default when dropped. // Will also check to ensure sync not already busy before updating. diff --git a/bin/core/src/api/read/action.rs b/bin/core/src/api/read/action.rs index 9dccb24ae..68b6a08eb 100644 --- a/bin/core/src/api/read/action.rs +++ b/bin/core/src/api/read/action.rs @@ -131,8 +131,8 @@ impl Resolve for GetActionsSummary { .unwrap_or_default() .get()?, ) { - (_, action_states) if action_states.running => { - res.running += 1; + (_, action_states) if action_states.running > 0 => { + res.running += action_states.running; } (ActionState::Ok, _) => res.ok += 1, (ActionState::Failed, _) => res.failed += 1, diff --git a/bin/core/src/api/read/sync.rs b/bin/core/src/api/read/sync.rs index 3e2674064..1e0fec6c7 100644 --- a/bin/core/src/api/read/sync.rs +++ b/bin/core/src/api/read/sync.rs @@ -93,7 +93,7 @@ impl Resolve for GetResourceSyncActionState { ) .await?; let action_state = action_states() - .resource_sync + .sync .get(&sync.id) .await .unwrap_or_default() @@ -138,7 +138,7 @@ impl Resolve for GetResourceSyncsSummary { continue; } if action_states - .resource_sync + .sync .get(&resource_sync.id) .await .unwrap_or_default() diff --git a/bin/core/src/api/write/action.rs b/bin/core/src/api/write/action.rs index cab3d7fa9..220cc0979 100644 --- a/bin/core/src/api/write/action.rs +++ b/bin/core/src/api/write/action.rs @@ -16,10 +16,7 @@ impl Resolve for CreateAction { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -35,10 +32,7 @@ impl Resolve for CopyAction { PermissionLevel::Write.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/alerter.rs b/bin/core/src/api/write/alerter.rs index 470ef5612..9bb6e9e84 100644 --- a/bin/core/src/api/write/alerter.rs +++ b/bin/core/src/api/write/alerter.rs @@ -16,10 +16,7 @@ impl Resolve for CreateAlerter { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -35,10 +32,7 @@ impl Resolve for CopyAlerter { PermissionLevel::Write.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/build.rs b/bin/core/src/api/write/build.rs index e139989a2..6a431c98c 100644 --- a/bin/core/src/api/write/build.rs +++ b/bin/core/src/api/write/build.rs @@ -50,10 +50,7 @@ impl Resolve for CreateBuild { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -71,10 +68,7 @@ impl Resolve for CopyBuild { .await?; // reset version to 0.0.0 config.version = Default::default(); - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/builder.rs b/bin/core/src/api/write/builder.rs index 560551f6c..00297f38e 100644 --- a/bin/core/src/api/write/builder.rs +++ b/bin/core/src/api/write/builder.rs @@ -16,10 +16,7 @@ impl Resolve for CreateBuilder { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -35,10 +32,7 @@ impl Resolve for CopyBuilder { PermissionLevel::Write.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/deployment.rs b/bin/core/src/api/write/deployment.rs index 2e7cb45c4..3b1592c5e 100644 --- a/bin/core/src/api/write/deployment.rs +++ b/bin/core/src/api/write/deployment.rs @@ -38,10 +38,8 @@ impl Resolve for CreateDeployment { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user) + .await } } @@ -58,10 +56,8 @@ impl Resolve for CopyDeployment { PermissionLevel::Read.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user) + .await } } @@ -153,10 +149,7 @@ impl Resolve for CreateDeploymentFromContainer { }); } - Ok( - resource::create::(&self.name, config, user) - .await?, - ) + resource::create::(&self.name, config, user).await } } diff --git a/bin/core/src/api/write/procedure.rs b/bin/core/src/api/write/procedure.rs index e98ead1c7..5f79273ed 100644 --- a/bin/core/src/api/write/procedure.rs +++ b/bin/core/src/api/write/procedure.rs @@ -16,10 +16,7 @@ impl Resolve for CreateProcedure { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -36,10 +33,8 @@ impl Resolve for CopyProcedure { PermissionLevel::Write.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user) + .await } } diff --git a/bin/core/src/api/write/repo.rs b/bin/core/src/api/write/repo.rs index a68406ffc..ef0424671 100644 --- a/bin/core/src/api/write/repo.rs +++ b/bin/core/src/api/write/repo.rs @@ -42,7 +42,7 @@ impl Resolve for CreateRepo { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok(resource::create::(&self.name, self.config, user).await?) + resource::create::(&self.name, self.config, user).await } } @@ -58,10 +58,7 @@ impl Resolve for CopyRepo { PermissionLevel::Read.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/server.rs b/bin/core/src/api/write/server.rs index 1c37c386d..df8981672 100644 --- a/bin/core/src/api/write/server.rs +++ b/bin/core/src/api/write/server.rs @@ -30,10 +30,7 @@ impl Resolve for CreateServer { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -49,10 +46,8 @@ impl Resolve for CopyServer { PermissionLevel::Read.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/stack.rs b/bin/core/src/api/write/stack.rs index 76f9e94a2..6b2943f29 100644 --- a/bin/core/src/api/write/stack.rs +++ b/bin/core/src/api/write/stack.rs @@ -51,10 +51,7 @@ impl Resolve for CreateStack { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user).await } } @@ -70,10 +67,8 @@ impl Resolve for CopyStack { PermissionLevel::Read.into(), ) .await?; - Ok( - resource::create::(&self.name, config.into(), user) - .await?, - ) + + resource::create::(&self.name, config.into(), user).await } } diff --git a/bin/core/src/api/write/sync.rs b/bin/core/src/api/write/sync.rs index 208143f75..1064ca106 100644 --- a/bin/core/src/api/write/sync.rs +++ b/bin/core/src/api/write/sync.rs @@ -68,10 +68,8 @@ impl Resolve for CreateResourceSync { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { - Ok( - resource::create::(&self.name, self.config, user) - .await?, - ) + resource::create::(&self.name, self.config, user) + .await } } @@ -88,14 +86,8 @@ impl Resolve for CopyResourceSync { PermissionLevel::Write.into(), ) .await?; - Ok( - resource::create::( - &self.name, - config.into(), - user, - ) - .await?, - ) + resource::create::(&self.name, config.into(), user) + .await } } diff --git a/bin/core/src/api/write/tag.rs b/bin/core/src/api/write/tag.rs index da8a68496..7585e27a2 100644 --- a/bin/core/src/api/write/tag.rs +++ b/bin/core/src/api/write/tag.rs @@ -13,9 +13,12 @@ use komodo_client::{ server::Server, stack::Stack, sync::ResourceSync, tag::Tag, }, }; +use reqwest::StatusCode; use resolver_api::Resolve; +use serror::AddStatusCodeError; use crate::{ + config::core_config, helpers::query::{get_tag, get_tag_check_owner}, resource, state::db_client, @@ -29,8 +32,18 @@ impl Resolve for CreateTag { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { + if core_config().disable_non_admin_create && !user.admin { + return Err( + anyhow!("Non admins cannot create tags") + .status_code(StatusCode::FORBIDDEN), + ); + } + if ObjectId::from_str(&self.name).is_ok() { - return Err(anyhow!("tag name cannot be ObjectId").into()); + return Err( + anyhow!("Tag name cannot be ObjectId") + .status_code(StatusCode::BAD_REQUEST), + ); } let mut tag = Tag { diff --git a/bin/core/src/api/write/user.rs b/bin/core/src/api/write/user.rs index 5cbaca349..ce87f0075 100644 --- a/bin/core/src/api/write/user.rs +++ b/bin/core/src/api/write/user.rs @@ -32,7 +32,7 @@ impl Resolve for CreateLocalUser { if !admin.admin { return Err( anyhow!("This method is admin-only.") - .status_code(StatusCode::UNAUTHORIZED), + .status_code(StatusCode::FORBIDDEN), ); } @@ -183,7 +183,7 @@ impl Resolve for DeleteUser { if !admin.admin { return Err( anyhow!("This method is admin-only.") - .status_code(StatusCode::UNAUTHORIZED), + .status_code(StatusCode::FORBIDDEN), ); } if admin.username == self.user || admin.id == self.user { diff --git a/bin/core/src/api/write/user_group.rs b/bin/core/src/api/write/user_group.rs index 125adbf3e..348efb887 100644 --- a/bin/core/src/api/write/user_group.rs +++ b/bin/core/src/api/write/user_group.rs @@ -10,7 +10,9 @@ use komodo_client::{ api::write::*, entities::{komodo_timestamp, user_group::UserGroup}, }; +use reqwest::StatusCode; use resolver_api::Resolve; +use serror::AddStatusCodeError; use crate::state::db_client; @@ -23,7 +25,10 @@ impl Resolve for CreateUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let user_group = UserGroup { name: self.name, @@ -58,7 +63,10 @@ impl Resolve for RenameUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); update_one_by_id( @@ -84,7 +92,10 @@ impl Resolve for DeleteUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); @@ -117,7 +128,10 @@ impl Resolve for AddUserToUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); @@ -161,7 +175,10 @@ impl Resolve for RemoveUserFromUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); @@ -205,7 +222,10 @@ impl Resolve for SetUsersInUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); @@ -252,7 +272,10 @@ impl Resolve for SetEveryoneUserGroup { WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("This call is admin-only").into()); + return Err( + anyhow!("This call is admin-only") + .status_code(StatusCode::FORBIDDEN), + ); } let db = db_client(); diff --git a/bin/core/src/api/write/variable.rs b/bin/core/src/api/write/variable.rs index 6df2dd4e8..f4ea801af 100644 --- a/bin/core/src/api/write/variable.rs +++ b/bin/core/src/api/write/variable.rs @@ -4,7 +4,9 @@ use komodo_client::{ api::write::*, entities::{Operation, ResourceTarget, variable::Variable}, }; +use reqwest::StatusCode; use resolver_api::Resolve; +use serror::AddStatusCodeError; use crate::{ helpers::{ @@ -22,6 +24,13 @@ impl Resolve for CreateVariable { self, WriteArgs { user }: &WriteArgs, ) -> serror::Result { + if !user.admin { + return Err( + anyhow!("Only admins can create variables") + .status_code(StatusCode::FORBIDDEN), + ); + } + let CreateVariable { name, value, @@ -29,10 +38,6 @@ impl Resolve for CreateVariable { is_secret, } = self; - if !user.admin { - return Err(anyhow!("only admins can create variables").into()); - } - let variable = Variable { name, value, @@ -44,7 +49,7 @@ impl Resolve for CreateVariable { .variables .insert_one(&variable) .await - .context("failed to create variable on db")?; + .context("Failed to create variable on db")?; let mut update = make_update( ResourceTarget::system(), @@ -69,7 +74,10 @@ impl Resolve for UpdateVariableValue { WriteArgs { user }: &WriteArgs, ) -> serror::Result { if !user.admin { - return Err(anyhow!("only admins can update variables").into()); + return Err( + anyhow!("Only admins can update variables") + .status_code(StatusCode::FORBIDDEN), + ); } let UpdateVariableValue { name, value } = self; @@ -87,7 +95,7 @@ impl Resolve for UpdateVariableValue { doc! { "$set": { "value": &value } }, ) .await - .context("failed to update variable value on db")?; + .context("Failed to update variable value on db")?; let mut update = make_update( ResourceTarget::system(), @@ -107,7 +115,7 @@ impl Resolve for UpdateVariableValue { ) }; - update.push_simple_log("update variable value", log); + update.push_simple_log("Update Variable Value", log); update.finalize(); add_update(update).await?; @@ -123,7 +131,10 @@ impl Resolve for UpdateVariableDescription { WriteArgs { user }: &WriteArgs, ) -> serror::Result { if !user.admin { - return Err(anyhow!("only admins can update variables").into()); + return Err( + anyhow!("Only admins can update variables") + .status_code(StatusCode::FORBIDDEN), + ); } db_client() .variables @@ -132,7 +143,7 @@ impl Resolve for UpdateVariableDescription { doc! { "$set": { "description": &self.description } }, ) .await - .context("failed to update variable description on db")?; + .context("Failed to update variable description on db")?; Ok(get_variable(&self.name).await?) } } @@ -144,7 +155,10 @@ impl Resolve for UpdateVariableIsSecret { WriteArgs { user }: &WriteArgs, ) -> serror::Result { if !user.admin { - return Err(anyhow!("only admins can update variables").into()); + return Err( + anyhow!("Only admins can update variables") + .status_code(StatusCode::FORBIDDEN), + ); } db_client() .variables @@ -153,7 +167,7 @@ impl Resolve for UpdateVariableIsSecret { doc! { "$set": { "is_secret": self.is_secret } }, ) .await - .context("failed to update variable is secret on db")?; + .context("Failed to update variable is secret on db")?; Ok(get_variable(&self.name).await?) } } @@ -164,14 +178,17 @@ impl Resolve for DeleteVariable { WriteArgs { user }: &WriteArgs, ) -> serror::Result { if !user.admin { - return Err(anyhow!("only admins can delete variables").into()); + return Err( + anyhow!("Only admins can delete variables") + .status_code(StatusCode::FORBIDDEN), + ); } let variable = get_variable(&self.name).await?; db_client() .variables .delete_one(doc! { "name": &self.name }) .await - .context("failed to delete variable on db")?; + .context("Failed to delete variable on db")?; let mut update = make_update( ResourceTarget::system(), @@ -180,7 +197,7 @@ impl Resolve for DeleteVariable { ); update - .push_simple_log("delete variable", format!("{variable:#?}")); + .push_simple_log("Delete Variable", format!("{variable:#?}")); update.finalize(); add_update(update).await?; diff --git a/bin/core/src/helpers/action_state.rs b/bin/core/src/helpers/action_state.rs index 608365db5..0d7f5a6a9 100644 --- a/bin/core/src/helpers/action_state.rs +++ b/bin/core/src/helpers/action_state.rs @@ -16,17 +16,16 @@ use super::cache::Cache; #[derive(Default)] pub struct ActionStates { - pub build: Cache>>, + pub server: Cache>>, + pub stack: Cache>>, pub deployment: Cache>>, - pub server: Cache>>, + pub build: Cache>>, pub repo: Cache>>, pub procedure: Cache>>, pub action: Cache>>, - pub resource_sync: - Cache>>, - pub stack: Cache>>, + pub sync: Cache>>, } /// Need to be able to check "busy" with write lock acquired. @@ -62,17 +61,33 @@ impl /// Returns a guard that returns the states to default (not busy) when dropped. pub fn update( &self, - handler: impl Fn(&mut States), + update_fn: impl Fn(&mut States), + ) -> anyhow::Result> { + self.update_custom( + update_fn, + |states| *states = Default::default(), + true, + ) + } + + /// Will acquire lock, optionally check busy, and if not will + /// run the provided update function on the states. + /// Returns a guard that calls the provided return_fn when dropped. + pub fn update_custom( + &self, + update_fn: impl Fn(&mut States), + return_fn: impl Fn(&mut States) + Send + 'static, + busy_check: bool, ) -> anyhow::Result> { let mut lock = self .0 .lock() - .map_err(|e| anyhow!("action state lock poisoned | {e:?}"))?; - if lock.busy() { - return Err(anyhow!("resource is busy")); + .map_err(|e| anyhow!("Action state lock poisoned | {e:?}"))?; + if busy_check && lock.busy() { + return Err(anyhow!("Resource is busy")); } - handler(&mut *lock); - Ok(UpdateGuard(&self.0)) + update_fn(&mut *lock); + Ok(UpdateGuard(&self.0, Box::new(return_fn))) } } @@ -82,6 +97,7 @@ impl /// user could drop UpdateGuard. pub struct UpdateGuard<'a, States: Default + Send + 'static>( &'a Mutex, + Box, ); impl Drop @@ -95,6 +111,6 @@ impl Drop return; } }; - *lock = States::default(); + self.1(&mut *lock); } } diff --git a/bin/core/src/helpers/query.rs b/bin/core/src/helpers/query.rs index a88ad4a08..04e3fcabd 100644 --- a/bin/core/src/helpers/query.rs +++ b/bin/core/src/helpers/query.rs @@ -13,26 +13,31 @@ use database::mungos::{ options::FindOneOptions, }, }; -use komodo_client::entities::{ - Operation, ResourceTarget, ResourceTargetVariant, - action::{Action, ActionState}, - alerter::Alerter, - build::Build, - builder::Builder, - deployment::{Deployment, DeploymentState}, - docker::container::{ContainerListItem, ContainerStateStatusEnum}, - permission::{PermissionLevel, PermissionLevelAndSpecifics}, - procedure::{Procedure, ProcedureState}, - repo::Repo, - server::{Server, ServerState}, - stack::{Stack, StackServiceNames, StackState}, - stats::SystemInformation, - sync::ResourceSync, - tag::Tag, - update::Update, - user::{User, admin_service_user}, - user_group::UserGroup, - variable::Variable, +use komodo_client::{ + busy::Busy, + entities::{ + Operation, ResourceTarget, ResourceTargetVariant, + action::{Action, ActionState}, + alerter::Alerter, + build::Build, + builder::Builder, + deployment::{Deployment, DeploymentState}, + docker::container::{ + ContainerListItem, ContainerStateStatusEnum, + }, + permission::{PermissionLevel, PermissionLevelAndSpecifics}, + procedure::{Procedure, ProcedureState}, + repo::Repo, + server::{Server, ServerState}, + stack::{Stack, StackServiceNames, StackState}, + stats::SystemInformation, + sync::ResourceSync, + tag::Tag, + update::Update, + user::{User, admin_service_user}, + user_group::UserGroup, + variable::Variable, + }, }; use periphery_client::api::stats; use tokio::sync::Mutex; @@ -467,7 +472,7 @@ pub async fn get_action_state(id: &String) -> ActionState { .action .get(id) .await - .map(|s| s.get().map(|s| s.running)) + .map(|s| s.get().map(|s| s.busy())) .transpose() .ok() .flatten() @@ -483,7 +488,7 @@ pub async fn get_procedure_state(id: &String) -> ProcedureState { .procedure .get(id) .await - .map(|s| s.get().map(|s| s.running)) + .map(|s| s.get().map(|s| s.busy())) .transpose() .ok() .flatten() diff --git a/bin/core/src/monitor/mod.rs b/bin/core/src/monitor/mod.rs index e7824efe2..3c50814f6 100644 --- a/bin/core/src/monitor/mod.rs +++ b/bin/core/src/monitor/mod.rs @@ -1,3 +1,5 @@ +use std::sync::{Arc, OnceLock}; + use async_timing_util::wait_until_timelength; use database::mungos::{find::find_collect, mongodb::bson::doc}; use futures::future::join_all; @@ -15,10 +17,11 @@ use komodo_client::entities::{ }; use periphery_client::api::{self, git::GetLatestCommit}; use serror::Serror; +use tokio::sync::Mutex; use crate::{ config::core_config, - helpers::periphery_client, + helpers::{cache::Cache, periphery_client}, monitor::{alert::check_alerts, record::record_server_stats}, state::{db_client, deployment_status_cache, repo_status_cache}, }; @@ -110,14 +113,47 @@ async fn refresh_server_cache(ts: i64) { } }; let futures = servers.into_iter().map(|server| async move { - update_cache_for_server(&server).await; + update_cache_for_server(&server, false).await; }); join_all(futures).await; tokio::join!(check_alerts(ts), record_server_stats(ts)); } +/// Makes sure cache for server doesn't update too frequently / simultaneously. +/// If forced, will still block against simultaneous update. +fn update_cache_for_server_controller() +-> &'static Cache>> { + static CACHE: OnceLock>>> = + OnceLock::new(); + CACHE.get_or_init(Default::default) +} + +/// The background loop will call this with force: false, +/// which exits early if the lock is busy or it was completed too recently. +/// If force is true, it will wait on simultaneous calls, and will +/// ignore the restriction on being completed too recently. #[instrument(level = "debug")] -pub async fn update_cache_for_server(server: &Server) { +pub async fn update_cache_for_server(server: &Server, force: bool) { + // Concurrency controller to ensure it isn't done too often + // when it happens in other contexts. + let controller = update_cache_for_server_controller() + .get_or_insert_default(&server.id) + .await; + let mut lock = match controller.try_lock() { + Ok(lock) => lock, + Err(_) if force => controller.lock().await, + Err(_) => return, + }; + + let now = komodo_timestamp(); + + // early return if called again sooner than 1s. + if !force && *lock > now - 1_000 { + return; + } + + *lock = now; + let (deployments, builds, repos, stacks) = tokio::join!( find_collect( &db_client().deployments, diff --git a/bin/core/src/resource/deployment.rs b/bin/core/src/resource/deployment.rs index dab5496c4..ff6197679 100644 --- a/bin/core/src/resource/deployment.rs +++ b/bin/core/src/resource/deployment.rs @@ -188,7 +188,7 @@ impl super::KomodoResource for Deployment { else { return Ok(()); }; - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; Ok(()) } diff --git a/bin/core/src/resource/mod.rs b/bin/core/src/resource/mod.rs index 06dfe9ac4..85f942deb 100644 --- a/bin/core/src/resource/mod.rs +++ b/bin/core/src/resource/mod.rs @@ -34,8 +34,10 @@ use komodo_client::{ parsers::parse_string_list, }; use partial_derive2::{Diff, MaybeNone, PartialDiff}; +use reqwest::StatusCode; use resolver_api::Resolve; use serde::{Serialize, de::DeserializeOwned}; +use serror::AddStatusCodeError; use crate::{ api::{read::ReadArgs, write::WriteArgs}, @@ -458,22 +460,31 @@ pub async fn create( name: &str, mut config: T::PartialConfig, user: &User, -) -> anyhow::Result> { +) -> serror::Result> { if !T::user_can_create(user) { - return Err(anyhow!( - "User does not have permissions to create {}.", - T::resource_type() - )); + return Err( + anyhow!( + "User does not have permissions to create {}.", + T::resource_type() + ) + .status_code(StatusCode::FORBIDDEN), + ); } if name.is_empty() { - return Err(anyhow!("Must provide non-empty name for resource.")); + return Err( + anyhow!("Must provide non-empty name for resource") + .status_code(StatusCode::BAD_REQUEST), + ); } let name = T::validated_name(name); if ObjectId::from_str(&name).is_ok() { - return Err(anyhow!("valid ObjectIds cannot be used as names.")); + return Err( + anyhow!("Valid ObjectIds cannot be used as names") + .status_code(StatusCode::BAD_REQUEST), + ); } // Ensure an existing resource with same name doesn't already exist @@ -489,7 +500,10 @@ pub async fn create( .into_iter() .any(|r| r.name == name) { - return Err(anyhow!("Must provide unique name for resource.")); + return Err( + anyhow!("Resource with name '{}' already exists", name) + .status_code(StatusCode::CONFLICT), + ); } let start_ts = komodo_timestamp(); diff --git a/bin/core/src/resource/server.rs b/bin/core/src/resource/server.rs index fd30554c3..e9a3701a9 100644 --- a/bin/core/src/resource/server.rs +++ b/bin/core/src/resource/server.rs @@ -123,7 +123,7 @@ impl super::KomodoResource for Server { created: &Resource, _update: &mut Update, ) -> anyhow::Result<()> { - update_cache_for_server(created).await; + update_cache_for_server(created, true).await; Ok(()) } @@ -145,7 +145,7 @@ impl super::KomodoResource for Server { updated: &Self, _update: &mut Update, ) -> anyhow::Result<()> { - update_cache_for_server(updated).await; + update_cache_for_server(updated, true).await; Ok(()) } diff --git a/bin/core/src/resource/stack.rs b/bin/core/src/resource/stack.rs index 95fff164c..f107fd5cc 100644 --- a/bin/core/src/resource/stack.rs +++ b/bin/core/src/resource/stack.rs @@ -252,7 +252,7 @@ impl super::KomodoResource for Stack { else { return Ok(()); }; - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; Ok(()) } diff --git a/bin/core/src/resource/sync.rs b/bin/core/src/resource/sync.rs index 189c3e27c..b6e57c798 100644 --- a/bin/core/src/resource/sync.rs +++ b/bin/core/src/resource/sync.rs @@ -113,7 +113,7 @@ impl super::KomodoResource for ResourceSync { async fn busy(id: &String) -> anyhow::Result { action_states() - .resource_sync + .sync .get(id) .await .unwrap_or_default() @@ -242,7 +242,7 @@ async fn get_resource_sync_state( data: &ResourceSyncInfo, ) -> ResourceSyncState { if let Some(state) = action_states() - .resource_sync + .sync .get(id) .await .and_then(|s| { diff --git a/bin/core/src/stack/execute.rs b/bin/core/src/stack/execute.rs index 9e59c40e8..202992d63 100644 --- a/bin/core/src/stack/execute.rs +++ b/bin/core/src/stack/execute.rs @@ -72,7 +72,7 @@ pub async fn execute_compose( .push(T::execute(periphery, stack, services, extras).await?); // Ensure cached stack state up to date by updating server cache - update_cache_for_server(&server).await; + update_cache_for_server(&server, true).await; update.finalize(); update_update(update.clone()).await?; diff --git a/bin/core/src/state.rs b/bin/core/src/state.rs index 454b3b392..660f0b362 100644 --- a/bin/core/src/state.rs +++ b/bin/core/src/state.rs @@ -40,6 +40,7 @@ pub fn db_client() -> &'static Client { .expect("db_client accessed before initialized") } +/// Must be called in app startup sequence. pub async fn init_db_client() { let client = Client::new(&core_config().database) .await diff --git a/bin/core/src/sync/execute.rs b/bin/core/src/sync/execute.rs index 2c413db1b..69e10899a 100644 --- a/bin/core/src/sync/execute.rs +++ b/bin/core/src/sync/execute.rs @@ -147,6 +147,7 @@ pub trait ExecuteResourceSync: ResourceSyncTrait { sync_user(), ) .await + .map_err(|e| e.error) { Ok(resource) => resource.id, Err(e) => { diff --git a/bin/core/src/sync/resources.rs b/bin/core/src/sync/resources.rs index 80f972eee..f27389e89 100644 --- a/bin/core/src/sync/resources.rs +++ b/bin/core/src/sync/resources.rs @@ -825,6 +825,7 @@ impl ExecuteResourceSync for Procedure { sync_user(), ) .await + .map_err(|e| e.error) { Ok(resource) => resource.id, Err(e) => { diff --git a/bin/periphery/aio.Dockerfile b/bin/periphery/aio.Dockerfile index db0468655..475a19b84 100644 --- a/bin/periphery/aio.Dockerfile +++ b/bin/periphery/aio.Dockerfile @@ -1,6 +1,7 @@ ## All in one, multi stage compile + runtime Docker build for your architecture. FROM rust:1.89.0-bullseye AS builder +RUN cargo install cargo-strip WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -10,7 +11,7 @@ COPY ./client/periphery ./client/periphery COPY ./bin/periphery ./bin/periphery # Compile app -RUN cargo build -p komodo_periphery --release +RUN cargo build -p komodo_periphery --release && cargo strip # Final Image FROM debian:bullseye-slim diff --git a/client/core/rs/src/busy.rs b/client/core/rs/src/busy.rs index 8b4eaa24e..17cef6daa 100644 --- a/client/core/rs/src/busy.rs +++ b/client/core/rs/src/busy.rs @@ -68,7 +68,7 @@ impl Busy for ProcedureActionState { impl Busy for ActionActionState { fn busy(&self) -> bool { - self.running + self.running > 0 } } diff --git a/client/core/rs/src/deserializers/forgiving_vec.rs b/client/core/rs/src/deserializers/forgiving_vec.rs index 06906612a..df5eefc9c 100644 --- a/client/core/rs/src/deserializers/forgiving_vec.rs +++ b/client/core/rs/src/deserializers/forgiving_vec.rs @@ -1,5 +1,4 @@ use serde::{ - __private::de::{Content, ContentDeserializer}, Deserialize, Deserializer, de::{IntoDeserializer, Visitor}, }; @@ -69,17 +68,15 @@ impl<'de, T: Deserialize<'de>> Visitor<'de> let mut res = Vec::with_capacity(seq.size_hint().unwrap_or_default()); loop { - match seq.next_element::() { - Ok(Some(content)) => { - match T::deserialize::>( - content.clone().into_deserializer(), - ) { + match seq.next_element::() { + Ok(Some(value)) => { + match T::deserialize(value.clone().into_deserializer()) { Ok(item) => res.push(item), Err(e) => { // Since this is used to parse startup config (including logging config), // the tracing logging is not initialized. Need to use eprintln. eprintln!( - "WARN: failed to parse item in list | {content:?} | {e:?}", + "WARN: failed to parse item in list | {value:?} | {e:?}", ) } } diff --git a/client/core/rs/src/entities/action.rs b/client/core/rs/src/entities/action.rs index ff39fc632..c7a447b2b 100644 --- a/client/core/rs/src/entities/action.rs +++ b/client/core/rs/src/entities/action.rs @@ -222,8 +222,8 @@ impl Default for ActionConfig { #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)] pub struct ActionActionState { - /// Whether the action is currently running. - pub running: bool, + /// Number of instances of the Action currently running + pub running: u32, } #[typeshare] diff --git a/client/core/ts/package.json b/client/core/ts/package.json index e8e196fa8..408919ea8 100644 --- a/client/core/ts/package.json +++ b/client/core/ts/package.json @@ -1,6 +1,6 @@ { "name": "komodo_client", - "version": "1.19.3", + "version": "1.19.4", "description": "Komodo client package", "homepage": "https://komo.do", "main": "dist/lib.js", diff --git a/client/core/ts/src/types.ts b/client/core/ts/src/types.ts index a99d74a74..84ea19f3c 100644 --- a/client/core/ts/src/types.ts +++ b/client/core/ts/src/types.ts @@ -1351,8 +1351,8 @@ export type ExportResourcesToTomlResponse = TomlResponse; export type FindUserResponse = User; export interface ActionActionState { - /** Whether the action is currently running. */ - running: boolean; + /** Number of instances of the Action currently running */ + running: number; } export type GetActionActionStateResponse = ActionActionState; diff --git a/docsite/docs/ecosystem/community.md b/docsite/docs/ecosystem/community.md index 9879937fb..0b16d33aa 100644 --- a/docsite/docs/ecosystem/community.md +++ b/docsite/docs/ecosystem/community.md @@ -15,4 +15,5 @@ These provide alerting implementations which can be used with the `Custom` Alert - [Telegram](https://github.com/mattsmallman/komodo-alert-to-telgram) by [mattsmallman](https://github.com/mattsmallman) - [Ntfy](https://github.com/FoxxMD/deploy-ntfy-alerter) by [FoxxMD](https://github.com/FoxxMD) - [Gotify](https://github.com/FoxxMD/deploy-gotify-alerter) by [FoxxMD](https://github.com/FoxxMD) -- [Apprise](https://github.com/FoxxMD/deploy-apprise-alerter) by [FoxxMD](https://github.com/FoxxMD) \ No newline at end of file +- [Apprise](https://github.com/FoxxMD/deploy-apprise-alerter) by [FoxxMD](https://github.com/FoxxMD) +- [Email](https://github.com/gutenye/email-notification/blob/main/src/templates/Komodo/Komodo.md) by [Guten Ye](https://github.com/gutenye) diff --git a/frontend/public/client/types.d.ts b/frontend/public/client/types.d.ts index b0a005f03..9d4299c83 100644 --- a/frontend/public/client/types.d.ts +++ b/frontend/public/client/types.d.ts @@ -1457,8 +1457,8 @@ export type ExportAllResourcesToTomlResponse = TomlResponse; export type ExportResourcesToTomlResponse = TomlResponse; export type FindUserResponse = User; export interface ActionActionState { - /** Whether the action is currently running. */ - running: boolean; + /** Number of instances of the Action currently running */ + running: number; } export type GetActionActionStateResponse = ActionActionState; export type GetActionResponse = Action; diff --git a/frontend/src/components/group-actions.tsx b/frontend/src/components/group-actions.tsx index 05ca664c4..1cca62464 100644 --- a/frontend/src/components/group-actions.tsx +++ b/frontend/src/components/group-actions.tsx @@ -136,12 +136,12 @@ const GroupActionDialog = ({ return ( !o && onClose()}> - + Group Execute - {formatted}
-
    +
      {selected.map((resource) => (
    • {resource}
    • ))} diff --git a/frontend/src/components/layouts.tsx b/frontend/src/components/layouts.tsx index a63a2155f..ea3f0a1c2 100644 --- a/frontend/src/components/layouts.tsx +++ b/frontend/src/components/layouts.tsx @@ -254,8 +254,11 @@ export const NewLayout = ({ try { await onConfirm(); set(false); - } catch (error) { - console.error("Error creating resource:", error); + } catch (error: any) { + const status = error?.status || error?.response?.status; + if (status !== 409 && status !== 400) { + set(false); + } } finally { setLoading(false); } diff --git a/frontend/src/components/monaco.tsx b/frontend/src/components/monaco.tsx index 6e24481a4..8109fe505 100644 --- a/frontend/src/components/monaco.tsx +++ b/frontend/src/components/monaco.tsx @@ -141,13 +141,7 @@ export const MonacoEditor = ({ )}px`; }, [editor, line_count]); - const { theme: _theme } = useTheme(); - const theme = - _theme === "system" - ? window.matchMedia("(prefers-color-scheme: dark)").matches - ? "dark" - : "light" - : _theme; + const { currentTheme } = useTheme(); const options: monaco.editor.IStandaloneEditorConstructionOptions = { minimap: { enabled: false }, @@ -171,7 +165,7 @@ export const MonacoEditor = ({ onValueChange?.(v ?? "")} @@ -233,13 +227,7 @@ export const MonacoDiffEditor = ({ )}px`; }, [editor, line_count]); - const { theme: _theme } = useTheme(); - const theme = - _theme === "system" - ? window.matchMedia("(prefers-color-scheme: dark)").matches - ? "dark" - : "light" - : _theme; + const { currentTheme } = useTheme(); const options: monaco.editor.IStandaloneDiffEditorConstructionOptions = { minimap: { enabled: true }, @@ -262,7 +250,7 @@ export const MonacoDiffEditor = ({ language={language} original={original} modified={modified} - theme={theme} + theme={currentTheme} options={options} onMount={(editor) => { const modifiedEditor = editor.getModifiedEditor(); diff --git a/frontend/src/components/resources/action/index.tsx b/frontend/src/components/resources/action/index.tsx index 240b3eb15..8e63f4fde 100644 --- a/frontend/src/components/resources/action/index.tsx +++ b/frontend/src/components/resources/action/index.tsx @@ -119,11 +119,12 @@ export const ActionComponents: RequiredResourceComponents = { Actions: { RunAction: ({ id }) => { - const running = useRead( - "GetActionActionState", - { action: id }, - { refetchInterval: 5000 } - ).data?.running; + const running = + (useRead( + "GetActionActionState", + { action: id }, + { refetchInterval: 5000 } + ).data?.running ?? 0) > 0; const { mutate, isPending } = useExecute("RunAction"); const action = useAction(id); if (!action) return null; diff --git a/frontend/src/components/resources/common.tsx b/frontend/src/components/resources/common.tsx index 7522e2175..c92f0f5b6 100644 --- a/frontend/src/components/resources/common.tsx +++ b/frontend/src/components/resources/common.tsx @@ -439,12 +439,23 @@ export const CopyResource = ({ const nav = useNavigate(); const inv = useInvalidate(); - const { mutate } = useWrite(`Copy${type}`, { - onSuccess: (res) => { + const { mutateAsync: copy } = useWrite(`Copy${type}`); + + const onConfirm = async () => { + if (!name) return; + try { + const res = await copy({ id, name }); inv([`List${type}s`]); nav(`/${usableResourcePath(type)}/${res._id?.$oid}`); - }, - }); + setOpen(false); + } catch (error: any) { + // Keep dialog open for validation errors (409/400), close for system errors + const status = error?.status || error?.response?.status; + if (status !== 409 && status !== 400) { + setOpen(false); + } + } + }; return ( @@ -472,9 +483,8 @@ export const CopyResource = ({ title="Copy" icon={} disabled={!name} - onClick={() => { - mutate({ id, name }); - setOpen(false); + onClick={async () => { + await onConfirm(); }} /> @@ -526,10 +536,13 @@ export const NewResource = ({ : {}; const onConfirm = async () => { if (!name) toast({ title: "Name cannot be empty" }); - const id = templateId - ? (await copy({ name, id: templateId }))._id?.$oid! - : (await create({ name, config }))._id?.$oid!; - nav(`/${usableResourcePath(type)}/${id}`); + const result = templateId + ? await copy({ name, id: templateId }) + : await create({ name, config }); + const resourceId = result._id?.$oid; + if (resourceId) { + nav(`/${usableResourcePath(type)}/${resourceId}`); + } }; return ( { if (!name) return; if (e.key === "Enter") { - onConfirm(); + onConfirm().catch(() => {}); } }} /> diff --git a/frontend/src/components/resources/server/index.tsx b/frontend/src/components/resources/server/index.tsx index 184e31ea7..09ea71d47 100644 --- a/frontend/src/components/resources/server/index.tsx +++ b/frontend/src/components/resources/server/index.tsx @@ -44,6 +44,12 @@ export const useServer = (id?: string) => (d) => d.id === id ); +// Helper function to check if server is available for API calls +export const useIsServerAvailable = (serverId?: string) => { + const server = useServer(serverId); + return server?.info.state === Types.ServerState.Ok; +}; + export const useFullServer = (id: string) => useRead("GetServer", { server: id }, { refetchInterval: 10_000 }).data; @@ -51,24 +57,26 @@ export const useFullServer = (id: string) => export const useVersionMismatch = (serverId?: string) => { const core_version = useRead("GetVersion", {}).data?.version; const server_version = useServer(serverId)?.info.version; - + const unknown = !server_version || server_version === "Unknown"; - const mismatch = !!server_version && !!core_version && server_version !== core_version; - + const mismatch = + !!server_version && !!core_version && server_version !== core_version; + return { unknown, mismatch, hasVersionMismatch: mismatch && !unknown }; }; const Icon = ({ id, size }: { id?: string; size: number }) => { const state = useServer(id)?.info.state; const { hasVersionMismatch } = useVersionMismatch(id); - + return ( ); @@ -137,10 +145,7 @@ const ConfigTabs = ({ id }: { id: string }) => { ); return ( - + @@ -221,10 +226,10 @@ export const ServerVersion = ({ id }: { id: string }) => { const core_version = useRead("GetVersion", {}).data?.version; const version = useServer(id)?.info.version; const server_state = useServer(id)?.info.state; - + const unknown = !version || version === "Unknown"; const mismatch = !!version && !!core_version && version !== core_version; - + // Don't show version for disabled servers if (server_state === Types.ServerState.Disabled) { return ( @@ -242,13 +247,14 @@ export const ServerVersion = ({ id }: { id: string }) => {
      - Server is disabled - version unknown. + Server is disabled - version + unknown.
      ); } - + return ( @@ -306,7 +312,11 @@ export const ServerComponents: RequiredResourceComponents = { ), Dashboard: () => { - const summary = useRead("GetServersSummary", {}, { refetchInterval: 15_000 }).data; + const summary = useRead( + "GetServersSummary", + {}, + { refetchInterval: 15_000 } + ).data; return ( { const state = useServer(id)?.info.state; const { hasVersionMismatch } = useVersionMismatch(id); - + // Show full version mismatch text - const displayState = state === Types.ServerState.Ok && hasVersionMismatch - ? "Version Mismatch" - : state === Types.ServerState.NotOk - ? "Not Ok" - : state; - + const displayState = + state === Types.ServerState.Ok && hasVersionMismatch + ? "Version Mismatch" + : state === Types.ServerState.NotOk + ? "Not Ok" + : state; + return ( - ); }, @@ -384,13 +395,13 @@ export const ServerComponents: RequiredResourceComponents = { Info: { Version: ServerVersion, Cpu: ({ id }) => { - const server = useServer(id); + const isServerAvailable = useIsServerAvailable(id); const core_count = useRead( "GetSystemInformation", { server: id }, { - enabled: server ? server.info.state !== "Disabled" : false, + enabled: isServerAvailable, refetchInterval: 5000, } ).data?.core_count ?? 0; @@ -402,19 +413,19 @@ export const ServerComponents: RequiredResourceComponents = { ); }, LoadAvg: ({ id }) => { - const server = useServer(id); + const isServerAvailable = useIsServerAvailable(id); const stats = useRead( "GetSystemStats", { server: id }, { - enabled: server ? server.info.state !== "Disabled" : false, + enabled: isServerAvailable, refetchInterval: 5000, } ).data; - + if (!stats?.load_average) return null; const one = stats.load_average?.one; - + return (
      @@ -423,12 +434,12 @@ export const ServerComponents: RequiredResourceComponents = { ); }, Mem: ({ id }) => { - const server = useServer(id); + const isServerAvailable = useIsServerAvailable(id); const stats = useRead( "GetSystemStats", { server: id }, { - enabled: server ? server.info.state !== "Disabled" : false, + enabled: isServerAvailable, refetchInterval: 5000, } ).data; @@ -440,12 +451,12 @@ export const ServerComponents: RequiredResourceComponents = { ); }, Disk: ({ id }) => { - const server = useServer(id); + const isServerAvailable = useIsServerAvailable(id); const stats = useRead( "GetSystemStats", { server: id }, { - enabled: server ? server.info.state !== "Disabled" : false, + enabled: isServerAvailable, refetchInterval: 5000, } ).data; @@ -616,11 +627,12 @@ export const ServerComponents: RequiredResourceComponents = { const { hasVersionMismatch } = useVersionMismatch(id); // Determine display state for header (longer text is okay in header) - const displayState = server?.info.state === Types.ServerState.Ok && hasVersionMismatch - ? "Version Mismatch" - : server?.info.state === Types.ServerState.NotOk - ? "Not Ok" - : server?.info.state; + const displayState = + server?.info.state === Types.ServerState.Ok && hasVersionMismatch + ? "Version Mismatch" + : server?.info.state === Types.ServerState.NotOk + ? "Not Ok" + : server?.info.state; return ( { const servers = useRead("ListServers", {}).data; @@ -73,11 +74,19 @@ export const ServerMonitoringTable = ({ search = "" }: { search?: string }) => { ); }; -const useStats = (id: string) => - useRead("GetSystemStats", { server: id }, { refetchInterval: 10_000 }).data; +const useStats = (id: string) => { + const isServerAvailable = useIsServerAvailable(id); + return useRead("GetSystemStats", { server: id }, { + enabled: isServerAvailable, + refetchInterval: 10_000 + }).data; +}; const useServerThresholds = (id: string) => { - const config = useRead("GetServer", { server: id }).data?.config as any; + const isServerAvailable = useIsServerAvailable(id); + const config = useRead("GetServer", { server: id }, { + enabled: isServerAvailable + }).data?.config as any; return { cpuWarning: config?.cpu_warning ?? 75, cpuCritical: config?.cpu_critical ?? 90, diff --git a/frontend/src/components/resources/server/stat-chart.tsx b/frontend/src/components/resources/server/stat-chart.tsx index 3464224dd..b9abbb4f2 100644 --- a/frontend/src/components/resources/server/stat-chart.tsx +++ b/frontend/src/components/resources/server/stat-chart.tsx @@ -95,13 +95,7 @@ export const InnerStatChart = ({ stats: StatDatapoint[] | undefined; seriesData?: { label: string; data: StatDatapoint[] }[]; }) => { - const { theme: _theme } = useTheme(); - const theme = - _theme === "system" - ? window.matchMedia("(prefers-color-scheme: dark)").matches - ? "dark" - : "light" - : _theme; + const { currentTheme } = useTheme(); const min = stats?.[0]?.date ?? 0; const max = stats?.[stats.length - 1]?.date ?? 0; @@ -200,7 +194,7 @@ export const InnerStatChart = ({ hex_color_by_intention("Unknown"), ] : [getColor(type)], - dark: theme === "dark", + dark: currentTheme === "dark", padding: { left: 10, right: 10, diff --git a/frontend/src/components/resources/server/stats.tsx b/frontend/src/components/resources/server/stats.tsx index 2c47172b5..c3f350a92 100644 --- a/frontend/src/components/resources/server/stats.tsx +++ b/frontend/src/components/resources/server/stats.tsx @@ -18,6 +18,7 @@ import { } from "@ui/select"; import { DockerResourceLink, ShowHideButton } from "@components/util"; import { filterBySplit } from "@lib/utils"; +import { useIsServerAvailable } from "."; export const ServerStats = ({ id, @@ -29,17 +30,23 @@ export const ServerStats = ({ const [interval, setInterval] = useStatsGranularity(); const { specific } = usePermissions({ type: "Server", id }); + const isServerAvailable = useIsServerAvailable(id); const stats = useRead( "GetSystemStats", { server: id }, - { refetchInterval: 10_000 } + { + enabled: isServerAvailable, + refetchInterval: 10_000 + } ).data; - const info = useRead("GetSystemInformation", { server: id }).data; + const info = useRead("GetSystemInformation", { server: id }, { enabled: isServerAvailable }).data; // Get all the containers with stats const containers = useRead("ListDockerContainers", { server: id, + }, { + enabled: isServerAvailable }).data?.filter((c) => c.stats); const [showContainers, setShowContainers] = useLocalStorage( "stats-show-container-table-v1", @@ -504,8 +511,8 @@ const LOAD_AVERAGE = ({ }) => { if (!stats?.load_average) return null; const { one = 0, five = 0, fifteen = 0 } = stats.load_average || {}; - const cores = useRead("GetSystemInformation", { server: id }).data - ?.core_count; + const isServerAvailable = useIsServerAvailable(id); + const cores = useRead("GetSystemInformation", { server: id }, { enabled: isServerAvailable }).data?.core_count; const pct = (load: number) => cores && cores > 0 ? Math.min((load / cores) * 100, 100) : undefined; diff --git a/frontend/src/components/resources/stack/info.tsx b/frontend/src/components/resources/stack/info.tsx index 4c497c311..d7a7e25ab 100644 --- a/frontend/src/components/resources/stack/info.tsx +++ b/frontend/src/components/resources/stack/info.tsx @@ -16,7 +16,7 @@ import { useLocalStorage, useWrite } from "@lib/hooks"; import { Button } from "@ui/button"; import { FilePlus, History } from "lucide-react"; import { useToast } from "@ui/use-toast"; -import { ConfirmButton, ShowHideButton } from "@components/util"; +import { ConfirmButton, ShowHideButton, CopyButton } from "@components/util"; import { DEFAULT_STACK_FILE_CONTENTS } from "./config"; import { Types } from "komodo_client"; @@ -205,55 +205,85 @@ export const StackInfo = ({ latest_contents.length > 0 && latest_contents.map((content) => { const showContents = show[content.path] ?? default_show_contents; + const handleToggleShow = () => { + setShow((show) => ({ + ...show, + [content.path]: !(show[content.path] ?? default_show_contents), + })); + }; return ( { + if ( + (e.key === "Enter" || e.key === " ") && + e.target === e.currentTarget + ) { + if (e.key === " ") e.preventDefault(); + handleToggleShow(); + } + }} > - -
      File:
      - {content.path} + +
      + File: + {content.path} + e.stopPropagation()} data-copy-button> + + +
      {canEdit && ( <> - { - if (stack) { - return await mutateAsync({ - stack: stack.name, - file_path: content.path, - contents: edits[content.path]!, - }).then(() => - setEdits({ ...edits, [content.path]: undefined }) - ); - } - }} - disabled={!edits[content.path]} - language="yaml" - loading={isPending} - /> + e.stopPropagation()}> + { + if (stack) { + return await mutateAsync({ + stack: stack.name, + file_path: content.path, + contents: edits[content.path]!, + }).then(() => + setEdits({ + ...edits, + [content.path]: undefined, + }) + ); + } + }} + disabled={!edits[content.path]} + language="yaml" + loading={isPending} + /> + )} setShow({ ...show, [content.path]: val })} + setShow={() => {}} />
      diff --git a/frontend/src/components/terminal/index.tsx b/frontend/src/components/terminal/index.tsx index 1ce3647b9..90d212207 100644 --- a/frontend/src/components/terminal/index.tsx +++ b/frontend/src/components/terminal/index.tsx @@ -31,14 +31,8 @@ export const Terminal = ({ _reconnect: boolean; _clear?: boolean; }) => { - const { theme: __theme } = useTheme(); - const _theme = - __theme === "system" - ? window.matchMedia("(prefers-color-scheme: dark)").matches - ? "dark" - : "light" - : __theme; - const theme = _theme === "dark" ? DARK_THEME : LIGHT_THEME; + const { currentTheme } = useTheme(); + const theme = currentTheme === "dark" ? DARK_THEME : LIGHT_THEME; const wsRef = useRef(null); const fitRef = useRef(new FitAddon()); diff --git a/frontend/src/components/topbar/components.tsx b/frontend/src/components/topbar/components.tsx index a4c46d08b..9c629ff60 100644 --- a/frontend/src/components/topbar/components.tsx +++ b/frontend/src/components/topbar/components.tsx @@ -239,50 +239,15 @@ export const UserDropdown = () => {
      - {accounts.map((login) => { - const selected = login.user_id === user?._id?.$oid; - return ( -
      - - - {viewLogout && ( - - )} -
      - ); - })} + {accounts.map((login) => ( + + ))} @@ -317,9 +282,66 @@ export const UserDropdown = () => { ); }; -const Username = ({ user_id }: { user_id: string }) => { - const res = useRead("GetUsername", { user_id }).data; - return ; +const Account = ({ + login, + current_id, + setOpen, + rerender, + viewLogout, +}: { + login: Types.JwtResponse; + current_id?: string; + setOpen: (open: boolean) => void; + rerender: () => void; + viewLogout: boolean; +}) => { + const res = useRead("GetUsername", { user_id: login.user_id }); + if (!res.data) return; + const selected = login.user_id === current_id; + return ( +
      + + + {viewLogout && ( + + )} +
      + ); }; const UsernameView = ({ diff --git a/frontend/src/lib/hooks.ts b/frontend/src/lib/hooks.ts index 434490389..23931f5bd 100644 --- a/frontend/src/lib/hooks.ts +++ b/frontend/src/lib/hooks.ts @@ -128,16 +128,21 @@ export const useLoginOptions = () => { export const useUser = () => { const userReset = useUserReset(); + const hasJwt = !!LOGIN_TOKENS.jwt(); + const query = useQuery({ queryKey: ["GetUser"], queryFn: () => komodo_client().auth("GetUser", {}), refetchInterval: 30_000, + enabled: hasJwt, }); + useEffect(() => { if (query.data && query.error) { userReset(); } }, [query.data, query.error]); + return query; }; @@ -173,9 +178,11 @@ export const useRead = < params: P, config?: C ) => { + const hasJwt = !!LOGIN_TOKENS.jwt(); return useQuery({ queryKey: [type, params], queryFn: () => komodo_client().read(type, params), + enabled: hasJwt && (config?.enabled !== false), ...config, }); }; diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index eb9fcd0b6..b88f60267 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -112,6 +112,11 @@ export default function Login() { login(creds); }; + const handleSubmit = (e: any) => { + e.preventDefault(); + handleLogin(); + }; + const handleSignUp = () => { const creds = getFormCredentials(); if (!creds) return; @@ -185,6 +190,7 @@ export default function Login() { {options?.local && (
      @@ -196,6 +202,7 @@ export default function Login() { autoComplete="username" autoCapitalize="none" autoCorrect="off" + autoFocus />
@@ -222,9 +229,8 @@ export default function Login() { )}