diff --git a/Cargo.lock b/Cargo.lock index 31420db..9b7b820 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "adler32" version = "1.2.0" @@ -83,7 +98,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -94,7 +109,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -109,18 +124,45 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link 0.2.0", +] + [[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "2.9.0" @@ -164,6 +206,12 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + [[package]] name = "cc" version = "1.2.17" @@ -190,7 +238,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -245,6 +293,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -299,6 +357,15 @@ dependencies = [ "syn", ] +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -322,6 +389,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.10" @@ -329,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -347,9 +420,30 @@ dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys", + "windows-sys 0.59.0", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -365,6 +459,56 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -388,6 +532,12 @@ dependencies = [ "wasi 0.14.2+wasi-0.2.4", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + [[package]] name = "gzip-header" version = "1.0.0" @@ -397,6 +547,31 @@ dependencies = [ "crc32fast", ] +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "heck" version = "0.5.0" @@ -409,6 +584,40 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" @@ -421,6 +630,86 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + [[package]] name = "iana-time-zone" version = "0.1.62" @@ -606,6 +895,43 @@ dependencies = [ "quote", ] +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -654,9 +980,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.171" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libredox" @@ -709,6 +1035,26 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + [[package]] name = "multipart" version = "0.18.0" @@ -727,6 +1073,23 @@ dependencies = [ "twoway", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "new_mime_guess" version = "4.0.4" @@ -771,18 +1134,89 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "portable-atomic" version = "1.11.0" @@ -957,13 +1391,69 @@ dependencies = [ "winapi", ] +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rouille" version = "3.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3716fbf57fc1084d7a706adf4e445298d123e4a44294c4e8213caf1b85fcc921" dependencies = [ - "base64", + "base64 0.13.1", "brotli", "chrono", "deflate", @@ -981,6 +1471,12 @@ dependencies = [ "url", ] +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + [[package]] name = "rustix" version = "1.0.3" @@ -991,7 +1487,40 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -1021,6 +1550,38 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.1", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.219" @@ -1053,6 +1614,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1_smol" version = "1.0.1" @@ -1076,16 +1649,33 @@ dependencies = [ "env_logger", "include_directory", "log", + "reqwest", "rouille", "tempdir", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "smallvec" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1098,6 +1688,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.100" @@ -1109,6 +1705,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.1" @@ -1120,6 +1725,27 @@ dependencies = [ "syn", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -1140,7 +1766,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1195,6 +1821,126 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "twoway" version = "0.1.8" @@ -1216,6 +1962,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -1245,6 +1997,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "walkdir" version = "2.5.0" @@ -1255,6 +2013,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1296,6 +2063,19 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.100" @@ -1328,6 +2108,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1350,7 +2140,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1374,6 +2164,50 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-registry" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" +dependencies = [ + "windows-link 0.1.1", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.1", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -1383,6 +2217,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1533,6 +2376,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerovec" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index 731616d..cc00b12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,6 @@ dir-diff = "0.3.3" env_logger = "0.11.7" include_directory = "0.1.1" log = "0.4.27" +reqwest = { version = "0.12.23", features = ["blocking"] } rouille = "3.6.2" tempdir = "0.3.7" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3ddc3c8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# Build Stage +FROM rust:latest AS builder +WORKDIR /app +COPY . . +RUN cargo build --release + +# Runtime Stage +FROM debian:stable-slim +WORKDIR /app +COPY --from=builder /app/target/release/handler . +CMD ["./handler"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..243bacd --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +PATH_VERSION = 1 + +TAG = $(MAJOR_VERSION).$(MINOR_VERSION).$(PATH_VERSION) + +build: + docker build . -t skubelb-handler:$(TAG) + docker tag skubelb-handler:$(TAG) us-west4-docker.pkg.dev/nixernetes/images/skubelb-handler:$(TAG) + +kube: + cat kubernetes.yaml.tmpl | sed 's/TAG/$(TAG)/' > kubernetes.yaml + +deploy: build kube + docker push us-west4-docker.pkg.dev/nixernetes/images/skubelb-handler:$(TAG) + kubectl apply -f kubernetes.yaml diff --git a/kubernetes.yaml b/kubernetes.yaml new file mode 100644 index 0000000..5f8245d --- /dev/null +++ b/kubernetes.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: skubelb + namespace: skubelb + labels: + k8s-app: skubelb +spec: + selector: + matchLabels: + name: skubelb + template: + metadata: + labels: + name: skubelb + spec: + tolerations: + # these tolerations are to have the daemonset runnable on control plane nodes + # remove them if your control plane nodes should not run pods + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + containers: + - name: skubelb + image: us-west4-docker.pkg.dev/nixernetes/images/skubelb-handler:0.0.1 + env: + - name: NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + command: ["sh", "-c", "./handler -s 10.128.0.2:8888 -l ${NODE_IP}"] + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 100Mi + terminationGracePeriodSeconds: 30 \ No newline at end of file diff --git a/kubernetes.yaml.tmpl b/kubernetes.yaml.tmpl new file mode 100644 index 0000000..541ecb0 --- /dev/null +++ b/kubernetes.yaml.tmpl @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: skubelb + namespace: skubelb + labels: + k8s-app: skubelb +spec: + selector: + matchLabels: + name: skubelb + template: + metadata: + labels: + name: skubelb + spec: + tolerations: + # these tolerations are to have the daemonset runnable on control plane nodes + # remove them if your control plane nodes should not run pods + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + containers: + - name: skubelb + image: us-west4-docker.pkg.dev/nixernetes/images/skubelb-handler:TAG + env: + - name: NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + command: ["sh", "-c", "./handler -s 10.128.0.2:8888 -l ${NODE_IP}"] + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 100Mi + terminationGracePeriodSeconds: 30 \ No newline at end of file diff --git a/src/bin/handler.rs b/src/bin/handler.rs new file mode 100644 index 0000000..39332c8 --- /dev/null +++ b/src/bin/handler.rs @@ -0,0 +1,43 @@ +use std::thread::sleep; +use std::time::Duration; + +use clap::Parser; + +use log::{error, info}; + +use anyhow::Result; +use env_logger::Env; + +/// Implements a client that constantly refreshes with the server. +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// The skubelb server we should register with + #[arg(short, long)] + server: String, + + /// The listen address that should be sent to skubelb. + #[arg(short, long)] + listen: String, +} + +fn main() { + // Log info and above by default + env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); + let args = Args::parse(); + + match handle(&args.server, &args.listen) { + Ok(_) => (), + Err(e) => error!("{}", e), + } +} + +fn handle(remote: &str, listen: &str) -> Result<()> { + let client = reqwest::blocking::Client::new(); + let url = format!("http://{}/register/{}", remote, listen); + loop { + sleep(Duration::from_secs(20)); + info!("sending post to {}", url); + client.post(&url).send()?; + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c11c1fb..68830bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,26 @@ -use std::sync::Mutex; use std::process::Command; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; +use std::thread::sleep; +use std::time::Duration; use clap::Parser; use skubelb::Rewriter; use skubelb::Server; +use anyhow::{Result, anyhow}; use env_logger::Env; use log::{info, warn}; -use anyhow::Result; -use rouille::{router, Request, Response}; +use rouille::{Request, Response, router}; /// Implements a HTTP server which allows clients to 'register' /// themselves. Their IP address will be used to replace a /// needle in a set of config files. This is intended to be /// used as a low-cost way of enabling Kubernetes ingress /// using nginx running on a machine that has a public port. -/// +/// /// The needle is expected to be a dummy IP address; something /// fairly unique. The goal is to replace nginx files, where /// we often repeat lines if we want nginx to load balance between @@ -37,7 +41,7 @@ struct Args { template_dir: String, /// The symlink that should be updated each time the config changes. - /// + /// /// Symlinks are used because file updates are not atomic. #[arg(short, long)] config_symlink: String, @@ -61,10 +65,31 @@ fn main() { let args = Args::parse(); let rewriter = Rewriter::new(args.needle); - let server_impl = Mutex::new(Server::new(rewriter, args.workspace_dir, args.template_dir, args.config_symlink)); + let server_impl = Arc::new(Mutex::new(Server::new( + rewriter, + args.workspace_dir, + args.template_dir, + args.config_symlink, + ))); let reload_command = args.reload_cmd.leak(); let reload_command: Vec<&str> = reload_command.split_ascii_whitespace().collect(); + // Start cleanup thread + { + let server_impl = server_impl.clone(); + thread::spawn(move || { + loop { + sleep(Duration::from_secs(30)); + match cleanup_worker(&server_impl) { + Ok(_) => (), + Err(e) => { + warn!("Error cleaning up handlers {}", e); + } + } + } + }); + } + rouille::start_server(args.listen, move |request| { info!("Processing request: {:?}", request); match handle(request, &server_impl) { @@ -76,19 +101,30 @@ fn main() { match output { Ok(o) => { info!("Ran {:?}; exit code: {}", reload_command, o.status); - info!("Ran {:?}; stdout: {}", reload_command, String::from_utf8_lossy(&o.stdout)); - info!("Ran {:?}; stderr: {}", reload_command, String::from_utf8_lossy(&o.stderr)); - }, + info!( + "Ran {:?}; stdout: {}", + reload_command, + String::from_utf8_lossy(&o.stdout) + ); + info!( + "Ran {:?}; stderr: {}", + reload_command, + String::from_utf8_lossy(&o.stderr) + ); + } Err(e) => { warn!("Failed to run {:?}: {:?}", reload_command, e); } }; } resp - }, + } Err(e) => { warn!("{:?}", e); - Response{status_code: 500, ..Response::empty_400()} + Response { + status_code: 500, + ..Response::empty_400() + } } } }); @@ -97,13 +133,23 @@ fn main() { fn handle(request: &Request, server_impl: &Mutex) -> Result<(Response, bool)> { router!(request, (POST) (/register/{ip: String}) => { - server_impl.lock().unwrap().register(request, &ip)?; + let mut server_impl = server_impl.lock().map_err(|_| anyhow!("failed to acquire lock"))?; + server_impl.register(request, &ip)?; + server_impl.cleanup()?; Ok((Response{status_code: 200, ..Response::empty_204()}, true)) }, (DELETE) (/register/{ip: String}) => { - server_impl.lock().unwrap().unregister(request, &ip)?; + let mut server_impl = server_impl.lock().map_err(|_| anyhow!("failed to acquire lock"))?; + server_impl.unregister(request, &ip)?; + server_impl.cleanup()?; Ok((Response{status_code: 200, ..Response::empty_204()}, true)) }, _ => Ok((Response::empty_404(), false)), ) -} \ No newline at end of file +} + +fn cleanup_worker(server_impl: &Mutex) -> Result<()> { + let mut server_impl = server_impl.lock().map_err(|_| anyhow!("failed to acquire lock"))?; + server_impl.cleanup()?; + Ok(()) +} diff --git a/src/rewriter.rs b/src/rewriter.rs index 9c7dc16..9317c37 100644 --- a/src/rewriter.rs +++ b/src/rewriter.rs @@ -1,6 +1,7 @@ use anyhow::Result; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::path::Path; +use std::time::Instant; use std::{ fs::{self, File}, io::{BufReader, prelude::*}, @@ -9,6 +10,8 @@ use std::{ pub struct Rewriter { source: String, replacements: HashSet, + // When each replacement should be cleaned up + replacement_cleanup: HashMap, } impl Rewriter { @@ -16,15 +19,18 @@ impl Rewriter { Self { source, replacements: HashSet::new(), + replacement_cleanup: HashMap::default(), } } - pub fn add_replacement(&mut self, replacement: String) { - self.replacements.insert(replacement); + pub fn add_replacement(&mut self, replacement: String, cleanup: Instant) { + self.replacements.insert(replacement.clone()); + self.replacement_cleanup.insert(replacement, cleanup); } pub fn remove_replacement(&mut self, replacement: &str) { self.replacements.remove(replacement); + self.replacement_cleanup.remove(replacement); } pub fn rewrite_folder(&self, src: &str, dst: &str) -> Result<()> { @@ -91,6 +97,20 @@ impl Rewriter { } Ok(()) } + + pub fn cleanup(&mut self) { + let now = Instant::now(); + let mut to_remove = vec![]; + for (name, when) in self.replacement_cleanup.iter() { + if when < &now { + to_remove.push(name.clone()); + } + } + + for name in to_remove { + self.remove_replacement(&name); + } + } } fn contains(needle: &[u8], haystack: &[u8]) -> Option<(usize, usize)> { @@ -110,6 +130,8 @@ fn contains(needle: &[u8], haystack: &[u8]) -> Option<(usize, usize)> { #[cfg(test)] mod tests { + use std::time::{Duration, Instant}; + use include_directory::{Dir, include_directory}; use tempdir::TempDir; @@ -123,10 +145,11 @@ mod tests { let src = testdata.path().join("testsrc"); let dst = TempDir::new("").unwrap(); + let now = Instant::now(); let mut rewriter = Rewriter::new("to_be_replaced".into()); - rewriter.add_replacement("abc".into()); - rewriter.add_replacement("def".into()); - rewriter.add_replacement("zyx".into()); + rewriter.add_replacement("abc".into(), now.checked_add(Duration::new(60*60*24, 0)).unwrap()); + rewriter.add_replacement("def".into(), now); + rewriter.add_replacement("zyx".into(), now); rewriter.remove_replacement("zyx"); rewriter .rewrite_folder( @@ -139,5 +162,20 @@ mod tests { assert!( dir_diff::is_different(testdata.path().join("testdst"), dst.path()).unwrap() == false ); + + // Trigger the cleanup, which should GC abc + let dst = TempDir::new("").unwrap(); + rewriter.cleanup(); + rewriter + .rewrite_folder( + src.as_os_str().to_str().unwrap(), + dst.path().as_os_str().to_str().unwrap(), + ) + .unwrap(); + + // Validate that everything matches + assert!( + dir_diff::is_different(testdata.path().join("testdst_after_gc"), dst.path()).unwrap() == false + ); } } diff --git a/src/server.rs b/src/server.rs index bf67785..d1acf23 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,9 +1,13 @@ -use std::{fs, path::Path}; +use std::{ + fs, + path::Path, + time::{Duration, Instant}, +}; +use anyhow::{anyhow, Context, Result}; use chrono::Utc; use log::info; use rouille::Request; -use anyhow::{Context, Result}; use crate::Rewriter; @@ -18,7 +22,12 @@ pub struct Server { } impl Server { - pub fn new(rewriter: Rewriter, workspace_dir: String, template_dir: String, config_dir: String) -> Self { + pub fn new( + rewriter: Rewriter, + workspace_dir: String, + template_dir: String, + config_dir: String, + ) -> Self { Self { rewriter, workspace_dir, @@ -27,9 +36,17 @@ impl Server { } } + pub fn cleanup(&mut self) -> Result<()> { + self.rewriter.cleanup(); + Ok(()) + } + pub fn register(&mut self, _request: &Request, ip: &str) -> Result<()> { info!("Registering {} as a handler", ip); - self.rewriter.add_replacement(ip.to_string()); + let cleanup_time = Instant::now() + .checked_add(Duration::from_secs(60 * 5)) + .ok_or(anyhow!("failed to convert time"))?; + self.rewriter.add_replacement(ip.to_string(), cleanup_time); self.generate_config()?; Ok(()) } @@ -49,11 +66,13 @@ impl Server { let path = Path::new(&self.workspace_dir).join(&now.format("%Y/%m/%d/%s").to_string()); let path = path.as_os_str().to_str().unwrap(); fs::create_dir_all(path).with_context(|| "creating directory")?; - self.rewriter.rewrite_folder(&self.template_dir, path).with_context(|| "generating configs")?; + self.rewriter + .rewrite_folder(&self.template_dir, path) + .with_context(|| "generating configs")?; // Finally, symlink it to the output folder; only support Linux for now let symlink = Path::new(&self.workspace_dir).join("symlink.tmp"); std::os::unix::fs::symlink(path, &symlink).with_context(|| "creating symlink")?; fs::rename(symlink, &self.config_dir).with_context(|| "renaming symlink")?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/testdata/testdst_after_gc/hello.txt b/src/testdata/testdst_after_gc/hello.txt new file mode 100644 index 0000000..b90c337 --- /dev/null +++ b/src/testdata/testdst_after_gc/hello.txt @@ -0,0 +1,4 @@ +This is a line +This is abc line + +This is another line diff --git a/src/testdata/testdst_after_gc/recursive/world.txt b/src/testdata/testdst_after_gc/recursive/world.txt new file mode 100644 index 0000000..fbbc0e3 --- /dev/null +++ b/src/testdata/testdst_after_gc/recursive/world.txt @@ -0,0 +1,3 @@ +This is a abc line. + +In a nested directory.