Skip to content

Commit

Permalink
Node status API dockerfile and env vars (#4986)
Browse files Browse the repository at this point in the history
* feat: add dockerfile and env variables

* Added workflow for pushing node status api on harbor

* Misc changes to pathing and using yq instead of jq

* fix: change the way we read env vars for nyxd, nym api and explorer

* fix: docker build workflow

* Remove config in favor of clap args

* Added naming and tags

* change from value to result

---------

Co-authored-by: Lawrence Stalder <[email protected]>
Co-authored-by: dynco-nym <[email protected]>
  • Loading branch information
3 people committed Oct 28, 2024
1 parent e5a29cc commit 40d9321
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 121 deletions.
54 changes: 49 additions & 5 deletions .github/workflows/push-node-status-api.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
name: Build and upload Node Status API container to harbor.nymte.ch

on:
workflow_dispatch:

env:
WORKING_DIRECTORY: "nym-node-status-api"
CONTAINER_NAME: "node-status-api"

jobs:
my-job:
runs-on: arc-ubuntu-22.04
build-container:
runs-on: arc-ubuntu-22.04-dind
steps:
- name: my-step
run: echo "Hello World!"
- name: Login to Harbor
uses: docker/login-action@v3
with:
registry: harbor.nymte.ch
username: ${{ secrets.HARBOR_ROBOT_USERNAME }}
password: ${{ secrets.HARBOR_ROBOT_SECRET }}

- name: Checkout repo
uses: actions/checkout@v4

- name: Configure git identity
run: |
git config --global user.email "[email protected]"
git config --global user.name "Lawrence Stalder"
- name: Get version from cargo.toml
uses: mikefarah/[email protected]
id: get_version
with:
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml

- name: Check if tag exists
run: |
if git rev-parse ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
echo "Tag ${{ steps.get_version.outputs.result }} already exists"
fi
- name: Remove existing tag if exists
run: |
if git rev-parse ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
git push --delete origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
git tag -d ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
fi
- name: Create tag
run: |
git tag -a ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }} -m "Version ${{ steps.get_version.outputs.result }}"
git push origin ${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}
- name: BuildAndPushImageOnHarbor
run: |
docker build -f ${{ env.WORKING_DIRECTORY }}/Dockerfile . -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.result }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
6 changes: 3 additions & 3 deletions envs/mainnet.env
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ COCONUT_DKG_CONTRACT_ADDRESS=n19604yflqggs9mk2z26mqygq43q2kr3n932egxx630svywd5mp

REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy
STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
NYXD="https://rpc.nymtech.net"
NYM_API="https://validator.nymtech.net/api/"
NYXD=https://rpc.nymtech.net
NYM_API=https://validator.nymtech.net/api/
NYXD_WS="wss://rpc.nymtech.net/websocket"
EXPLORER_API="https://explorer.nymtech.net/api/"
EXPLORER_API=https://explorer.nymtech.net/api/
NYM_VPN_API="https://nymvpn.com/api"
11 changes: 8 additions & 3 deletions nym-node-status-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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",
] }
15 changes: 15 additions & 0 deletions nym-node-status-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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

RUN apt-get update && apt-get install -y ca-certificates

WORKDIR /nym

COPY --from=builder /usr/src/nym/target/release/nym-node-status-api ./
ENTRYPOINT [ "/nym/nym-node-status-api" ]
14 changes: 11 additions & 3 deletions nym-node-status-api/launch_node_status_api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ set -e

export RUST_LOG=${RUST_LOG:-debug}

export NYM_API_CLIENT_TIMEOUT=60;
export EXPLORER_CLIENT_TIMEOUT=60;
export NYM_API_CLIENT_TIMEOUT=60
export EXPLORER_CLIENT_TIMEOUT=60
#export NYXD=https://rpc.nymtech.net
#export NYM_API=https://validator.nymtech.net/api/
#export EXPLORER_API=https://explorer.nymtech.net/api/
#export NETWORK_NAME=mainnet

cargo run --package nym-node-status-api --release -- --config-env-file ../envs/mainnet.env
#cargo run --package nym-node-status-api --release -- --connection-url "sqlite://node-status-api.sqlite?mode=rwc"

cd ..
docker build -t node-status-api -f nym-node-status-api/Dockerfile .
docker run --env-file envs/mainnet.env -e NYM_NODE_STATUS_API_CONNECTION_URL="sqlite://node-status-api.sqlite?mode=rwc" node-status-api
62 changes: 57 additions & 5 deletions nym-node-status-api/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,69 @@
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 {
static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new();
PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print())
}

#[derive(Parser, Debug)]
#[derive(Clone, Debug, Parser)]
#[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)]
pub(crate) config_env_file: Option<std::path::PathBuf>,
/// Network name for the network to which we're connecting.
#[clap(long, env = "NETWORK_NAME")]
pub(crate) network_name: String,

/// Explorer api url.
#[clap(short, long, env = "EXPLORER_API")]
pub(crate) explorer_api: String,

/// Nym api url.
#[clap(short, long, env = "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 = "NYXD")]
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))
}
72 changes: 0 additions & 72 deletions nym-node-status-api/src/config.rs

This file was deleted.

5 changes: 1 addition & 4 deletions nym-node-status-api/src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 = SqliteConnectOptions::from_str(&connection_url)?
.create_if_missing(true)
.disable_statement_logging();
Expand Down
26 changes: 8 additions & 18 deletions nym-node-status-api/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
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;
mod http;
mod logging;
Expand All @@ -16,33 +12,27 @@ async fn main() -> anyhow::Result<()> {
logging::setup_tracing_logger();

let args = cli::Cli::parse();
// 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()?;
tracing::debug!("Using config:\n{:#?}", conf);
let connection_url = args.connection_url.clone();
tracing::debug!("Using config:\n{:#?}", args);

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();
let args_clone = args.clone();
tokio::spawn(async move {
monitor::spawn_in_background(db_pool, conf_clone).await;
monitor::spawn_in_background(db_pool, args_clone).await;
});
tracing::info!("Started monitor task");

let shutdown_handles = http::server::start_http_api(
storage.pool_owned().await,
conf.http_port(),
conf.nym_http_cache_ttl(),
args.http_port,
args.nym_http_cache_ttl,
)
.await
.expect("Failed to start server");

tracing::info!("Started HTTP server on port {}", conf.http_port());
tracing::info!("Started HTTP server on port {}", args.http_port);

wait_for_signal().await;

Expand Down
Loading

0 comments on commit 40d9321

Please sign in to comment.