From d3eb2789eb71570b464d6bcffb670606e49877a6 Mon Sep 17 00:00:00 2001 From: Starblessed Date: Sat, 26 Sep 2026 22:13:02 -0300 Subject: [PATCH 1/2] add: functional dockerfile and docker-compose config --- .Dockerignore | 1 + .env.example | 3 + .gitignore | 4 + Cargo.lock | 180 ++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- Dockerfile | 22 +++++ docker-compose.yaml | 14 +++ src/main.rs | 8 +- src/server/mod.rs | 7 +- src/session_manager/mod.rs | 15 +++- 10 files changed, 248 insertions(+), 10 deletions(-) create mode 100644 .Dockerignore create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 docker-compose.yaml diff --git a/.Dockerignore b/.Dockerignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/.Dockerignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a0bb707 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +IP=0.0.0.0 +PORT=8411 +RUST_LOG=info \ No newline at end of file diff --git a/.gitignore b/.gitignore index ea8c4bf..5e22f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ +# Rust build dir /target + +# Environment Variables +.env \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e822c03..7750027 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "1.0.0" @@ -52,6 +61,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.13.1" @@ -136,12 +151,68 @@ dependencies = [ "winapi", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "env_filter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "ephemeral" version = "0.1.0" dependencies = [ "clap", "datetime", + "env_logger", + "log", "serde", "serde_json", "tokio", @@ -220,6 +291,43 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jiff" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "js-sys" version = "0.3.106" @@ -255,6 +363,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + [[package]] name = "memchr" version = "2.8.3" @@ -332,6 +446,21 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + [[package]] name = "proc-macro2" version = "1.0.107" @@ -368,9 +497,38 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.1", ] +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + [[package]] name = "rustversion" version = "1.0.23" @@ -486,6 +644,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "tokio" version = "1.53.1" diff --git a/Cargo.toml b/Cargo.toml index 898ca72..27a7f2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,10 @@ version = "0.1.0" edition = "2024" [dependencies] -clap = { version = "4.6.7", features = ["derive"] } +clap = { version = "4.6.7", features = ["derive", "env"] } datetime = "0.5.2" +env_logger = "0.11.11" +log = "0.4.34" serde = { version = "1.0.229", features = ["derive"] } serde_json = "1.0.151" tokio = { version = "1.53.1", features = ["full"] } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..efcd1a4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# Build +FROM rust:1-slim AS builder +WORKDIR /app +COPY Cargo.toml Cargo.lock* ./ +COPY src ./src +RUN cargo build --release + +# Run +FROM debian:bookworm-slim +WORKDIR /app + +ARG IP +ARG PORT + +ENV IP=$IP +ENV PORT=$PORT + +COPY --from=builder /app/target/release/ephemeral /usr/local/bin/ephemeral + +EXPOSE $PORT + +ENTRYPOINT ["/usr/local/bin/ephemeral"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..ed7e0ca --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,14 @@ +services: + ephemeral: + build: + context: . + dockerfile: Dockerfile + args: + - IP=${IP} + - PORT=${PORT} + environment: + - IP=${IP} + - PORT=${PORT} + - RUST_LOG=${RUST_LOG:-info} + ports: + - "${PORT}:${PORT}" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 67eab9c..7c0912e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use clap::Parser; +use log::info; mod server; pub mod session; @@ -8,25 +9,28 @@ pub mod utils; #[derive(Parser)] struct Args { /// Host IP Address + #[arg(long, env = "IP")] ip: String, /// Server Application Port + #[arg(long, env = "PORT")] port: Option, } #[tokio::main] async fn main() { + env_logger::init(); let args = Args::parse(); let address: server::Address = { let port = match args.port { Some(port) => { if port != server::STANDARD_PORT { - println!("Custom port provided: {}", port); + info!("Custom port provided: {}", port); } port } None => { - println!( + info!( "No port provided, proceeding with standard: {}", server::STANDARD_PORT ); diff --git a/src/server/mod.rs b/src/server/mod.rs index a2a5a3c..4d4cd60 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,5 +1,6 @@ use crate::session_manager::SessionManager; use datetime::Instant; +use log::info; use tokio::io::Result; use tokio::net::TcpListener; @@ -42,14 +43,14 @@ impl Server { pub async fn run(&self) -> Result<()> { let listener = TcpListener::bind(&self.address.to_string()).await?; - println!("Server started at: {:?}", self.started); - println!("Ephemeral Server listening on {}", self.address); + info!("Server started at: {:?}", self.started); + info!("Ephemeral Server listening on {}", self.address); // TODO: Accept connections and redirect them to the session manager loop { let (socket, client_addr) = listener.accept().await?; - println!("New connection established with: {}", client_addr); + info!("New connection established with: {}", client_addr); self.manager.add_socket(socket).await; } diff --git a/src/session_manager/mod.rs b/src/session_manager/mod.rs index 8ccb7b8..596008d 100644 --- a/src/session_manager/mod.rs +++ b/src/session_manager/mod.rs @@ -1,5 +1,6 @@ use crate::session::{Session, SessionError}; use core::str; +use log::{error, info, warn}; use serde::Deserialize; use serde_json::{Map, Value, json}; use std::collections::HashMap; @@ -119,7 +120,7 @@ impl SessionManager { } } Err(e) => { - eprintln!("parse error: {e}; input: {line:?}"); + error!("parse error: {e}; input: {line:?}"); break; } }; @@ -127,6 +128,7 @@ impl SessionManager { Err(_) => break, } } + info!("Session {} terminated.", &session_id); sessions.lock().await.remove(&session_id); } @@ -139,7 +141,7 @@ impl SessionManager { return json!({"error": "Command cannot be None!"}).to_string(); }; - println!("Session {} received command {}", session.id, command); + info!("Session {} received command {}", session.id, command); let payload: &Payload = &request.payload; @@ -152,7 +154,10 @@ impl SessionManager { match result { Ok(data) => data, - Err(e) => Map::from_iter([("error".to_string(), json!(format!("{:?}", e)))]), + Err(e) => { + warn!("get_data failed with error: {:?}", e); + Map::from_iter([("error".to_string(), json!(format!("{:?}", e)))]) + } } } @@ -167,6 +172,7 @@ impl SessionManager { match result { Ok(data) => data, Err(e) => { + warn!("get_partial_data failed with error: {:?}", e); Map::from_iter([("error".to_string(), json!(format!("{:?}", e)))]) } } @@ -194,6 +200,7 @@ impl SessionManager { // CMD = set_partial -> Requires data: Map // May return an error if: // - payload cannot be parsed to type Map + // - session data wasn't previously initialized "set_partial" => { if let Payload::Dict(data) = payload { let result = session.set_partial_data(Some(data.clone())); @@ -201,6 +208,7 @@ impl SessionManager { match result { Ok(_) => Map::from_iter([("result".to_string(), json!("ok"))]), Err(e) => { + warn!("set_partial_data failed with error: {:?}", e); Map::from_iter([("error".to_string(), json!(format!("{:?}", e)))]) } } @@ -208,6 +216,7 @@ impl SessionManager { Map::from_iter([("error".to_string(), json!("set_partial requires an object"))]) } } + // CMD = wipeout "wipeout" => { session.wipeout(); From d664770aa00f5c1233e0eafacb401dd3b562e829 Mon Sep 17 00:00:00 2001 From: Starblessed Date: Sat, 26 Sep 2026 22:16:04 -0300 Subject: [PATCH 2/2] fix: small redundant reference lint issue --- src/session_manager/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/session_manager/mod.rs b/src/session_manager/mod.rs index 596008d..ee01a89 100644 --- a/src/session_manager/mod.rs +++ b/src/session_manager/mod.rs @@ -128,7 +128,7 @@ impl SessionManager { Err(_) => break, } } - info!("Session {} terminated.", &session_id); + info!("Session {} terminated.", session_id); sessions.lock().await.remove(&session_id); }