From e69b76791b7b59b6f7599a6110ff288d16e3652f Mon Sep 17 00:00:00 2001 From: MasterPtato <23087326+MasterPtato@users.noreply.github.com> Date: Fri, 2 Aug 2024 03:30:02 +0000 Subject: [PATCH] feat(workflows, clusters): add workflow backfill service (#1000) ## Changes --- docs/libraries/workflow/GOTCHAS.md | 4 - docs/libraries/workflow/LOOPS.md | 6 +- lib/bolt/Cargo.lock | 666 ++++++------ lib/chirp-workflow/core/src/ctx/backfill.rs | 384 +++++++ lib/chirp-workflow/core/src/ctx/mod.rs | 2 + lib/chirp-workflow/core/src/ctx/workflow.rs | 7 +- lib/chirp-workflow/core/src/error.rs | 6 +- lib/chirp-workflow/core/src/signal.rs | 2 +- lib/chirp-workflow/macros/src/lib.rs | 2 +- lib/runtime/src/lib.rs | 2 +- svc/Cargo.lock | 22 + svc/Cargo.toml | 1 + .../cluster/src/workflows/datacenter/mod.rs | 2 - .../cluster/src/workflows/datacenter/scale.rs | 8 +- .../src/workflows/datacenter/tls_issue.rs | 4 +- svc/pkg/cluster/src/workflows/server/mod.rs | 75 +- .../standalone/workflow-backfill/Cargo.toml | 31 + .../standalone/workflow-backfill/Service.toml | 11 + .../standalone/workflow-backfill/src/lib.rs | 996 ++++++++++++++++++ .../standalone/workflow-backfill/src/main.rs | 15 + svc/pkg/linode/src/workflows/server/mod.rs | 2 + 21 files changed, 1853 insertions(+), 395 deletions(-) create mode 100644 lib/chirp-workflow/core/src/ctx/backfill.rs create mode 100644 svc/pkg/cluster/standalone/workflow-backfill/Cargo.toml create mode 100644 svc/pkg/cluster/standalone/workflow-backfill/Service.toml create mode 100644 svc/pkg/cluster/standalone/workflow-backfill/src/lib.rs create mode 100644 svc/pkg/cluster/standalone/workflow-backfill/src/main.rs diff --git a/docs/libraries/workflow/GOTCHAS.md b/docs/libraries/workflow/GOTCHAS.md index e9101185e0..1d81bca877 100644 --- a/docs/libraries/workflow/GOTCHAS.md +++ b/docs/libraries/workflow/GOTCHAS.md @@ -108,7 +108,3 @@ the internal location. > **\*** Even if they did know about each other via atomics, there is no guarantee of consistency from > `buffer_unordered`. Preemptively incrementing the location ensures consistency regardless of the order or > completion time of the futures. - -## Loops - -TODO diff --git a/docs/libraries/workflow/LOOPS.md b/docs/libraries/workflow/LOOPS.md index a84c282b52..3291944630 100644 --- a/docs/libraries/workflow/LOOPS.md +++ b/docs/libraries/workflow/LOOPS.md @@ -6,4 +6,8 @@ TODO https://docs.temporal.io/develop/go/continue-as-new -TODO +Continue As New effectively wipes the entire history of the workflow, allowing you to start from scratch when +needed. + +With loops, only the history of previous completed iterations of the loop is forgotten. This is because it is +assumed there are no side effects from the loop, meaning previous iterations have no effect on the workflow. diff --git a/lib/bolt/Cargo.lock b/lib/bolt/Cargo.lock index 0a327a0b5c..0486b32444 100644 --- a/lib/bolt/Cargo.lock +++ b/lib/bolt/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -43,47 +43,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -91,9 +92,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "async-posthog" @@ -121,13 +122,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -143,9 +144,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-endpoint" @@ -356,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "987b1e37febb9bd409ca0846e82d35299e572ad8279bc404778caeb5fc05ad56" dependencies = [ "base64-simd", - "itoa 1.0.10", + "itoa 1.0.11", "num-integer", "ryu", "time", @@ -389,9 +390,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -431,9 +432,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -498,7 +499,7 @@ dependencies = [ "handlebars", "heck 0.3.3", "hex", - "indexmap 2.2.3", + "indexmap 2.2.6", "indicatif", "indoc", "ipnet", @@ -530,21 +531,21 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c764d619ca78fccbf3069b37bd7af92577f044bb15236036662d79b6559f25b7" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "bytes-utils" @@ -558,9 +559,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.86" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -570,9 +571,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -580,7 +581,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -597,9 +598,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ "clap_builder", "clap_derive", @@ -607,39 +608,39 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.0", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "console" @@ -681,18 +682,18 @@ dependencies = [ [[package]] name = "crc32c" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89254598aa9b9fa608de44b3ae54c810f0f06d755e24c50177f1f8f31ff50ce2" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" dependencies = [ "rustc_version", ] [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -719,12 +720,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.8", - "darling_macro 0.20.8", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -743,16 +744,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 2.0.50", + "strsim 0.11.1", + "syn 2.0.72", ] [[package]] @@ -768,13 +769,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.8", + "darling_core 0.20.10", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -843,9 +844,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -855,9 +856,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -870,9 +871,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -889,9 +890,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fnv" @@ -946,7 +947,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -987,9 +988,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -998,15 +999,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1014,7 +1015,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.3", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1043,9 +1044,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -1062,6 +1063,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1073,9 +1080,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1094,13 +1101,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", - "itoa 1.0.10", + "itoa 1.0.11", ] [[package]] @@ -1116,9 +1123,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1128,9 +1135,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -1141,7 +1148,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.10", + "itoa 1.0.11", "pin-project-lite", "socket2", "tokio", @@ -1175,7 +1182,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.10", + "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", ] @@ -1245,12 +1252,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1273,9 +1280,9 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -1289,6 +1296,12 @@ dependencies = [ "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -1306,54 +1319,53 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "json-patch" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" dependencies = [ "serde", "serde_json", "thiserror", - "treediff", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1361,9 +1373,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "maplit" @@ -1383,9 +1395,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -1395,9 +1407,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -1405,31 +1417,31 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1458,23 +1470,13 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.6", - "libc", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -1483,9 +1485,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.2" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -1498,11 +1500,11 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -1519,7 +1521,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -1530,9 +1532,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.100" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae94056a791d0e1217d18b6cbdccb02c61e3054fc69893607f4067e3bb0b1fd1" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -1542,9 +1544,9 @@ dependencies = [ [[package]] name = "os_pipe" -version = "1.1.5" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1569,9 +1571,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1579,15 +1581,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1598,9 +1600,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -1609,9 +1611,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -1619,22 +1621,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "pest_meta" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -1643,29 +1645,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1737,9 +1739,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1769,9 +1771,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1808,18 +1810,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1829,9 +1831,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1840,15 +1842,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -1870,7 +1872,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", @@ -1947,9 +1949,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" @@ -1962,11 +1964,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1987,9 +1989,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", @@ -2030,15 +2032,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "s3-util" @@ -2081,11 +2083,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -2094,9 +2096,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -2104,37 +2106,37 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ - "itoa 1.0.10", + "itoa 1.0.11", "ryu", "serde", ] @@ -2150,9 +2152,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -2164,7 +2166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.10", + "itoa 1.0.11", "ryu", "serde", ] @@ -2191,20 +2193,20 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.8", + "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "serde_yaml" -version = "0.9.32" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.3", - "itoa 1.0.10", + "indexmap 2.2.6", + "itoa 1.0.11", "ryu", "serde", "unsafe-libyaml", @@ -2244,9 +2246,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2271,18 +2273,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2305,9 +2307,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -2325,14 +2327,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -2347,9 +2349,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.50" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -2409,12 +2411,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", + "fastrand 2.1.0", "rustix", "windows-sys 0.52.0", ] @@ -2431,32 +2433,32 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", - "itoa 1.0.10", + "itoa 1.0.11", "num-conv", "powerfmt", "serde", @@ -2472,9 +2474,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -2482,9 +2484,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2497,32 +2499,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -2552,15 +2553,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -2569,16 +2570,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -2595,9 +2595,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] @@ -2608,7 +2608,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -2663,7 +2663,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", ] [[package]] @@ -2675,15 +2675,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "treediff" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d127780145176e2b5d16611cc25a900150e86e9fd79d3bde6ff3a37359c9cb5" -dependencies = [ - "serde_json", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -2740,15 +2731,15 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "untrusted" @@ -2764,9 +2755,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -2781,15 +2772,15 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "serde", @@ -2824,9 +2815,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2834,24 +2825,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -2861,9 +2852,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2871,28 +2862,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2925,9 +2916,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "wildmatch" -version = "2.3.0" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb" +checksum = "3928939971918220fed093266b809d1ee4ec6c1a2d72692ff6876898f3b16c19" [[package]] name = "winapi" @@ -2957,7 +2948,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -2975,7 +2966,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -2995,17 +2986,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3016,9 +3008,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3028,9 +3020,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3040,9 +3032,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3052,9 +3050,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3064,9 +3062,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3076,9 +3074,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3088,9 +3086,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -3119,6 +3117,6 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/lib/chirp-workflow/core/src/ctx/backfill.rs b/lib/chirp-workflow/core/src/ctx/backfill.rs new file mode 100644 index 0000000000..8310667eb5 --- /dev/null +++ b/lib/chirp-workflow/core/src/ctx/backfill.rs @@ -0,0 +1,384 @@ +use futures_util::FutureExt; +use global_error::unwrap_ref; +use global_error::GlobalResult; +use indoc::indoc; +use serde::Serialize; +use std::{ + collections::hash_map::DefaultHasher, + future::Future, + hash::{Hash, Hasher}, + pin::Pin, +}; +use uuid::Uuid; + +use crate::util::Location; + +// Yes +type Query = Box< + dyn for<'a> FnOnce( + &'a mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Pin> + Send + 'a>>, +>; + +pub struct BackfillCtx { + queries: Vec, +} + +impl BackfillCtx { + pub fn new() -> Self { + BackfillCtx { + queries: Vec::new(), + } + } + + pub async fn execute(self, tx: &mut sqlx::Transaction<'_, sqlx::Postgres>) -> GlobalResult<()> { + tracing::info!(queries=%self.queries.len(), "executing backfill queries"); + + for query in self.queries { + query(tx).await?; + } + + Ok(()) + } +} + +impl BackfillCtx { + pub fn workflow(&mut self, workflow_name: &str, builder: F) -> GlobalResult + where + F: Fn(&mut WorkflowBackfillCtx) -> GlobalResult<()>, + { + let mut wf_ctx = WorkflowBackfillCtx::new(workflow_name); + let workflow_id = wf_ctx.workflow_id; + + builder(&mut wf_ctx)?; + + self.queries.extend(wf_ctx.queries); + + Ok(workflow_id) + } +} + +pub struct WorkflowBackfillCtx { + workflow_id: Uuid, + workflow_name: String, + + root_location: Location, + location_idx: usize, + + tags: Option, + input: Option, + output: Option, + + queries: Vec, +} + +impl WorkflowBackfillCtx { + fn new(workflow_name: &str) -> Self { + WorkflowBackfillCtx { + workflow_id: Uuid::new_v4(), + workflow_name: workflow_name.to_string(), + + root_location: Box::new([]), + location_idx: 0, + + tags: None, + input: None, + output: None, + + queries: Vec::new(), + } + } + + fn branch(&mut self) -> Self { + let branch = WorkflowBackfillCtx { + workflow_id: self.workflow_id, + workflow_name: self.workflow_name.clone(), + + root_location: self + .root_location + .iter() + .cloned() + .chain(std::iter::once(self.location_idx)) + .collect(), + location_idx: 0, + + tags: None, + input: None, + output: None, + + queries: Vec::new(), + }; + + self.location_idx += 1; + + branch + } + + fn full_location(&self) -> Vec { + self.root_location + .iter() + .cloned() + .map(|x| x as i64) + .chain(std::iter::once(self.location_idx as i64)) + .collect() + } + + pub fn finalize(&mut self) { + let wake_immediate = true; + + let workflow_id = self.workflow_id; + let workflow_name = self.workflow_name.clone(); + let tags = std::mem::replace(&mut self.tags, Default::default()); + let input = std::mem::replace(&mut self.input, Default::default()); + let output = std::mem::replace(&mut self.output, Default::default()); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflows ( + workflow_id, workflow_name, create_ts, ray_id, tags, input, output, wake_immediate + ) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + " + )) + .bind(workflow_id) + .bind(workflow_name) + .bind(rivet_util::timestamp::now()) + .bind(Uuid::new_v4()) + .bind(tags) + .bind(unwrap_ref!(input, "workflow backfill must have input")) + .bind(output) + .bind(wake_immediate) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + } +} + +impl WorkflowBackfillCtx { + pub fn tags(&mut self, tags: T) -> GlobalResult<()> { + self.tags = Some(serde_json::to_value(&tags)?); + + Ok(()) + } + + pub fn input(&mut self, input: T) -> GlobalResult<()> { + self.input = Some(serde_json::to_value(&input)?); + + Ok(()) + } + + pub fn output(&mut self, output: T) -> GlobalResult<()> { + self.output = Some(serde_json::to_value(&output)?); + + Ok(()) + } + + pub fn activity( + &mut self, + activity_name: &str, + input: T, + output: U, + ) -> GlobalResult<()> { + let mut hasher = DefaultHasher::new(); + input.hash(&mut hasher); + let input_hash = hasher.finish(); + + let workflow_id = self.workflow_id; + let location = self.full_location(); + let activity_name = activity_name.to_string(); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflow_activity_events ( + workflow_id, location, activity_name, input_hash, input, output, create_ts + ) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ", + )) + .bind(workflow_id) + .bind(location) + .bind(activity_name) + .bind(input_hash.to_le_bytes()) + .bind(serde_json::to_value(&input)?) + .bind(serde_json::to_value(&output)?) + .bind(rivet_util::timestamp::now()) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + + self.location_idx += 1; + + Ok(()) + } + + pub fn message( + &mut self, + message_name: &str, + tags: serde_json::Value, + body: T, + ) -> GlobalResult<()> { + let workflow_id = self.workflow_id; + let location = self.full_location(); + let message_name = message_name.to_string(); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflow_message_send_events ( + workflow_id, location, tags, message_name, body + ) + VALUES ($1, $2, $3, $4, $5) + " + )) + .bind(workflow_id) + .bind(location) + .bind(&tags) + .bind(message_name) + .bind(serde_json::to_value(&body)?) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + + self.location_idx += 1; + + Ok(()) + } + + pub fn signal( + &mut self, + signal_name: &str, + body: T, + ) -> GlobalResult<()> { + let workflow_id = self.workflow_id; + let location = self.full_location(); + let signal_name = signal_name.to_string(); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflow_signal_send_events ( + workflow_id, location, signal_id, signal_name, body + ) + VALUES ($1, $2, $3, $4, $5) + " + )) + .bind(workflow_id) + .bind(location) + .bind(Uuid::new_v4()) + .bind(signal_name) + .bind(serde_json::to_value(&body)?) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + + self.location_idx += 1; + + Ok(()) + } + + pub fn sub_workflow(&mut self, builder: F) -> GlobalResult<()> + where + F: Fn(&mut WorkflowBackfillCtx) -> GlobalResult<()>, + { + let mut swf_ctx = self.branch(); + + builder(&mut swf_ctx)?; + + self.queries.extend(swf_ctx.queries); + + self.location_idx += 1; + + Ok(()) + } + + pub fn dispatch_sub_workflow(&mut self, sub_workflow_id: Uuid) -> GlobalResult<()> { + let workflow_id = self.workflow_id; + let location = self.full_location(); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflow_sub_workflow_events( + workflow_id, location, sub_workflow_id, create_ts + ) + VALUES($1, $2, $3, $4) + " + )) + .bind(workflow_id) + .bind(location) + .bind(sub_workflow_id) + .bind(rivet_util::timestamp::now()) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + + self.location_idx += 1; + + Ok(()) + } + + pub fn listen( + &mut self, + signal_name: &str, + body: T, + ) -> GlobalResult<()> { + let workflow_id = self.workflow_id; + let location = self.full_location(); + let signal_name = signal_name.to_string(); + + self.queries.push(Box::new(move |tx| { + async move { + sqlx::query(indoc!( + " + INSERT INTO db_workflow.workflow_signal_events ( + workflow_id, location, signal_id, signal_name, body, ack_ts + ) + VALUES ($1, $2, $3, $4, $5, $6) + " + )) + .bind(workflow_id) + .bind(location) + .bind(Uuid::new_v4()) + .bind(signal_name) + .bind(serde_json::to_value(&body)?) + .bind(rivet_util::timestamp::now()) + .execute(&mut **tx) + .await?; + + Ok(()) + } + .boxed() + })); + + self.location_idx += 1; + + Ok(()) + } +} diff --git a/lib/chirp-workflow/core/src/ctx/mod.rs b/lib/chirp-workflow/core/src/ctx/mod.rs index 7850baad93..97d6695cc8 100644 --- a/lib/chirp-workflow/core/src/ctx/mod.rs +++ b/lib/chirp-workflow/core/src/ctx/mod.rs @@ -1,5 +1,6 @@ mod activity; pub(crate) mod api; +mod backfill; mod listen; pub mod message; mod operation; @@ -8,6 +9,7 @@ mod test; pub(crate) mod workflow; pub use activity::ActivityCtx; pub use api::ApiCtx; +pub use backfill::BackfillCtx; pub use listen::ListenCtx; pub use message::MessageCtx; pub use operation::OperationCtx; diff --git a/lib/chirp-workflow/core/src/ctx/workflow.rs b/lib/chirp-workflow/core/src/ctx/workflow.rs index 35fedca730..14e7b321b5 100644 --- a/lib/chirp-workflow/core/src/ctx/workflow.rs +++ b/lib/chirp-workflow/core/src/ctx/workflow.rs @@ -636,8 +636,11 @@ impl WorkflowCtx { if activity.activity_id != activity_id { return Err(WorkflowError::HistoryDiverged(format!( - "expected {event}, found activity {}", - activity_id.name + "expected activity {}#{:x}, found activity {}#{:x}", + activity.activity_id.name, + activity.activity_id.input_hash, + activity_id.name, + activity_id.input_hash, ))) .map_err(GlobalError::raw); } diff --git a/lib/chirp-workflow/core/src/error.rs b/lib/chirp-workflow/core/src/error.rs index 50d7b181ed..dd5fa51486 100644 --- a/lib/chirp-workflow/core/src/error.rs +++ b/lib/chirp-workflow/core/src/error.rs @@ -155,9 +155,9 @@ impl WorkflowError { pub fn is_recoverable(&self) -> bool { match self { - WorkflowError::ActivityFailure(_, _) => true, - WorkflowError::ActivityTimeout => true, - WorkflowError::OperationTimeout => true, + WorkflowError::ActivityFailure(_, _) + | WorkflowError::ActivityTimeout + | WorkflowError::OperationTimeout => true, _ => false, } } diff --git a/lib/chirp-workflow/core/src/signal.rs b/lib/chirp-workflow/core/src/signal.rs index 0791f6fee7..40ea68376a 100644 --- a/lib/chirp-workflow/core/src/signal.rs +++ b/lib/chirp-workflow/core/src/signal.rs @@ -67,7 +67,7 @@ macro_rules! join_signal { Ok( Self::$signals( serde_json::from_value(body) - .map_err(WorkflowError::DeserializeActivityOutput)? + .map_err(WorkflowError::DeserializeSignalBody)? ) ) } diff --git a/lib/chirp-workflow/macros/src/lib.rs b/lib/chirp-workflow/macros/src/lib.rs index 74184b4222..e2a886e10b 100644 --- a/lib/chirp-workflow/macros/src/lib.rs +++ b/lib/chirp-workflow/macros/src/lib.rs @@ -312,7 +312,7 @@ pub fn signal(attr: TokenStream, item: TokenStream) -> TokenStream { } fn parse(_name: &str, body: serde_json::Value) -> chirp_workflow::prelude::WorkflowResult { - serde_json::from_value(body).map_err(WorkflowError::DeserializeActivityOutput) + serde_json::from_value(body).map_err(WorkflowError::DeserializeSignalBody) } } }; diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 0e6ff7fceb..6331c0c8f2 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -1,7 +1,7 @@ use std::{env, future::Future, sync::Once, time::Duration}; use thiserror::Error; -use tracing_subscriber::{fmt::writer::MakeWriterExt, prelude::*}; +use tracing_subscriber::prelude::*; mod metrics; diff --git a/svc/Cargo.lock b/svc/Cargo.lock index 01e1fac5f4..a359372a2f 100644 --- a/svc/Cargo.lock +++ b/svc/Cargo.lock @@ -2583,6 +2583,28 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "cluster-workflow-backfill" +version = "0.0.1" +dependencies = [ + "chirp-client", + "chirp-workflow", + "cluster", + "linode", + "rivet-connection", + "rivet-health-checks", + "rivet-metrics", + "rivet-operation", + "rivet-runtime", + "serde", + "sqlx 0.7.4 (git+https://github.com/rivet-gg/sqlx?rev=08d6e61aa0572e7ec557abbedb72cebb96e1ac5b)", + "token-create", + "tokio", + "tracing", + "tracing-logfmt", + "tracing-subscriber", +] + [[package]] name = "combine" version = "4.6.7" diff --git a/svc/Cargo.toml b/svc/Cargo.toml index 238cd0e2d2..84a7e79d3e 100644 --- a/svc/Cargo.toml +++ b/svc/Cargo.toml @@ -66,6 +66,7 @@ members = [ "pkg/cluster/standalone/default-update", "pkg/cluster/standalone/gc", "pkg/cluster/standalone/metrics-publish", + "pkg/cluster/standalone/workflow-backfill", "pkg/custom-user-avatar/ops/list-for-game", "pkg/custom-user-avatar/ops/upload-complete", "pkg/debug/ops/email-res", diff --git a/svc/pkg/cluster/src/workflows/datacenter/mod.rs b/svc/pkg/cluster/src/workflows/datacenter/mod.rs index 8e18185b52..c0a54a612f 100644 --- a/svc/pkg/cluster/src/workflows/datacenter/mod.rs +++ b/svc/pkg/cluster/src/workflows/datacenter/mod.rs @@ -63,7 +63,6 @@ pub(crate) async fn cluster_datacenter(ctx: &mut WorkflowCtx, input: &Input) -> ctx.repeat(|ctx| { let datacenter_id = input.datacenter_id; - let provider = input.provider.clone(); async move { match ctx.listen::
().await? { @@ -90,7 +89,6 @@ pub(crate) async fn cluster_datacenter(ctx: &mut WorkflowCtx, input: &Input) -> datacenter_id, server_id: sig.server_id, pool_type: sig.pool_type, - provider: provider.clone(), tags: sig.tags, }, ) diff --git a/svc/pkg/cluster/src/workflows/datacenter/scale.rs b/svc/pkg/cluster/src/workflows/datacenter/scale.rs index 4c6b89f11f..f38e041ebf 100644 --- a/svc/pkg/cluster/src/workflows/datacenter/scale.rs +++ b/svc/pkg/cluster/src/workflows/datacenter/scale.rs @@ -19,7 +19,7 @@ use chirp_workflow::prelude::*; use futures_util::{FutureExt, StreamExt, TryStreamExt}; use serde_json::json; -use crate::types::{Datacenter, PoolType, Provider}; +use crate::types::{Datacenter, PoolType}; #[derive(sqlx::FromRow)] struct ServerRow { @@ -76,7 +76,6 @@ enum DrainState { struct PoolCtx { datacenter_id: Uuid, - provider: Provider, pool_type: PoolType, desired_count: usize, } @@ -125,7 +124,6 @@ enum Action { Provision { server_id: Uuid, pool_type: PoolType, - provider: Provider, }, Drain { server_id: Uuid, @@ -144,7 +142,6 @@ impl Action { Action::Provision { server_id, pool_type, - provider, } => { ctx.dispatch_tagged_workflow( &json!({ @@ -154,7 +151,6 @@ impl Action { datacenter_id, server_id, pool_type, - provider, tags: Vec::new(), }, ) @@ -275,7 +271,6 @@ async fn inner( for pool in &dc.pools { let pool_ctx = PoolCtx { datacenter_id: dc.datacenter_id, - provider: dc.provider.clone(), pool_type: pool.pool_type.clone(), desired_count: pool.desired_count.max(pool.min_count).min(pool.max_count) as usize, }; @@ -748,7 +743,6 @@ async fn provision_server( actions.push(Action::Provision { server_id, pool_type: pctx.pool_type.clone(), - provider: pctx.provider.clone(), }); Ok(()) diff --git a/svc/pkg/cluster/src/workflows/datacenter/tls_issue.rs b/svc/pkg/cluster/src/workflows/datacenter/tls_issue.rs index d2cb818543..5fd1f73515 100644 --- a/svc/pkg/cluster/src/workflows/datacenter/tls_issue.rs +++ b/svc/pkg/cluster/src/workflows/datacenter/tls_issue.rs @@ -87,7 +87,7 @@ struct OrderOutput { } #[activity(Order)] -#[timeout = 90] +#[timeout = 130] async fn order(ctx: &ActivityCtx, input: &OrderInput) -> GlobalResult { let client = cf_client().await?; @@ -304,7 +304,7 @@ async fn poll_txt_dns(hostname: &str, content: &str) -> GlobalResult<()> { let fqdn = format!("{hostname}."); // Retry DNS until the TXT record shows up - for attempt in 1..=100 { + for attempt in 1..=60 { tokio::time::sleep(std::time::Duration::from_secs(2)).await; tracing::info!(%attempt, %fqdn, "attempting to resolve dns"); diff --git a/svc/pkg/cluster/src/workflows/server/mod.rs b/svc/pkg/cluster/src/workflows/server/mod.rs index 9f541150ab..4d61ebe158 100644 --- a/svc/pkg/cluster/src/workflows/server/mod.rs +++ b/svc/pkg/cluster/src/workflows/server/mod.rs @@ -22,7 +22,6 @@ use crate::{ pub(crate) struct Input { pub datacenter_id: Uuid, pub server_id: Uuid, - pub provider: Provider, pub pool_type: PoolType, pub tags: Vec, } @@ -54,7 +53,7 @@ pub(crate) async fn cluster_server(ctx: &mut WorkflowCtx, input: &Input) -> Glob .activity(GetPrebakeInput { datacenter_id: input.datacenter_id, pool_type: input.pool_type.clone(), - provider: input.provider.clone(), + provider: dc.provider.clone(), }) .await?; @@ -62,7 +61,7 @@ pub(crate) async fn cluster_server(ctx: &mut WorkflowCtx, input: &Input) -> Glob if image_res.updated { ctx.dispatch_workflow(crate::workflows::prebake::Input { datacenter_id: input.datacenter_id, - provider: input.provider.clone(), + provider: dc.provider.clone(), pool_type: input.pool_type.clone(), install_script_hash: crate::util::INSTALL_SCRIPT_HASH.to_string(), tags: Vec::new(), @@ -90,7 +89,7 @@ pub(crate) async fn cluster_server(ctx: &mut WorkflowCtx, input: &Input) -> Glob hardware.provider_hardware, ); - match input.provider { + match dc.provider { Provider::Linode => { let workflow_id = ctx .dispatch_tagged_workflow( @@ -146,7 +145,9 @@ pub(crate) async fn cluster_server(ctx: &mut WorkflowCtx, input: &Input) -> Glob datacenter_id: dc.datacenter_id, provider_datacenter_id: dc.provider_datacenter_id.clone(), datacenter_name_id: dc.name_id.clone(), - provision_res, + provider_server_id: provision_res.provider_server_id.clone(), + provider_hardware: provision_res.provider_hardware.clone(), + public_ip: provision_res.public_ip, already_installed, }) .await?; @@ -266,36 +267,34 @@ pub(crate) async fn cluster_server(ctx: &mut WorkflowCtx, input: &Input) -> Glob .await?; } Main::Taint(_) => {} // Only for state - Main::Destroy(_) => { - if let PoolType::Gg = input.pool_type { - ctx.workflow(dns_delete::Input { - server_id: input.server_id, - }) - .await?; - } + Main::Destroy(_) => break, + } + } - match input.provider { - Provider::Linode => { - tracing::info!(server_id=?input.server_id, "destroying linode server"); - - ctx.tagged_signal( - &json!({ - "server_id": input.server_id, - }), - linode::workflows::server::Destroy {}, - ) - .await?; - - // Wait for workflow to complete - ctx.wait_for_workflow::( - provider_server_workflow_id, - ) - .await?; - } - } + if let PoolType::Gg = input.pool_type { + ctx.workflow(dns_delete::Input { + server_id: input.server_id, + }) + .await?; + } - break; - } + match dc.provider { + Provider::Linode => { + tracing::info!(server_id=?input.server_id, "destroying linode server"); + + ctx.tagged_signal( + &json!({ + "server_id": input.server_id, + }), + linode::workflows::server::Destroy {}, + ) + .await?; + + // Wait for workflow to complete + ctx.wait_for_workflow::( + provider_server_workflow_id, + ) + .await?; } } @@ -474,7 +473,9 @@ struct UpdateDbInput { datacenter_id: Uuid, provider_datacenter_id: String, datacenter_name_id: String, - provision_res: ProvisionResponse, + provider_server_id: String, + provider_hardware: String, + public_ip: Ipv4Addr, already_installed: bool, } @@ -496,9 +497,9 @@ async fn update_db(ctx: &ActivityCtx, input: &UpdateDbInput) -> GlobalResult<()> RETURNING create_ts ", input.server_id, - &input.provision_res.provider_server_id, - &input.provision_res.provider_hardware, - IpAddr::V4(input.provision_res.public_ip), + &input.provider_server_id, + &input.provider_hardware, + IpAddr::V4(input.public_ip), provision_complete_ts, if input.already_installed { Some(provision_complete_ts) diff --git a/svc/pkg/cluster/standalone/workflow-backfill/Cargo.toml b/svc/pkg/cluster/standalone/workflow-backfill/Cargo.toml new file mode 100644 index 0000000000..3ac53a570c --- /dev/null +++ b/svc/pkg/cluster/standalone/workflow-backfill/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "cluster-workflow-backfill" +version = "0.0.1" +edition = "2018" +authors = ["Rivet Gaming, LLC "] +license = "Apache-2.0" + +[dependencies] +chirp-client = { path = "../../../../../lib/chirp/client" } +chirp-workflow = { path = "../../../../../lib/chirp-workflow/core" } +rivet-connection = { path = "../../../../../lib/connection" } +rivet-health-checks = { path = "../../../../../lib/health-checks" } +rivet-metrics = { path = "../../../../../lib/metrics" } +rivet-operation = { path = "../../../../../lib/operation/core" } +rivet-runtime = { path = "../../../../../lib/runtime" } +serde = { version = "1.0", features = ["derive"] } +tokio = { version = "1.29", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] } +tracing-logfmt = "0.3" + +cluster = { path = "../.." } +linode = { path = "../../../linode" } +token-create = { path = "../../../token/ops/create" } + +[dependencies.sqlx] +git = "https://github.com/rivet-gg/sqlx" +rev = "08d6e61aa0572e7ec557abbedb72cebb96e1ac5b" +default-features = false + +[dev-dependencies] diff --git a/svc/pkg/cluster/standalone/workflow-backfill/Service.toml b/svc/pkg/cluster/standalone/workflow-backfill/Service.toml new file mode 100644 index 0000000000..4a7f0beb5e --- /dev/null +++ b/svc/pkg/cluster/standalone/workflow-backfill/Service.toml @@ -0,0 +1,11 @@ +[service] +name = "cluster-workflow-backfill" + +[runtime] +kind = "rust" + +[oneshot] + +[databases] +db-cluster = {} +db-workflow = {} diff --git a/svc/pkg/cluster/standalone/workflow-backfill/src/lib.rs b/svc/pkg/cluster/standalone/workflow-backfill/src/lib.rs new file mode 100644 index 0000000000..6433312627 --- /dev/null +++ b/svc/pkg/cluster/standalone/workflow-backfill/src/lib.rs @@ -0,0 +1,996 @@ +use std::{ + convert::TryInto, + net::{IpAddr, Ipv4Addr}, +}; + +use chirp_workflow::prelude::*; +use rivet_operation::prelude::{proto::backend, Message}; +use serde::Serialize; +use serde_json::json; + +#[tracing::instrument(skip_all)] +pub async fn run_from_env() -> GlobalResult<()> { + let pools = rivet_pools::from_env("cluster-workflow-backfill").await?; + let client = + chirp_client::SharedClient::from_env(pools.clone())?.wrap_new("cluster-workflow-backfill"); + let cache = rivet_cache::CacheInner::from_env(pools.clone())?; + let ctx = StandaloneCtx::new( + chirp_workflow::compat::db_from_pools(&pools).await?, + rivet_connection::Connection::new(client, pools, cache), + "cluster-workflow-backfill", + ) + .await?; + + let crdb = ctx.crdb().await?; + let mut tx = crdb.begin().await?; + + let mut bctx = BackfillCtx::new(); + + #[derive(sqlx::FromRow)] + struct ClusterRow { + cluster_id: Uuid, + name_id: String, + owner_team_id: Option, + } + + let cluster_rows = sql_fetch_all!( + [ctx, ClusterRow, @tx &mut tx] + " + SELECT + cluster_id, + name_id, + owner_team_id + FROM db_cluster.clusters + ", + ) + .await?; + + for cluster in cluster_rows { + bctx.workflow("cluster", |wf| { + wf.tags(json!({ + "cluster_id": cluster.cluster_id, + }))?; + wf.input(cluster::workflows::cluster::Input { + cluster_id: cluster.cluster_id, + name_id: cluster.name_id.clone(), + owner_team_id: cluster.owner_team_id, + })?; + wf.finalize(); + + #[derive(Serialize, Hash)] + struct InsertDbInput { + cluster_id: Uuid, + name_id: String, + owner_team_id: Option, + } + + wf.activity( + "insert_db", + InsertDbInput { + cluster_id: cluster.cluster_id, + name_id: cluster.name_id.clone(), + owner_team_id: cluster.owner_team_id, + }, + serde_json::Value::Null, + )?; + + wf.message( + "cluster-create-complete", + json!({ + "cluster_id": cluster.cluster_id, + }), + cluster::workflows::cluster::CreateComplete {}, + )?; + + Ok(()) + })?; + } + + #[derive(sqlx::FromRow, Clone)] + struct DcRow { + datacenter_id: Uuid, + cluster_id: Uuid, + name_id: String, + display_name: String, + provider: i64, + provider_datacenter_id: String, + provider_api_token: Option, + pools: Vec, + build_delivery_method: i64, + } + #[derive(sqlx::FromRow)] + struct DcTlsRow { + datacenter_id: Uuid, + gg_cert_pem: Option, + gg_private_key_pem: Option, + job_cert_pem: Option, + job_private_key_pem: Option, + expire_ts: i64, + } + + let dc_rows = sql_fetch_all!( + [ctx, DcRow, @tx &mut tx] + " + SELECT + datacenter_id, + cluster_id, + name_id, + display_name, + provider_datacenter_id, + provider_api_token, + create_ts, + provider, + pools, + build_delivery_method + FROM db_cluster.datacenters + ", + ) + .await?; + let dc_tls_rows = sql_fetch_all!( + [ctx, DcTlsRow, @tx &mut tx] + " + SELECT + datacenter_id, + gg_cert_pem, + gg_private_key_pem, + job_cert_pem, + job_private_key_pem, + expire_ts + FROM db_cluster.datacenter_tls + ", + ) + .await?; + + for dc in dc_rows.clone() { + let tls = unwrap!(dc_tls_rows + .iter() + .find(|dc_tls| dc_tls.datacenter_id == dc.datacenter_id)); + + bctx.workflow("cluster_datacenter", |wf| { + wf.tags(json!({ + "datacenter_id": dc.datacenter_id, + }))?; + wf.input(json!({ + "cluster_id": dc.cluster_id, + "datacenter_id": dc.datacenter_id, + "name_id": dc.name_id.clone(), + "display_name": dc.display_name.clone(), + + "provider": TryInto::::try_into(dc.provider)?, + "provider_datacenter_id": dc.provider_datacenter_id.clone(), + "provider_api_token": dc.provider_api_token.clone(), + + "pools": ({ + let proto = backend::cluster::Pools::decode(dc.pools.as_slice())?.pools; + + proto + .into_iter() + .map(TryInto::::try_into) + .collect::>>()? + }), + + "build_delivery_method": + TryInto::::try_into(dc.build_delivery_method)?, + "prebakes_enabled": false, + }))?; + wf.finalize(); + + #[derive(Serialize, Hash)] + struct InsertDbInput { + cluster_id: Uuid, + datacenter_id: Uuid, + name_id: String, + display_name: String, + + provider: cluster::types::Provider, + provider_datacenter_id: String, + provider_api_token: Option, + + pools: Vec, + + build_delivery_method: cluster::types::BuildDeliveryMethod, + prebakes_enabled: bool, + } + + wf.activity( + "insert_db", + InsertDbInput { + cluster_id: dc.cluster_id, + datacenter_id: dc.datacenter_id, + name_id: dc.name_id.clone(), + display_name: dc.display_name.clone(), + + provider: dc.provider.try_into()?, + provider_datacenter_id: dc.provider_datacenter_id.clone(), + provider_api_token: dc.provider_api_token.clone(), + + pools: { + let proto = backend::cluster::Pools::decode(dc.pools.as_slice())?.pools; + + proto + .into_iter() + .map(TryInto::try_into) + .collect::>>()? + }, + + build_delivery_method: dc.build_delivery_method.try_into()?, + prebakes_enabled: false, + }, + serde_json::Value::Null, + )?; + + // Tls issue + if let ( + Some(gg_cert_pem), + Some(gg_private_key_pem), + Some(job_cert_pem), + Some(job_private_key_pem), + ) = ( + &tls.gg_cert_pem, + &tls.gg_private_key_pem, + &tls.job_cert_pem, + &tls.job_private_key_pem, + ) { + wf.sub_workflow(|swf| { + let base_zone_id = unwrap!( + util::env::cloudflare::zone::main::id(), + "dns not configured" + ); + let job_zone_id = + unwrap!(util::env::cloudflare::zone::job::id(), "dns not configured"); + let domain_main = unwrap!(util::env::domain_main(), "dns not enabled"); + let domain_job = unwrap!(util::env::domain_job(), "dns not enabled"); + + #[derive(Serialize, Hash)] + struct OrderInput { + renew: bool, + zone_id: String, + common_name: String, + subject_alternative_names: Vec, + } + + swf.activity( + "order", + OrderInput { + renew: false, + zone_id: base_zone_id.to_string(), + common_name: domain_main.to_string(), + subject_alternative_names: vec![format!( + "*.{}.{domain_main}", + dc.datacenter_id + )], + }, + json!({ + "cert": gg_cert_pem, + "private_key": gg_private_key_pem, + "expire_ts": tls.expire_ts, + }), + )?; + + swf.activity( + "order", + OrderInput { + renew: false, + zone_id: job_zone_id.to_string(), + common_name: domain_job.to_string(), + subject_alternative_names: vec![ + format!("*.lobby.{}.{domain_job}", dc.datacenter_id), + format!("*.{}.{domain_job}", dc.datacenter_id), + ], + }, + json!({ + "cert": job_cert_pem, + "private_key": job_private_key_pem, + "expire_ts": tls.expire_ts, + }), + )?; + + #[derive(Serialize, Hash)] + struct InsertDbInput { + datacenter_id: Uuid, + gg_cert: String, + gg_private_key: String, + job_cert: String, + job_private_key: String, + expire_ts: i64, + } + + swf.activity( + "insert_db", + InsertDbInput { + datacenter_id: dc.datacenter_id, + gg_cert: gg_cert_pem.clone(), + gg_private_key: gg_private_key_pem.clone(), + job_cert: job_cert_pem.clone(), + job_private_key: job_private_key_pem.clone(), + expire_ts: tls.expire_ts, + }, + serde_json::Value::Null, + )?; + + Ok(()) + })?; + } + + wf.message( + "cluster-datacenter-create-complete", + json!({ + "datacenter_id": dc.datacenter_id, + }), + cluster::workflows::datacenter::CreateComplete {}, + )?; + + wf.signal( + "cluster-datacenter-scale", + cluster::workflows::datacenter::Scale {}, + )?; + + Ok(()) + })?; + } + + #[derive(sqlx::FromRow)] + struct ServerRow { + server_id: Uuid, + datacenter_id: Uuid, + pool_type: i64, + provider_server_id: Option, + provider_hardware: Option, + vlan_ip: Option, + public_ip: Option, + is_provisioned: bool, + is_installed: bool, + is_draining: bool, + is_tainted: bool, + } + #[derive(sqlx::FromRow)] + struct ServerLinodeRow { + server_id: Uuid, + ssh_key_id: i64, + linode_id: Option, + firewall_id: Option, + } + #[derive(sqlx::FromRow)] + struct ServerCfRow { + server_id: Uuid, + dns_record_id: Option, + secondary_dns_record_id: Option, + } + + let server_rows = sql_fetch_all!( + [ctx, ServerRow, @tx &mut tx] + " + SELECT + server_id, + datacenter_id, + pool_type, + provider_server_id, + provider_hardware, + vlan_ip, + public_ip, + (provision_complete_ts IS NOT NULL) AS is_provisioned, + (install_complete_ts IS NOT NULL) AS is_installed, + (drain_ts IS NOT NULL) AS is_draining, + (taint_ts IS NOT NULL) AS is_tainted + FROM db_cluster.servers + WHERE cloud_destroy_ts IS NULL + ", + ) + .await?; + let server_linode_rows = sql_fetch_all!( + [ctx, ServerLinodeRow, @tx &mut tx] + " + SELECT + server_id, + ssh_key_id, + linode_id, + firewall_id + FROM db_cluster.servers_linode + ", + ) + .await?; + let server_cf_rows = sql_fetch_all!( + [ctx, ServerCfRow, @tx &mut tx] + " + SELECT + server_id, + dns_record_id, + secondary_dns_record_id + FROM db_cluster.servers_cloudflare + ", + ) + .await?; + + for server in server_rows { + let dc = unwrap!(dc_rows + .iter() + .find(|dc| dc.datacenter_id == server.datacenter_id)); + let pools = { + let proto = backend::cluster::Pools::decode(dc.pools.as_slice())?.pools; + + proto + .into_iter() + .map(TryInto::::try_into) + .collect::>>()? + }; + let pool_type = server.pool_type.try_into()?; + let pool = unwrap!(pools.iter().find(|p| p.pool_type == pool_type)); + + let linode = server_linode_rows + .iter() + .find(|s| s.server_id == server.server_id); + let cf = server_cf_rows + .iter() + .find(|s| s.server_id == server.server_id); + + let install_token = create_token(&ctx).await?; + + let firewall_preset = match pool_type { + cluster::types::PoolType::Job => linode::types::FirewallPreset::Job, + cluster::types::PoolType::Gg => linode::types::FirewallPreset::Gg, + cluster::types::PoolType::Ats => linode::types::FirewallPreset::Ats, + }; + + let linode_server_workflow_id = bctx.workflow("linode_server", |wf| { + wf.tags(json!({ + "server_id": server.server_id, + }))?; + wf.input(json!({ + "server_id": server.server_id, + "provider_datacenter_id": dc.provider_datacenter_id, + "custom_image": Option::::None, + "hardware": unwrap!(pool.hardware.first()).provider_hardware, + "api_token": dc.provider_api_token.clone(), + "firewall_preset": firewall_preset.clone(), + "vlan_ip": server.vlan_ip, + "tags": [], + }))?; + wf.finalize(); + + let Some(linode) = linode else { return Ok(()) }; + + let Some(linode_id) = linode.linode_id else { + return Ok(()); + }; + let linode_id = linode_id as u64; + + #[derive(Serialize, Hash)] + struct CreateSshKeyInput { + server_id: Uuid, + api_token: Option, + is_test: bool, + } + + wf.activity( + "create_ssh_key", + CreateSshKeyInput { + server_id: server.server_id, + api_token: dc.provider_api_token.clone(), + is_test: false, + }, + json!({ + "ssh_key_id": linode.ssh_key_id, + // Not the actual public key, but not required + "public_key": "", + }), + )?; + + let ns = util::env::namespace(); + let tags = vec![ + // HACK: Linode requires tags to be > 3 characters. We extend the namespace to make sure it + // meets the minimum length requirement. + format!("rivet-{ns}"), + format!("{ns}-{}", dc.provider_datacenter_id), + format!("{ns}-{}", firewall_preset), + format!("{ns}-{}-{}", dc.provider_datacenter_id, firewall_preset), + ]; + + #[derive(Serialize, Hash)] + struct CreateInstanceInput { + api_token: Option, + ssh_public_key: String, + name: String, + datacenter: String, + hardware: String, + tags: Vec, + } + + wf.activity( + "create_instance", + CreateInstanceInput { + api_token: dc.provider_api_token.clone(), + // Not the actual public key, but not required + ssh_public_key: "".to_string(), + name: format!("{ns}-{}", server.server_id), + datacenter: dc.provider_datacenter_id.clone(), + hardware: unwrap!(pool.hardware.first()).provider_hardware.clone(), + tags: tags.clone(), + }, + json!({ + "linode_id": linode_id, + // Not the actual server disk size, but not required + "server_disk_size": 0, + }), + )?; + + #[derive(Serialize, Hash)] + struct WaitInstanceReadyInput { + api_token: Option, + linode_id: u64, + } + + wf.activity( + "wait_instance_ready", + WaitInstanceReadyInput { + api_token: dc.provider_api_token.clone(), + linode_id, + }, + serde_json::Value::Null, + )?; + + #[derive(Serialize, Hash)] + struct CreateDisksInput { + api_token: Option, + image: String, + ssh_public_key: String, + linode_id: u64, + disk_size: u64, + } + + #[derive(Serialize, Hash)] + struct CreateDisksOutput { + boot_id: u64, + swap_id: u64, + } + + wf.activity( + "create_disks", + CreateDisksInput { + api_token: dc.provider_api_token.clone(), + image: "linode/debian11".to_string(), + // Not the actual public key, but not required + ssh_public_key: "".to_string(), + linode_id, + // Not the actual server disk size, but not required + disk_size: 0, + }, + CreateDisksOutput { + // Not the actual boot id, but not required + boot_id: 0, + // Not the actual swap id, but not required + swap_id: 0, + }, + )?; + + #[derive(Serialize, Hash)] + struct CreateInstanceConfigInput { + api_token: Option, + vlan_ip: Option, + linode_id: u64, + disks: CreateDisksOutput, + } + + wf.activity( + "create_instance_config", + CreateInstanceConfigInput { + api_token: dc.provider_api_token.clone(), + vlan_ip: server + .vlan_ip + .map(|vlan_ip| { + if let IpAddr::V4(vlan_ip) = vlan_ip { + GlobalResult::Ok(vlan_ip) + } else { + bail!("unexpected ipv6"); + } + }) + .transpose()?, + linode_id, + disks: CreateDisksOutput { + // Not the actual boot id, but not required + boot_id: 0, + // Not the actual swap id, but not required + swap_id: 0, + }, + }, + serde_json::Value::Null, + )?; + + let Some(firewall_id) = linode.firewall_id else { + return Ok(()); + }; + + #[derive(Debug, Serialize, Deserialize, Hash)] + struct CreateFirewallInput { + server_id: Uuid, + api_token: Option, + firewall_preset: linode::types::FirewallPreset, + tags: Vec, + linode_id: u64, + } + + wf.activity( + "create_firewall", + CreateFirewallInput { + server_id: server.server_id, + api_token: dc.provider_api_token.clone(), + firewall_preset: firewall_preset.clone(), + tags, + linode_id, + }, + firewall_id, + )?; + + #[derive(Debug, Serialize, Deserialize, Hash)] + struct BootInstanceInput { + api_token: Option, + linode_id: u64, + } + + wf.activity( + "boot_instance", + BootInstanceInput { + api_token: dc.provider_api_token.clone(), + linode_id, + }, + serde_json::Value::Null, + )?; + + let public_ip = if let Some(public_ip) = server.public_ip { + if let IpAddr::V4(public_ip) = public_ip { + public_ip + } else { + bail!("unexpected ipv6"); + } + } else { + return Ok(()); + }; + + #[derive(Serialize, Hash)] + struct GetPublicIpInput { + api_token: Option, + linode_id: u64, + } + + wf.activity( + "get_public_ip", + GetPublicIpInput { + api_token: dc.provider_api_token.clone(), + linode_id, + }, + public_ip, + )?; + + wf.signal( + "linode-server-provision-complete", + json!({ + "linode_id": linode_id, + "public_ip": public_ip, + // Not actual boot disk id, but not required + "boot_disk_id": 0, + }), + )?; + + Ok(()) + })?; + + bctx.workflow("cluster_server", |wf| { + wf.tags(json!({ + "server_id": server.server_id, + }))?; + wf.input(json!({ + "datacenter_id": server.datacenter_id, + "server_id": server.server_id, + "pool_type": pool_type.clone(), + "tags": [], + }))?; + wf.finalize(); + + #[derive(Serialize, Hash)] + struct GetDcInput { + datacenter_id: Uuid, + } + + wf.activity( + "get_dc", + GetDcInput { + datacenter_id: server.datacenter_id, + }, + cluster::types::Datacenter { + cluster_id: dc.cluster_id, + datacenter_id: dc.datacenter_id, + name_id: dc.name_id.clone(), + display_name: dc.display_name.clone(), + + provider: dc.provider.try_into()?, + provider_datacenter_id: dc.provider_datacenter_id.clone(), + provider_api_token: dc.provider_api_token.clone(), + + pools: { + let proto = backend::cluster::Pools::decode(dc.pools.as_slice())?.pools; + + proto + .into_iter() + .map(TryInto::try_into) + .collect::>>()? + }, + + build_delivery_method: dc.build_delivery_method.try_into()?, + prebakes_enabled: false, + create_ts: util::timestamp::now(), + }, + )?; + + let vlan_ip = if let Some(vlan_ip) = server.vlan_ip { + if let IpAddr::V4(vlan_ip) = vlan_ip { + vlan_ip + } else { + bail!("unexpected ipv6"); + } + } else { + return Ok(()); + }; + + #[derive(Serialize, Hash)] + struct GetVlanIpInput { + datacenter_id: Uuid, + server_id: Uuid, + pool_type: cluster::types::PoolType, + } + + wf.activity( + "get_vlan_ip", + GetVlanIpInput { + datacenter_id: server.datacenter_id, + server_id: server.server_id, + pool_type: pool_type.clone(), + }, + vlan_ip, + )?; + + wf.dispatch_sub_workflow(linode_server_workflow_id)?; + + if !server.is_provisioned { + return Ok(()); + } + + let public_ip = if let IpAddr::V4(public_ip) = unwrap!(server.public_ip) { + public_ip + } else { + bail!("unexpected ipv6"); + }; + + wf.listen( + "linode-server-provision-complete", + json!({ + "linode_id": unwrap!(unwrap!(linode).linode_id), + "public_ip": public_ip, + "boot_disk_id": 0, + }), + )?; + + #[derive(Serialize, Hash)] + struct UpdateDbInput { + server_id: Uuid, + pool_type: cluster::types::PoolType, + cluster_id: Uuid, + datacenter_id: Uuid, + provider_datacenter_id: String, + datacenter_name_id: String, + provider_server_id: String, + provider_hardware: String, + public_ip: Ipv4Addr, + already_installed: bool, + } + + wf.activity( + "update_db", + UpdateDbInput { + server_id: server.server_id, + pool_type: pool_type.clone(), + cluster_id: dc.cluster_id, + datacenter_id: server.datacenter_id, + provider_datacenter_id: dc.provider_datacenter_id.clone(), + datacenter_name_id: dc.name_id.clone(), + provider_server_id: unwrap!(server.provider_server_id.clone()), + provider_hardware: unwrap!(server.provider_hardware.clone()), + public_ip, + already_installed: false, + }, + serde_json::Value::Null, + )?; + + if !server.is_installed { + return Ok(()); + } + + // Install + wf.sub_workflow(|swf| { + #[derive(Serialize, Hash)] + struct CreateTokenInput {} + + swf.activity("create_token", CreateTokenInput {}, install_token.clone())?; + + #[derive(Serialize, Hash)] + struct InstallOverSshInput { + datacenter_id: Uuid, + public_ip: Ipv4Addr, + pool_type: cluster::types::PoolType, + initialize_immediately: bool, + server_token: String, + } + + swf.activity( + "install_over_ssh", + InstallOverSshInput { + datacenter_id: server.datacenter_id, + public_ip, + pool_type: pool_type.clone(), + initialize_immediately: true, + server_token: install_token.clone(), + }, + serde_json::Value::Null, + )?; + + #[derive(Serialize, Hash)] + struct UpdateDbInput { + datacenter_id: Uuid, + server_id: Uuid, + pool_type: cluster::types::PoolType, + } + + swf.activity( + "update_db", + UpdateDbInput { + datacenter_id: server.datacenter_id, + server_id: server.server_id, + pool_type: pool_type.clone(), + }, + serde_json::Value::Null, + )?; + + Ok(()) + })?; + + wf.signal( + "cluster-datacenter-scale", + cluster::workflows::datacenter::Scale {}, + )?; + + if let cluster::types::PoolType::Gg = pool_type { + if let Some(cf) = cf { + // Dns create + wf.sub_workflow(|swf| { + #[derive(Serialize, Hash)] + struct GetServerInfoInput { + server_id: Uuid, + } + + swf.activity( + "get_server_info", + GetServerInfoInput { + server_id: server.server_id, + }, + json!({ + "datacenter_id": server.datacenter_id, + "public_ip": public_ip, + }), + )?; + + let zone_id = + unwrap!(util::env::cloudflare::zone::job::id(), "dns not configured"); + let domain_job = unwrap!(util::env::domain_job()); + + #[derive(Serialize, Hash)] + struct CreateDnsRecordInput { + record_name: String, + public_ip: Ipv4Addr, + zone_id: String, + } + + if let Some(dns_record_id) = &cf.dns_record_id { + swf.activity( + "create_dns_record", + CreateDnsRecordInput { + record_name: format!( + "*.lobby.{}.{domain_job}", + server.datacenter_id + ), + public_ip, + zone_id: zone_id.to_string(), + }, + dns_record_id.clone(), + )?; + } + + if let Some(secondary_dns_record_id) = &cf.secondary_dns_record_id { + swf.activity( + "create_dns_record", + CreateDnsRecordInput { + record_name: format!( + "lobby.{}.{domain_job}", + server.datacenter_id + ), + public_ip, + zone_id: zone_id.to_string(), + }, + secondary_dns_record_id.clone(), + )?; + } + + if cf.dns_record_id.is_some() && cf.secondary_dns_record_id.is_some() { + #[derive(Serialize, Hash)] + struct InsertDbInput { + server_id: Uuid, + primary_dns_record_id: String, + secondary_dns_record_id: String, + } + + swf.activity( + "insert_db", + InsertDbInput { + server_id: server.server_id, + primary_dns_record_id: unwrap!(cf.dns_record_id.clone()), + secondary_dns_record_id: unwrap!(cf + .secondary_dns_record_id + .clone()), + }, + serde_json::Value::Null, + )?; + } + + Ok(()) + })?; + } + } + + if server.is_draining { + wf.listen("cluster-server-drain", json!({}))?; + } + + if server.is_tainted { + wf.listen("cluster-server-taint", json!({}))?; + } + + Ok(()) + })?; + } + + bctx.execute(&mut tx).await?; + + tx.commit().await?; + + tracing::info!("backfill complete"); + + Ok(()) +} + +async fn create_token(ctx: &StandaloneCtx) -> GlobalResult { + use rivet_operation::prelude::proto::{self, backend::pkg::*}; + + // Create server token for authenticating API calls from the server + let token_res = op!([ctx] token_create { + token_config: Some(token::create::request::TokenConfig { + ttl: cluster::util::SERVER_TOKEN_TTL, + }), + refresh_token_config: None, + issuer: "cluster-workflow-backfill".to_owned(), + client: None, + kind: Some(token::create::request::Kind::New(token::create::request::KindNew { + entitlements: vec![ + proto::claims::Entitlement { + kind: Some( + proto::claims::entitlement::Kind::ProvisionedServer( + proto::claims::entitlement::ProvisionedServer {} + ) + ) + } + ], + })), + label: Some("srv".to_owned()), + ..Default::default() + }) + .await?; + let server_token = unwrap_ref!(token_res.token).token.clone(); + + Ok(server_token) +} diff --git a/svc/pkg/cluster/standalone/workflow-backfill/src/main.rs b/svc/pkg/cluster/standalone/workflow-backfill/src/main.rs new file mode 100644 index 0000000000..d527e0912e --- /dev/null +++ b/svc/pkg/cluster/standalone/workflow-backfill/src/main.rs @@ -0,0 +1,15 @@ +use chirp_workflow::prelude::*; +use tracing_subscriber::prelude::*; + +#[tokio::main] +async fn main() -> GlobalResult<()> { + tracing_subscriber::registry() + .with( + tracing_logfmt::builder() + .layer() + .with_filter(tracing_subscriber::filter::LevelFilter::INFO), + ) + .init(); + + cluster_workflow_backfill::run_from_env().await +} diff --git a/svc/pkg/linode/src/workflows/server/mod.rs b/svc/pkg/linode/src/workflows/server/mod.rs index ff1e3bd86e..ae18d99a3b 100644 --- a/svc/pkg/linode/src/workflows/server/mod.rs +++ b/svc/pkg/linode/src/workflows/server/mod.rs @@ -30,6 +30,8 @@ pub async fn linode_server(ctx: &mut WorkflowCtx, input: &Input) -> GlobalResult let provision_res = match provision(ctx, input, &mut cleanup_ctx).await { // If we cannot recover a provisioning error, send a failed signal and clean up resources Err(err) if !err.is_workflow_recoverable() => { + tracing::warn!(?err); + ctx.dispatch_workflow(cleanup::Input { api_token: input.api_token.clone(), ssh_key_id: cleanup_ctx.ssh_key_id,