diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..94a969dc1f2264778bbdf7ecd0917c3cc4c7f9be --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +/target +.env +Dockerfile \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5ffc2ce997518f8aaa8d2457548d246261efda32..af965808505f24eca6498781a71d48d5c6268168 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,8 @@ stages: .test-template: tags: - kube + except: + - master image: rust:1.67.1-buster stage: test interruptible: true @@ -35,3 +37,16 @@ fmt: script: - rustup component add rustfmt - pre-commit run fmt -av + +build_img: + tags: + - kube + only: + - master + image: + name: r.j3ss.co/img + entrypoint: [""] + script: + - img login --password "${DOCKER_PASSWORD}" --username "${DOCKER_USER}" "${DOCKER_REGISTRY}" + - img build --no-console -t docker.le-memese.com/bots/s3bot:latest . + - img push docker.le-memese.com/bots/s3bot:latest diff --git a/Cargo.lock b/Cargo.lock index 804087c3f1f65b918d6d0ce00bae60908fa14300..48e9db9dfe516c23feb6dfd77fa6d6a5c598e352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1964,6 +1964,7 @@ dependencies = [ "libc", "memchr", "mio", + "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", diff --git a/Cargo.toml b/Cargo.toml index d86072d128bddbfb889be2eba361269b820f5ed6..bc66a3b666993989f4e18730e03b3bdafae004c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,9 @@ rand = "0.8.5" rayon = "1.6.1" serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.93" -tokio = { version = "1.25.0", features = ["bytes", "rt", "macros"] } +tokio = { version = "1.25.0", features = [ + "bytes", + "rt", + "macros", + "rt-multi-thread", +] } diff --git a/Dockerfile b/Dockerfile index 08ebc90f0d45884285702206eec16ad0e024961b..54495390c433c5ac6f2239133c8490b2bdf62a54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,15 @@ -FROM rust:1.67.1-alpine3.17 as builder +FROM rust:1.67.1-buster as builder WORKDIR /app -COPY Cargo.toml Cargo.lock ./ +COPY Cargo.toml Cargo.lock askama.toml ./ COPY src ./src +COPY static ./static RUN cargo build --release --all-features FROM debian:bullseye-20230109-slim as base +WORKDIR / + RUN apt-get update \ && apt-get install -y openssl ca-certificates \ && rm -rf /var/lib/apt/lists/* @@ -21,4 +24,5 @@ FROM base as rootless RUN useradd --create-home -u 1000 --user-group s3bot WORKDIR /home/s3bot +RUN mv /static ./static USER s3bot diff --git a/src/main.rs b/src/main.rs index aa91b0e893b702671650770dcfc02bf553bf66de..1d4ed0d8f8bead92de0d5f527789f8576ebede54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ -use futures::{stream::FuturesUnordered, StreamExt}; +use futures::{stream::FuturesUnordered, Future}; use std::sync::Arc; use tokio::sync::RwLock; use clap::Parser; +use futures::StreamExt; use logging::setup_logger; mod args; @@ -11,7 +12,12 @@ mod logging; mod server; pub mod utils; -#[tokio::main(flavor = "current_thread")] +async fn error_wrap<T>(fut: impl Future<Output = std::io::Result<T>>) -> anyhow::Result<T> { + let res = fut.await?; + Ok(res) +} + +#[tokio::main] async fn main() -> anyhow::Result<()> { dotenvy::dotenv().ok(); let args = args::Arguments::parse(); @@ -22,29 +28,24 @@ async fn main() -> anyhow::Result<()> { let bot_token = token_lock.clone(); let server_token = token_lock.clone(); - let local_set = tokio::task::LocalSet::new(); - local_set - .run_until(async { - let tasks = vec![ - tokio::task::spawn_local(bot::start(args.bot.clone(), bot_token)), - tokio::task::spawn_local(server::start(args.server.clone(), server_token)), - ]; - // Here we wait for one async task to complete. - let completed = tasks - .into_iter() - .collect::<FuturesUnordered<_>>() - .take(1) - .collect::<Vec<_>>() - .await; - // Now we get all completed futures (one future), - // and return it's result. - if let Some(fut) = completed.into_iter().next() { - fut? - } else { - Ok(()) - } - }) - .await?; - - Ok(()) + let web_server = server::create(args.server.clone(), server_token)?; + let bot_future = bot::start(args.bot.clone(), bot_token); + + let tasks = [ + tokio::task::spawn(bot_future), + tokio::task::spawn(error_wrap(web_server)), + ]; + + let completed = tasks + .into_iter() + .collect::<FuturesUnordered<_>>() + .take(1) + .collect::<Vec<_>>() + .await; + + if let Some(fut) = completed.into_iter().next() { + fut? + } else { + Ok(()) + } } diff --git a/src/server/main.rs b/src/server/main.rs index 016606fd539c8f85afe5b33f9c3483d5e4cec7b7..8559ea06af58f2075725f79d7092f43db2af1033 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -1,15 +1,15 @@ use std::sync::Arc; use tokio::sync::RwLock; -use actix_web::{web::Data, App, HttpServer}; +use actix_web::{dev::Server, web::Data, App, HttpServer}; use crate::args::ServerConfig; use super::routes::{healthcheck, index, login}; -pub async fn start(args: ServerConfig, token: Arc<RwLock<Option<String>>>) -> anyhow::Result<()> { +pub fn create(args: ServerConfig, token: Arc<RwLock<Option<String>>>) -> anyhow::Result<Server> { let addr = (args.host.clone(), args.port); - HttpServer::new(move || { + let server = HttpServer::new(move || { App::new() .wrap(actix_web::middleware::Logger::new( "\"%r\" \"-\" \"%s\" \"%a\" \"%D\"", @@ -23,7 +23,6 @@ pub async fn start(args: ServerConfig, token: Arc<RwLock<Option<String>>>) -> an }) .bind(addr)? .workers(1) - .run() - .await?; - Ok(()) + .run(); + Ok(server) } diff --git a/src/server/mod.rs b/src/server/mod.rs index f35abb767028ff61dd8a83e413d8862bb770e7bf..4092409882b66f62f37ec96842126ed23a1f91c9 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -3,4 +3,4 @@ mod routes; mod schema; mod templates; -pub use main::start; +pub use main::create;