Skip to content

Commit

Permalink
ci: [torrust#384] add container healthcheck for index service
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Nov 16, 2023
1 parent 04b70ba commit c3eedc0
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 13 deletions.
9 changes: 7 additions & 2 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ COPY --from=build \
RUN cargo nextest run --workspace-remap /test/src/ --extract-to /test/src/ --no-run --archive-file /test/torrust-index.tar.zst
RUN cargo nextest run --workspace-remap /test/src/ --target-dir-remap /test/src/target/ --cargo-metadata /test/src/target/nextest/cargo-metadata.json --binaries-metadata /test/src/target/nextest/binaries-metadata.json

RUN mkdir -p /app/bin/; cp -l /test/src/target/release/torrust-index /app/bin/torrust-index
RUN mkdir -p /app/bin/; \
cp -l /test/src/target/release/torrust-index /app/bin/torrust-index; \
cp -l /test/src/target/release/health_check /app/bin/health_check;
# RUN mkdir -p /app/lib/; cp -l $(realpath $(ldd /app/bin/torrust-index | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN chown -R root:root /app; chmod -R u=rw,go=r,a+X /app; chmod -R a+x /app/bin

Expand All @@ -99,11 +101,13 @@ ARG TORRUST_INDEX_PATH_CONFIG="/etc/torrust/index/index.toml"
ARG TORRUST_INDEX_DATABASE_DRIVER="sqlite3"
ARG USER_ID=1000
ARG API_PORT=3001
ARG HEALTH_CHECK_PORT=3002

ENV TORRUST_INDEX_PATH_CONFIG=${TORRUST_INDEX_PATH_CONFIG}
ENV TORRUST_INDEX_DATABASE_DRIVER=${TORRUST_INDEX_DATABASE_DRIVER}
ENV USER_ID=${USER_ID}
ENV API_PORT=${API_PORT}
ENV HEALTH_CHECK_PORT=${HEALTH_CHECK_PORT}
ENV TZ=Etc/UTC

EXPOSE ${API_PORT}/tcp
Expand All @@ -130,5 +134,6 @@ CMD ["sh"]
FROM runtime as release
ENV RUNTIME="release"
COPY --from=test /app/ /usr/
# HEALTHCHECK CMD ["/usr/bin/wget", "--no-verbose", "--tries=1", "--spider", "localhost:${API_PORT}/version"]
HEALTHCHECK --interval=5s --timeout=5s --start-period=3s --retries=3 \
CMD /usr/bin/health_check http://localhost:${HEALTH_CHECK_PORT}/health_check || exit 1
CMD ["/usr/bin/torrust-index"]
8 changes: 4 additions & 4 deletions contrib/dev-tools/container/e2e/mysql/run-e2e-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ echo "Running E2E tests using MySQL ..."
./contrib/dev-tools/container/e2e/mysql/e2e-env-up.sh || exit 1

# Wait for conatiners to be healthy
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-mysql-1 10 3
# todo: implement healthchecks for tracker and index and wait until they are healthy
#wait_for_container torrust-tracker-1 10 3
#wait_for_container torrust-idx-back-1 10 3
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-mysql-1 10 3 || exit 1
# todo: implement healthchecks for the tracker and wait until it's healthy
#./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-tracker-1 10 3
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-index-1 10 3 || exit 1
sleep 20s

# Just to make sure that everything is up and running
Expand Down
8 changes: 4 additions & 4 deletions contrib/dev-tools/container/e2e/sqlite/run-e2e-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ echo "Running E2E tests using SQLite ..."
./contrib/dev-tools/container/e2e/sqlite/e2e-env-up.sh || exit 1

# Wait for conatiners to be healthy
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-mysql-1 10 3
# todo: implement healthchecks for tracker and index and wait until they are healthy
#wait_for_container torrust-tracker-1 10 3
#wait_for_container torrust-idx-back-1 10 3
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-mysql-1 10 3 || exit 1
# todo: implement healthchecks for the tracker and wait until it's healthy
#./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-tracker-1 10 3
./contrib/dev-tools/container/functions/wait_for_container_to_be_healthy.sh torrust-index-1 10 3 || exit 1
sleep 20s

# Just to make sure that everything is up and running
Expand Down
44 changes: 41 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::net::SocketAddr;
use std::sync::Arc;

use axum::routing::get;
use axum::{Json, Router};
use log::info;
use serde_json::{json, Value};
use tokio::task::JoinHandle;

use crate::bootstrap::logging;
Expand All @@ -22,6 +26,8 @@ use crate::web::api::v1::auth::Authentication;
use crate::web::api::{start, Version};
use crate::{mailer, tracker};

const HEALTH_CHECK_PORT: u16 = 3002;

pub struct Running {
pub api_socket_addr: SocketAddr,
pub api_server: Option<JoinHandle<std::result::Result<(), std::io::Error>>>,
Expand Down Expand Up @@ -159,6 +165,8 @@ pub async fn run(configuration: Configuration, api_version: &Version) -> Running
let weak_tracker_statistics_importer = Arc::downgrade(&tracker_statistics_importer);

let tracker_statistics_importer_handle = tokio::spawn(async move {
info!("Tracker statistics importer started");

let interval = std::time::Duration::from_secs(torrent_info_update_interval);
let mut interval = tokio::time::interval(interval);
interval.tick().await; // first tick is immediate...
Expand All @@ -173,12 +181,42 @@ pub async fn run(configuration: Configuration, api_version: &Version) -> Running
});

// Start API server

let running_api = start(app_data, &net_ip, net_port, api_version).await;

Running {
// Full running application
let app = Running {
api_socket_addr: running_api.socket_addr,
api_server: running_api.api_server,
tracker_data_importer_handle: tracker_statistics_importer_handle,
}
};

// Start Health Checker
// This must be done after launching the other services because it does not
// re-check the health of all services.
let _health_check_handle = tokio::spawn(async move {
let app = Router::new().route("/health_check", get(get(health_check)));

let addr = format!("127.0.0.1:{HEALTH_CHECK_PORT}");

info!("Health checker listening on http://{}/health_check", addr);

axum::Server::bind(&addr.parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
});

app
}

/// It runs a health check on the application.
///
/// For the time being, we only return ok if the application services were
/// launched. This services has to be launched after launching all the other
/// application services.
///
/// It's used for container health check when the application is containerized.
async fn health_check() -> Json<Value> {
// todo: check that services are healthy
Json(json!({ "status": "Ok" }))
}
34 changes: 34 additions & 0 deletions src/bin/health_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! Command line tool to parse a torrent file and print the decoded torrent.
//!
//! It's only used for debugging purposes.
use std::{env, process};

#[tokio::main]
async fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: cargo run --bin health_check <HEALTH_URL>");
eprintln!("Example: cargo run --bin health_check http://localhost:3002/health_check");
std::process::exit(1);
}

println!("Health check ...");

let url = &args[1].clone();

match reqwest::get(url).await {
Ok(response) => {
if response.status().is_success() {
println!("STATUS: {}", response.status());
process::exit(0);
} else {
println!("Non-success status received.");
process::exit(1);
}
}
Err(err) => {
println!("ERROR: {err}");
process::exit(1);
}
}
}

0 comments on commit c3eedc0

Please sign in to comment.