Files
nym/nym-node-status-api/nym-node-status-agent/src/probe.rs
T
Jędrzej Stuczyński b3d02e3ba7 feat: NS ticket faucet (#6047)
* ns-api: remove sqlite support

ns-api: add env var to skip migrations for local dev

ns-api: tidy up imports

ns-api: fix deserialisation fo node descriptions

update dockerfile

update README

fix up README and example env

ns-api: bump major version to 4

ns-api: add more geoip data and new performance field in dvpn responses

* ability to import partial ticketbooks

* wip: adding common ecash state to NS API

* buffering ticketbooks

* wip

* distribute tickets when getting testrun assignment

* passing ticketbook data to gateway probe

* wrapped around storage tx

* ticketbook query fixes

* clippy

* modified testrun assignment to always return tickets

* Update version

* Update push-node-status-agent.yaml

* Update Cargo.toml

* add entrypoint for ns agents

* sqlx prepare and cargo fmt

* clippy fixes

* Update ci-check-ns-api-version.yml

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: benedetta davico <46782255+benedettadavico@users.noreply.github.com>
Co-authored-by: benedettadavico <benedetta.davico@gmail.com>
2025-09-29 14:53:15 +01:00

126 lines
4.6 KiB
Rust

use nym_node_status_client::models::{AttachedTicketMaterials, VersionedSerialise};
use tracing::{debug, error, info};
pub(crate) struct GwProbe {
path: String,
}
impl GwProbe {
pub(crate) fn new(probe_path: String) -> Self {
Self { path: probe_path }
}
pub(crate) async fn version(&self) -> String {
debug!("Attempting to execute binary at: {}", &self.path);
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
match tokio::fs::metadata(&self.path).await {
Ok(metadata) => {
let perms = metadata.permissions();
let mode = perms.mode();
if mode & 0o111 == 0 {
error!(
"Binary is not executable: {} (mode: {:o})",
&self.path, mode
);
return "Binary is not executable".to_string();
}
debug!("Binary exists with permissions: {:o}", mode);
}
Err(e) => {
error!("Failed to stat binary at {}: {}", &self.path, e);
return format!("Failed to access binary: {e}");
}
}
}
let mut command = tokio::process::Command::new(&self.path);
command.stdout(std::process::Stdio::piped());
command.arg("--version");
info!("Executing command: {:?} --version", &self.path);
match command.spawn() {
Ok(child) => match child.wait_with_output().await {
Ok(output) => {
if output.status.success() {
String::from_utf8(output.stdout)
.unwrap_or_else(|_| "Unable to parse version output".to_string())
} else {
let stderr = String::from_utf8(output.stderr)
.unwrap_or_else(|_| "Unable to parse error output".to_string());
error!(
"Command failed with exit code {}: {}",
output.status.code().unwrap_or(-1),
stderr
);
format!("Command failed: {stderr}")
}
}
Err(e) => {
error!("Failed to get command output: {}", e);
format!("Failed to get command output: {e}")
}
},
Err(e) => {
error!("Failed to spawn process: {}", e);
format!("Failed to spawn process: {e}")
}
}
}
pub(crate) fn run_and_get_log(
&self,
gateway_key: &Option<String>,
probe_extra_args: &Vec<String>,
ticket_materials: AttachedTicketMaterials,
) -> String {
let mut command = std::process::Command::new(&self.path);
command.stdout(std::process::Stdio::piped());
if let Some(gateway_id) = gateway_key {
command.arg("--gateway").arg(gateway_id);
}
tracing::info!("Extra args for the probe:");
for arg in probe_extra_args {
let mut split = arg.splitn(2, '=');
let name = split.next().unwrap_or_default();
let value = split.next().unwrap_or_default();
tracing::info!("{} {}", name, value);
command.arg(format!("--{name}")).arg(value);
}
info!("attaching ticket materials to the probe");
let serialised = ticket_materials.to_serialised_string();
command.arg("--ticket-materials").arg(serialised);
command.arg("--ticket-materials-revision").arg(
<AttachedTicketMaterials as VersionedSerialise>::CURRENT_SERIALISATION_REVISION
.to_string(),
);
match command.spawn() {
Ok(child) => {
if let Ok(output) = child.wait_with_output() {
if !output.status.success() {
let out = String::from_utf8_lossy(&output.stdout);
let err = String::from_utf8_lossy(&output.stderr);
tracing::error!("Probe exited with {:?}:\n{}\n{}", output.status, out, err);
}
return String::from_utf8(output.stdout)
.unwrap_or("Unable to get log from test run".to_string());
}
"Unable to get log from test run".to_string()
}
Err(e) => {
error!("Failed to spawn test: {}", e);
"Failed to spawn test run task".to_string()
}
}
}
}