feat: add dockerfile and env variables

This commit is contained in:
Fran Arbanas
2024-10-18 12:23:25 +02:00
parent 8d400ed4e0
commit a60f37ae88
6 changed files with 94 additions and 26 deletions
+8 -3
View File
@@ -16,7 +16,7 @@ rust-version.workspace = true
anyhow = { workspace = true }
axum = { workspace = true, features = ["tokio"] }
chrono = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
clap = { workspace = true, features = ["cargo", "derive", "env", "string"] }
cosmwasm-std = { workspace = true }
envy = { workspace = true }
futures-util = { workspace = true }
@@ -53,5 +53,10 @@ utoipauto = { workspace = true }
[build-dependencies]
anyhow = { workspace = true }
tokio = { workspace = true, features = ["macros" ] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { workspace = true, features = ["macros"] }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
] }
+13
View File
@@ -0,0 +1,13 @@
FROM rust:latest AS builder
COPY ./ /usr/src/nym
WORKDIR /usr/src/nym/nym-node-status-api
RUN cargo build --release
FROM ubuntu:24.04
WORKDIR /nym
COPY --from=builder /usr/src/nym/target/release/nym-node-status-api ./
ENTRYPOINT [ "/nym/nym-node-status-api" ]
+58 -2
View File
@@ -1,6 +1,7 @@
use clap::Parser;
use nym_bin_common::bin_info;
use std::sync::OnceLock;
use reqwest::Url;
use std::{sync::OnceLock, time::Duration};
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
@@ -12,6 +13,61 @@ fn pretty_build_info_static() -> &'static str {
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
pub(crate) struct Cli {
/// Path pointing to an env file that configures the Nym API.
#[clap(short, long)]
#[clap(short, long, env = "NYM_NODE_STATUS_API_ENV_FILE")]
pub(crate) config_env_file: Option<std::path::PathBuf>,
/// Network name for the network to which we're connecting.
#[clap(long, env = "NYM_NODE_STATUS_API_NETWORK_NAME")]
pub(crate) network_name: String,
/// Explorer api url.
#[clap(short, long, env = "NYM_NODE_STATUS_API_EXPLORER_API")]
pub(crate) explorer_api: String,
/// Nym api url.
#[clap(short, long, env = "NYM_NODE_STATUS_API_NYM_API")]
pub(crate) nym_api: String,
/// TTL for the http cache.
#[clap(
long,
default_value_t = 30,
env = "NYM_NODE_STATUS_API_NYM_HTTP_CACHE_TTL"
)]
pub(crate) nym_http_cache_ttl: u64,
/// HTTP port on which to run node status api.
#[clap(long, default_value_t = 8000, env = "NYM_NODE_STATUS_API_HTTP_PORT")]
pub(crate) http_port: u16,
/// Nyxd address.
#[clap(long, env = "NYM_NODE_STATUS_API_NYXD_ADDR")]
pub(crate) nyxd_addr: Url,
/// Nym api client timeout.
#[clap(
long,
default_value = "15",
env = "NYM_NODE_STATUS_API_NYM_API_CLIENT_TIMEOUT"
)]
#[arg(value_parser = parse_duration)]
pub(crate) nym_api_client_timeout: Duration,
/// Explorer api client timeout.
#[clap(
long,
default_value = "15",
env = "NYM_NODE_STATUS_API_EXPLORER_CLIENT_TIMEOUT"
)]
#[arg(value_parser = parse_duration)]
pub(crate) explorer_client_timeout: Duration,
/// Connection url for the database.
#[clap(long, env = "NYM_NODE_STATUS_API_CONNECTION_URL")]
pub(crate) connection_url: String,
}
fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
let seconds = arg.parse()?;
Ok(std::time::Duration::from_secs(seconds))
}
+11 -10
View File
@@ -1,8 +1,9 @@
use anyhow::anyhow;
use reqwest::Url;
use serde::Deserialize;
use std::time::Duration;
use crate::cli::Cli;
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct Config {
#[serde(default = "Config::default_http_cache_seconds")]
@@ -17,6 +18,15 @@ pub(crate) struct Config {
}
impl Config {
pub(crate) fn from_args(args: Cli) -> Self {
Config {
nym_http_cache_ttl: args.nym_http_cache_ttl,
http_port: args.http_port,
nyxd_addr: args.nyxd_addr,
explorer_client_timeout: args.explorer_client_timeout,
}
}
pub(crate) fn from_env() -> anyhow::Result<Self> {
envy::from_env::<Self>().map_err(|e| {
tracing::error!("Failed to load config from env: {e}");
@@ -61,12 +71,3 @@ where
let secs: u64 = s.parse().map_err(serde::de::Error::custom)?;
Ok(Duration::from_secs(secs))
}
pub(super) fn read_env_var(env_var: &str) -> anyhow::Result<String> {
std::env::var(env_var)
.map_err(|_| anyhow!("You need to set {}", env_var))
.map(|value| {
tracing::trace!("{}={}", env_var, value);
value
})
}
+1 -4
View File
@@ -1,13 +1,11 @@
use std::str::FromStr;
use crate::read_env_var;
use anyhow::{anyhow, Result};
use sqlx::{migrate::Migrator, sqlite::SqliteConnectOptions, ConnectOptions, SqlitePool};
pub(crate) mod models;
pub(crate) mod queries;
pub(crate) const DATABASE_URL_ENV_VAR: &str = "DATABASE_URL";
static MIGRATOR: Migrator = sqlx::migrate!("./migrations");
pub(crate) type DbPool = SqlitePool;
@@ -17,8 +15,7 @@ pub(crate) struct Storage {
}
impl Storage {
pub async fn init() -> Result<Self> {
let connection_url = read_env_var(DATABASE_URL_ENV_VAR)?;
pub async fn init(connection_url: String) -> Result<Self> {
let connect_options = {
let connect_options = SqliteConnectOptions::from_str(&connection_url)?;
let mut connect_options = connect_options.create_if_missing(true);
+3 -7
View File
@@ -2,8 +2,6 @@ use clap::Parser;
use nym_network_defaults::setup_env;
use nym_task::signal::wait_for_signal;
use crate::config::read_env_var;
mod cli;
mod config;
mod db;
@@ -19,14 +17,12 @@ async fn main() -> anyhow::Result<()> {
// if dotenv file is present, load its values
// otherwise, default to mainnet
setup_env(args.config_env_file.as_ref());
tracing::debug!("{:?}", read_env_var("NETWORK_NAME"));
tracing::debug!("{:?}", read_env_var("EXPLORER_API"));
tracing::debug!("{:?}", read_env_var("NYM_API"));
let conf = config::Config::from_env()?;
let connection_url = args.connection_url.clone();
let conf = config::Config::from_args(args);
tracing::debug!("Using config:\n{:#?}", conf);
let storage = db::Storage::init().await?;
let storage = db::Storage::init(connection_url).await?;
let db_pool = storage.pool_owned().await;
let conf_clone = conf.clone();
tokio::spawn(async move {