Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A meta endpoint serving hostname and other basic info #68

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ jobs:
run: cargo clippy --all-targets -- -D warnings

- name: finally, get picky about formatting
run: cargo fmt --check
run: |
cargo fmt --check || \
(echo "Fix formatting errors by running \`just lint\` locally."; exit 1)

cargo-deny:
runs-on: ubuntu-latest
Expand Down
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name = "serval-agent"
version = "0.1.0"
edition = "2021"
license = "BSD-2-Clause-Patent"
build = "build.rs"

[dependencies]
anyhow = { workspace = true }
Expand All @@ -16,6 +17,7 @@ dotenvy = "0.15.6"
engine = { path = "../engine" }
env_logger = { workspace = true }
futures = "0.3.28"
gethostname = "0.4.2"
http = "0.2.8"
hyper = "0.14.23"
log = "0.4.17"
Expand All @@ -35,3 +37,6 @@ toml = { workspace = true }
urlencoding = "2.1.2"
utils = { path = "../utils" }
uuid = { workspace = true }

[build-dependencies]
vergen = { version = "8.1.3", features = ["build", "cargo", "git", "gitcl", "rustc"] }
14 changes: 14 additions & 0 deletions agent/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::error::Error;

use vergen::EmitBuilder;

fn main() -> Result<(), Box<dyn Error>> {
// Emit the instructions
EmitBuilder::builder()
.all_build()
.all_cargo()
.all_git()
.all_rustc()
.emit()?;
Ok(())
}
19 changes: 18 additions & 1 deletion agent/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use std::collections::HashMap;
use std::time::Duration;

use anyhow::Result;
use axum::extract::State;
use axum::http::{Request, StatusCode};
use axum::middleware::Next;
use axum::response::{IntoResponse, Response};
use axum::Json;
use http::header::HeaderValue;
use utils::mesh::PeerMetadata;

use crate::structures::AppState;
use crate::structures::{AgentInfo, AppState, MESH};

pub mod v1;
// Follow this pattern for additional major versions. E.g.,
Expand Down Expand Up @@ -52,3 +57,15 @@ pub async fn monitor_status(_state: State<AppState>) -> impl IntoResponse {
metrics::increment_counter!("monitor:status");
StatusCode::NOT_IMPLEMENTED
}

/// Provide agent status information.
pub async fn agent_info(state: State<AppState>) -> Json<AgentInfo> {
metrics::increment_counter!("agent:info");
Json(AgentInfo::new(&state))
}

/// Provide agent peer information.
pub async fn agent_peers(_state: State<AppState>) -> Json<HashMap<PeerMetadata, Duration>> {
metrics::increment_counter!("agent:peers");
Json(MESH.get().unwrap().peer_latencies().await)
}
4 changes: 3 additions & 1 deletion agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ fn init_router(state: &Arc<RunnerState>) -> Router {

let mut router: Router<Arc<RunnerState>, Body> = Router::new()
.route("/monitor/ping", get(ping))
.route("/monitor/status", get(monitor_status));
.route("/monitor/status", get(monitor_status))
.route("/agent/info", get(agent_info))
.route("/agent/peers", get(agent_peers));
router = v1::mesh::mount(router);

// NOTE: We have two of these now. If we develop a third, generalize this pattern.
Expand Down
57 changes: 57 additions & 0 deletions agent/src/structures/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;

use anyhow::Result;
use engine::extensions::{load_extensions, ServalExtension};
use gethostname::gethostname;
use once_cell::sync::OnceCell;
use serde::Serialize;
use utils::errors::ServalError;
use utils::mesh::ServalMesh;
use uuid::Uuid;
Expand All @@ -21,6 +24,7 @@ pub struct RunnerState {
pub should_run_jobs: bool,
pub should_run_scheduler: bool,
pub has_storage: bool,
pub start_timestamp: Instant,
}

impl RunnerState {
Expand Down Expand Up @@ -53,8 +57,61 @@ impl RunnerState {
should_run_jobs,
should_run_scheduler,
has_storage,
start_timestamp: Instant::now(),
})
}
}

pub type AppState = Arc<RunnerState>;

/// Agent metadata.
#[derive(Serialize)]
struct BuildInfo {
build_timestamp: String,
build_date: String,
git_branch: String,
git_timestamp: String,
git_date: String,
git_hash: String,
git_describe: String,
rustc_host_triple: String,
rustc_version: String,
cargo_target_triple: String,
}

impl BuildInfo {
fn new() -> BuildInfo {
BuildInfo {
build_timestamp: String::from(env!("VERGEN_BUILD_TIMESTAMP")),
build_date: String::from(env!("VERGEN_BUILD_DATE")),
git_branch: String::from(env!("VERGEN_GIT_BRANCH")),
git_timestamp: String::from(env!("VERGEN_GIT_COMMIT_TIMESTAMP")),
git_date: String::from(env!("VERGEN_GIT_COMMIT_DATE")),
git_hash: String::from(env!("VERGEN_GIT_SHA")),
git_describe: String::from(env!("VERGEN_GIT_DESCRIBE")),
rustc_host_triple: String::from(env!("VERGEN_RUSTC_HOST_TRIPLE")),
rustc_version: String::from(env!("VERGEN_RUSTC_SEMVER")),
cargo_target_triple: String::from(env!("VERGEN_CARGO_TARGET_TRIPLE")),
}
}
}

/// Agent metadata.
#[derive(Serialize)]
pub struct AgentInfo {
hostname: String,
instance_id: Uuid,
uptime: f64,
build_info: BuildInfo,
}

impl AgentInfo {
pub fn new(state: &AppState) -> AgentInfo {
AgentInfo {
hostname: gethostname().into_string().expect("Failed to get hostname"),
instance_id: state.instance_id,
uptime: state.start_timestamp.elapsed().as_secs_f64(),
build_info: BuildInfo::new(),
}
}
}