From cf9dc6fef175b197915c324fef1790b8c7a0d016 Mon Sep 17 00:00:00 2001 From: Maninderpreet Singh Date: Mon, 12 May 2025 22:51:21 -0400 Subject: [PATCH] feat: #0 docker image --- .dockerignore | 31 +++++ Cargo.lock | 289 +++++++++++++++++++++------------------ Cargo.toml | 4 +- Dockerfile | 40 ++++++ docker-compose.yml | 23 ++++ examples/Dockerfile | 17 +++ examples/user-dockerfile | 18 +++ src/config.rs | 16 ++- src/error.rs | 52 +++++++ src/logger.rs | 69 ++++++++++ src/main.rs | 16 ++- src/proxy.rs | 52 +++---- 12 files changed, 455 insertions(+), 172 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 examples/Dockerfile create mode 100644 examples/user-dockerfile create mode 100644 src/error.rs create mode 100644 src/logger.rs diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4b87856 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,31 @@ +# Git +.git +.gitignore + +# Rust build artifacts +target/ +**/*.rs.bk + +# Examples and test files +examples/ +tests/ + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo + +# Docker files +Dockerfile +.dockerignore +docker-compose.yml + +# Documentation +README.md +LICENSE + +# Development configs +.env +.env.* +*.log \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 03ef2d7..6e96229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -134,9 +140,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -209,7 +215,7 @@ checksum = "9f83833816c66c986e913b22ac887cec216ea09301802054316fc5301809702c" dependencies = [ "cap-primitives", "cap-std", - "rustix 1.0.5", + "rustix 1.0.7", "smallvec", ] @@ -225,7 +231,7 @@ dependencies = [ "io-lifetimes", "ipnet", "maybe-owned", - "rustix 1.0.5", + "rustix 1.0.7", "rustix-linux-procfs", "windows-sys 0.59.0", "winx", @@ -250,7 +256,7 @@ dependencies = [ "cap-primitives", "io-extras", "io-lifetimes", - "rustix 1.0.5", + "rustix 1.0.7", ] [[package]] @@ -263,15 +269,15 @@ dependencies = [ "cap-primitives", "iana-time-zone", "once_cell", - "rustix 1.0.5", + "rustix 1.0.7", "winx", ] [[package]] name = "cc" -version = "1.2.20" +version = "1.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "32db95edf998450acc7881c932f94cd9b05c87b4b2599e8bab064753da4acfd1" dependencies = [ "jobserver", "libc", @@ -284,6 +290,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + [[package]] name = "cobs" version = "0.2.3" @@ -650,7 +670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix 1.0.5", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -682,7 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94e7099f6313ecacbe1256e8ff9d617b75d1bcb16a6fddef94866d225a01a14a" dependencies = [ "io-lifetimes", - "rustix 1.0.5", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -792,9 +812,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -834,9 +854,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", @@ -853,9 +873,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "foldhash", "serde", @@ -968,7 +988,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.9", + "h2 0.4.10", "http 1.3.1", "http-body 1.0.1", "httparse", @@ -1006,21 +1026,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -1029,31 +1050,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -1061,67 +1062,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "id-arena" version = "2.2.1" @@ -1141,9 +1129,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1225,9 +1213,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd" +checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806" dependencies = [ "jiff-static", "log", @@ -1238,9 +1226,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300" +checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48" dependencies = [ "proc-macro2", "quote", @@ -1253,7 +1241,7 @@ version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", "libc", ] @@ -1287,9 +1275,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libm" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" @@ -1315,9 +1303,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "log" @@ -1375,6 +1363,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.36.7" @@ -1444,6 +1441,15 @@ dependencies = [ "serde", ] +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1606,12 +1612,14 @@ name = "rilot" version = "0.1.0" dependencies = [ "anyhow", + "chrono", "env_logger", "hyper 0.14.32", "log", "once_cell", "serde", "serde_json", + "thiserror 1.0.69", "tokio", "wasmtime", "wasmtime-wasi", @@ -1660,9 +1668,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", @@ -1678,7 +1686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fc84bf7e9aa16c4f2c758f27412dc9841341e16aa682d9c7ac308fe3ee12056" dependencies = [ "once_cell", - "rustix 1.0.5", + "rustix 1.0.7", ] [[package]] @@ -1697,9 +1705,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" @@ -1776,9 +1787,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -1941,9 +1952,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -1951,9 +1962,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.2" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes", @@ -2136,12 +2147,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -2260,12 +2265,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.229.0" +version = "0.230.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2" +checksum = "d4349d0943718e6e434b51b9639e876293093dca4b96384fb136ab5bd5ce6660" dependencies = [ "leb128fmt", - "wasmparser 0.229.0", + "wasmparser 0.230.0", ] [[package]] @@ -2283,9 +2288,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.229.0" +version = "0.230.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c" +checksum = "808198a69b5a0535583370a51d459baa14261dfab04800c4864ee9e1a14346ed" dependencies = [ "bitflags", "indexmap", @@ -2332,7 +2337,7 @@ dependencies = [ "psm", "pulley-interpreter", "rayon", - "rustix 1.0.5", + "rustix 1.0.7", "semver", "serde", "serde_derive", @@ -2380,7 +2385,7 @@ dependencies = [ "directories-next", "log", "postcard", - "rustix 1.0.5", + "rustix 1.0.7", "serde", "serde_derive", "sha2", @@ -2472,7 +2477,7 @@ dependencies = [ "anyhow", "cc", "cfg-if", - "rustix 1.0.5", + "rustix 1.0.7", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", "windows-sys 0.59.0", @@ -2486,7 +2491,7 @@ checksum = "e43014e680b0b61628ea30bc193f73fbc27723f373a9e353919039aca1d8536c" dependencies = [ "cc", "object", - "rustix 1.0.5", + "rustix 1.0.7", "wasmtime-versioned-export-macros", ] @@ -2547,7 +2552,7 @@ dependencies = [ "futures", "io-extras", "io-lifetimes", - "rustix 1.0.5", + "rustix 1.0.7", "system-interface", "thiserror 2.0.12", "tokio", @@ -2579,7 +2584,7 @@ dependencies = [ "tracing", "wasmtime", "wasmtime-wasi", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] @@ -2635,31 +2640,40 @@ dependencies = [ [[package]] name = "wast" -version = "229.0.0" +version = "230.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9" +checksum = "b8edac03c5fa691551531533928443faf3dc61a44f814a235c7ec5d17b7b34f1" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.229.0", + "wasm-encoder 0.230.0", ] [[package]] name = "wat" -version = "1.229.0" +version = "1.230.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0" +checksum = "0d77d62229e38db83eac32bacb5f61ebb952366ab0dae90cf2b3c07a65eea894" dependencies = [ - "wast 229.0.0", + "wast 230.0.0", ] [[package]] name = "webpki-roots" -version = "0.26.10" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37493cadf42a2a939ed404698ded7fb378bf301b5011f973361779a3a74f8c93" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.0", +] + +[[package]] +name = "webpki-roots" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" dependencies = [ "rustls-pki-types", ] @@ -2898,9 +2912,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ "memchr", ] @@ -2954,23 +2968,17 @@ dependencies = [ "wast 35.0.2", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -2980,9 +2988,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", @@ -3037,11 +3045,22 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -3050,9 +3069,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 66d4b2f..ade563d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,6 @@ wasmtime-wasi = "32.0.0" wasmtime-wasi-io = "32.0.0" wasmtime-wasi-http = "32.0.0" env_logger = "0.11" -log="0.4" \ No newline at end of file +log="0.4" +chrono = "0.4" +thiserror = "1.0" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e6c1897 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +# Build stage +FROM rust:1.86.0-slim as builder + +WORKDIR /usr/src/rilot + +# Copy only the necessary files for building +COPY Cargo.toml Cargo.lock ./ +COPY src ./src + +# Install build dependencies and musl target +RUN apt-get update && \ + apt-get install -y pkg-config libssl-dev musl-tools && \ + rustup target add x86_64-unknown-linux-musl && \ + rm -rf /var/lib/apt/lists/* + +# Build the application for musl +RUN cargo build --release --target x86_64-unknown-linux-musl + +# Runtime stage +FROM alpine:3.19 + +WORKDIR /app + +# Install runtime dependencies +RUN apk add --no-cache ca-certificates openssl + +# Copy the binary from builder to a directory in PATH +COPY --from=builder /usr/src/rilot/target/x86_64-unknown-linux-musl/release/rilot /usr/local/bin/ + +# Create directories for config and wasm +RUN mkdir -p /app/config /app/wasm + +# Create a non-root user +RUN adduser -D -u 1000 rilot +USER rilot + +# Expose the port +EXPOSE 8080 + +# No CMD or ENTRYPOINT - let users specify how to run it \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bf9bfb2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.8' + +services: + rilot: + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" + volumes: + - ./config.json:/app/config/config.json + - ./wasm:/app/wasm + environment: + - RILOT_HOST=0.0.0.0 + - RILOT_PORT=8080 + - RILOT_LOG=debug + - RILOT_ENV=development + # You can override the config path if needed + # - RILOT_CONFIG_PATH=/app/config/custom-config.json + +networks: + default: + driver: bridge \ No newline at end of file diff --git a/examples/Dockerfile b/examples/Dockerfile new file mode 100644 index 0000000..b54edf6 --- /dev/null +++ b/examples/Dockerfile @@ -0,0 +1,17 @@ +# Use the official Rilot image +FROM apprilot/rilot-core:beta2 + +# Copy your config file +COPY config/config.json /app/config/config.json + +# Copy your WASM files if needed +COPY target/wasm32-wasip1/release/*.wasm /app/wasm/ + +# Set environment variables +ENV RILOT_HOST=0.0.0.0 +ENV RILOT_PORT=3000 +ENV RUST_LOG=debug + +# # Run Rilot with your config +ENTRYPOINT ["/usr/local/bin/rilot"] +CMD ["/app/config/config.json"] diff --git a/examples/user-dockerfile b/examples/user-dockerfile new file mode 100644 index 0000000..cf685ff --- /dev/null +++ b/examples/user-dockerfile @@ -0,0 +1,18 @@ +# Use the official Rilot image +FROM apprilot/rilot:latest + +# Copy your config file +COPY config.json /app/config/config.json + +# Copy your WASM files if needed +COPY wasm/*.wasm /app/wasm/ + +# You can override environment variables if needed +ENV RILOT_PORT=3000 +ENV RUST_LOG=info + +# Specify how to run Rilot with your config +ENTRYPOINT ["rilot"] +CMD ["/app/config/config.json"] + +# The container will automatically use the config at /app/config/config.json \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index ec4215b..42d4873 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,6 @@ use serde::Deserialize; +use crate::error::{Result, RilotError}; +use std::fs; #[derive(Debug, Deserialize, Clone)] pub struct ProxyRule { @@ -27,14 +29,14 @@ fn default_rule_type() -> String { "contain".to_string() } -use std::fs; - -pub fn load_config(path: &str) -> Config { - let data = fs::read_to_string(path).expect("Failed to read config.json"); - serde_json::from_str(&data).expect("Failed to parse config.json") +fn default_rewrite_mode() -> String { + "none".to_string() } +pub fn load_config(path: &str) -> Result { + let data = fs::read_to_string(path) + .map_err(|e| RilotError::ConfigError(format!("Failed to read config file: {}", e)))?; -fn default_rewrite_mode() -> String { - "none".to_string() + serde_json::from_str(&data) + .map_err(|e| RilotError::ConfigError(format!("Failed to parse config file: {}", e))) } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..0dacbbf --- /dev/null +++ b/src/error.rs @@ -0,0 +1,52 @@ +use thiserror::Error; +use std::io; + +#[derive(Error, Debug)] +pub enum RilotError { + #[error("Configuration error: {0}")] + ConfigError(String), + + #[error("WASM error: {0}")] + WasmError(String), + + #[error("Proxy error: {0}")] + ProxyError(String), + + #[error("IO error: {0}")] + IoError(#[from] io::Error), + + #[error("HTTP error: {0}")] + HttpError(String), + + #[error("Invalid header: {0}")] + InvalidHeader(String), + + #[error("Invalid URI: {0}")] + InvalidUri(String), + + #[error("Serialization error: {0}")] + SerializationError(String), + + #[error("Unknown error: {0}")] + Unknown(String), +} + +pub type Result = std::result::Result; + +impl From for RilotError { + fn from(err: anyhow::Error) -> Self { + RilotError::Unknown(err.to_string()) + } +} + +impl From for RilotError { + fn from(err: hyper::Error) -> Self { + RilotError::HttpError(err.to_string()) + } +} + +impl From for RilotError { + fn from(err: serde_json::Error) -> Self { + RilotError::SerializationError(err.to_string()) + } +} \ No newline at end of file diff --git a/src/logger.rs b/src/logger.rs new file mode 100644 index 0000000..384e5cb --- /dev/null +++ b/src/logger.rs @@ -0,0 +1,69 @@ +use log::{Level, LevelFilter, Metadata, Record}; +use std::io::{self, Write}; +use chrono::Local; + +pub struct Logger; + +impl log::Log for Logger { + fn enabled(&self, metadata: &Metadata) -> bool { + metadata.level() <= Level::Debug + } + + fn log(&self, record: &Record) { + if self.enabled(record.metadata()) { + let now = Local::now(); + let timestamp = now.format("%Y-%m-%d %H:%M:%S%.3f"); + + let level_str = match record.level() { + Level::Error => "❌ ERROR", + Level::Warn => "⚠️ WARN", + Level::Info => "ℹ️ INFO", + Level::Debug => "🔍 DEBUG", + Level::Trace => "🔎 TRACE", + }; + + let target = if record.target().starts_with("rilot") { + record.target() + } else { + "rilot" + }; + + let args = record.args(); + let file = record.file().unwrap_or("unknown"); + let line = record.line().unwrap_or(0); + + let output = format!( + "{} {} [{}:{}] {}: {}\n", + timestamp, + level_str, + file, + line, + target, + args + ); + + let _ = io::stderr().write_all(output.as_bytes()); + } + } + + fn flush(&self) { + let _ = io::stderr().flush(); + } +} + +pub fn init() { + let env = env_logger::Env::default() + .filter_or("RILOT_LOG", "info") + .write_style_or("RILOT_LOG_STYLE", "always"); + + let level = env_logger::Builder::from_env(env) + .format_timestamp(None) + .format_module_path(false) + .format_target(false) + .build() + .filter(); + + log::set_boxed_logger(Box::new(Logger)) + .map(|()| log::set_max_level(level)) + .expect("Failed to initialize logger"); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a5780ef..856313e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,17 +3,23 @@ use std::env; mod config; mod proxy; mod wasm_engine; +mod logger; +mod error; + +use error::{Result, RilotError}; #[tokio::main] -async fn main() { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); +async fn main() -> Result<()> { + // Initialize custom logger + logger::init(); let args: Vec = env::args().collect(); let config_path = args.get(1).map_or("./config.json", |p| p.as_str()); log::info!("🛠️ Loading configuration from: {}", config_path); - let cfg = config::load_config(config_path); + let cfg = config::load_config(config_path) + .map_err(|e| RilotError::ConfigError(format!("Failed to load config: {}", e)))?; log::info!("✅ Configuration loaded successfully."); if cfg.proxies.is_empty() { @@ -23,7 +29,9 @@ async fn main() { let config_arc = Arc::new(cfg); log::info!("🚀 Starting proxy server..."); - proxy::start_proxy(config_arc).await; + proxy::start_proxy(config_arc).await + .map_err(|e| RilotError::ProxyError(format!("Proxy server error: {}", e)))?; log::info!("👋 Proxy server shut down."); + Ok(()) } \ No newline at end of file diff --git a/src/proxy.rs b/src/proxy.rs index abf223d..b8437b4 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -11,8 +11,8 @@ use hyper::{ use hyper::service::{make_service_fn, service_fn}; use std::{collections::HashMap, convert::Infallible, net::SocketAddr, sync::Arc, str}; use serde::Serialize; +use crate::{config, wasm_engine, error::Result}; -use crate::{config, wasm_engine}; #[derive(Serialize)] struct WasmInput { method: String, @@ -21,8 +21,7 @@ struct WasmInput { body: String, } - -pub async fn start_proxy(config: Arc) { +pub async fn start_proxy(config: Arc) -> Result<()> { let make_svc = make_service_fn(move |_conn| { let cfg = config.clone(); let config_inner = cfg.clone(); @@ -41,15 +40,18 @@ pub async fn start_proxy(config: Arc) { let addr = SocketAddr::new(host.parse().expect("Invalid host"), port); - println!("🚀 Rilot proxy starting at http://{}", addr); + log::info!("🚀 Rilot proxy starting at http://{}", addr); let server = Server::bind(&addr).serve(make_svc); if let Err(e) = server.await { - eprintln!("❌ Server error: {}", e); + log::error!("❌ Server error: {}", e); + return Err(crate::error::RilotError::ProxyError(e.to_string())); } + + Ok(()) } -fn simple_response(status: StatusCode, body: &'static str) -> Result, Infallible> { +fn simple_response(status: StatusCode, body: &'static str) -> std::result::Result, Infallible> { Ok(Response::builder() .status(status) .header("Content-Type", "text/plain") @@ -60,11 +62,11 @@ fn simple_response(status: StatusCode, body: &'static str) -> Result, config: Arc, -) -> Result, Infallible> { +) -> std::result::Result, Infallible> { let path = req.uri().path().to_string(); let method = req.method().clone(); - println!("➡️ Received request: {} {}", method, path); + log::info!("➡️ Received request: {} {}", method, path); let matched_proxy = config.proxies.iter().find(|p| { match p.rule.r#type.as_str() { @@ -76,12 +78,12 @@ async fn handle_request( let proxy_config = match matched_proxy { Some(p) => p, None => { - println!("🚫 No matching proxy rule found for path: {}", path); - return simple_response(StatusCode::NOT_FOUND, "Not Found: No matching proxy rule."); + log::warn!("🚫 No matching proxy rule found for path: {}", path); + return simple_response(StatusCode::NOT_FOUND, "404: Not Found"); } }; - println!( + log::info!( "✅ Matched rule for '{}' to app '{}' ({})", path, proxy_config.app_name, proxy_config.app_uri ); @@ -99,7 +101,7 @@ async fn handle_request( let body_bytes = match hyper::body::to_bytes(req.body_mut()).await { Ok(bytes) => bytes, Err(e) => { - eprintln!("⚠️ Failed to read request body: {}", e); + log::error!("⚠️ Failed to read request body: {}", e); return simple_response(StatusCode::INTERNAL_SERVER_ERROR, "Error reading request body."); } }; @@ -107,7 +109,7 @@ async fn handle_request( let body_str = String::from_utf8_lossy(&body_bytes).to_string(); if let Some(wasm_file) = &proxy_config.override_file { - println!("⚙️ Running Wasm override: {}", wasm_file); + log::info!("⚙️ Running Wasm override: {}", wasm_file); let wasm_input = WasmInput { method: method.to_string(), path: path.clone(), @@ -118,16 +120,16 @@ async fn handle_request( let input_json = match serde_json::to_string(&wasm_input) { Ok(json) => json, Err(e) => { - eprintln!("⚠️ Failed to serialize input for Wasm: {}", e); + log::error!("⚠️ Failed to serialize input for Wasm: {}", e); return simple_response(StatusCode::INTERNAL_SERVER_ERROR, "Error preparing Wasm input."); } }; match wasm_engine::run_modify_request(wasm_file, &input_json).await { Ok(out) => { - println!("✅ Wasm execution successful. Output: {:?}", out); + log::info!("✅ Wasm execution successful. Output: {:?}", out); if let Some(new_target) = out.app_url { - println!("↪️ Overriding target URI to: {}", new_target); + log::info!("↪️ Overriding target URI to: {}", new_target); target_uri_str = new_target; } @@ -136,23 +138,23 @@ async fn handle_request( HeaderName::from_bytes(k.as_bytes()), HeaderValue::from_str(&v), ) { - println!("Adding/Updating header: {} = {}", k, v); + log::info!("Adding/Updating header: {} = {}", k, v); req.headers_mut().insert(name, value); } else { - eprintln!("⚠️ Invalid header from Wasm: {} = {}", k, v); + log::error!("⚠️ Invalid header from Wasm: {} = {}", k, v); } } for k in out.headers_to_remove { if let Ok(name) = HeaderName::from_bytes(k.as_bytes()) { - println!("Removing header: {}", k); + log::info!("Removing header: {}", k); req.headers_mut().remove(name); } else { - eprintln!("⚠️ Invalid header name to remove from Wasm: {}", k); + log::error!("⚠️ Invalid header name to remove from Wasm: {}", k); } } } Err(e) => { - eprintln!("❌ Wasm execution failed: {}", e); + log::error!("❌ Wasm execution failed: {}", e); return simple_response(StatusCode::INTERNAL_SERVER_ERROR, "Wasm override module failed."); } }; @@ -176,12 +178,12 @@ async fn handle_request( let final_uri = match Uri::try_from(&final_target_uri_str) { Ok(uri) => uri, Err(e) => { - eprintln!("⚠️ Failed to construct final target URI '{}': {}", final_target_uri_str, e); + log::error!("⚠️ Failed to construct final target URI '{}': {}", final_target_uri_str, e); return simple_response(StatusCode::INTERNAL_SERVER_ERROR, "Error constructing target URL."); } }; - println!("🚀 Forwarding request to: {}", final_uri); + log::info!("🚀 Forwarding request to: {}", final_uri); *req.uri_mut() = final_uri; *req.body_mut() = Body::from(body_bytes); // Use original bytes @@ -190,11 +192,11 @@ async fn handle_request( match client.request(req).await { Ok(backend_res) => { - println!("✅ Received response from backend: {}", backend_res.status()); + log::info!("✅ Received response from backend: {}", backend_res.status()); Ok(backend_res) }, Err(e) => { - eprintln!("❌ Error forwarding request: {}", e); + log::error!("❌ Error forwarding request: {}", e); simple_response(StatusCode::BAD_GATEWAY, "Error connecting to upstream service.") } }