136 lines
3.7 KiB
Rust
Raw Normal View History

use std::{
env,
path::{Path, PathBuf},
};
use serde::Serialize;
2026-01-26 08:26:15 +01:00
use testing_framework_core::topology::generation::{GeneratedNodeConfig, GeneratedTopology};
use testing_framework_env as tf_env;
2025-12-10 15:26:34 +01:00
use crate::docker::platform::{host_gateway_entry, resolve_image};
mod node;
pub use node::{EnvEntry, NodeDescriptor};
use testing_framework_config::constants::DEFAULT_CFGSYNC_PORT;
/// Top-level docker-compose descriptor built from a GeneratedTopology.
#[derive(Clone, Debug, Serialize)]
pub struct ComposeDescriptor {
2026-01-26 08:26:15 +01:00
nodes: Vec<NodeDescriptor>,
}
impl ComposeDescriptor {
/// Start building a descriptor from a generated topology.
#[must_use]
pub const fn builder(topology: &GeneratedTopology) -> ComposeDescriptorBuilder<'_> {
ComposeDescriptorBuilder::new(topology)
}
#[cfg(test)]
2026-01-26 08:26:15 +01:00
pub fn nodes(&self) -> &[NodeDescriptor] {
&self.nodes
}
}
/// Builder for `ComposeDescriptor` that plugs topology values into the
/// template.
pub struct ComposeDescriptorBuilder<'a> {
topology: &'a GeneratedTopology,
cfgsync_port: Option<u16>,
}
impl<'a> ComposeDescriptorBuilder<'a> {
const fn new(topology: &'a GeneratedTopology) -> Self {
Self {
topology,
cfgsync_port: None,
}
}
#[must_use]
/// Set cfgsync port for nodes.
pub const fn with_cfgsync_port(mut self, port: u16) -> Self {
self.cfgsync_port = Some(port);
self
}
/// Finish building the descriptor.
#[must_use]
pub fn build(self) -> ComposeDescriptor {
let cfgsync_port = self.cfgsync_port.unwrap_or(DEFAULT_CFGSYNC_PORT);
let (image, platform) = resolve_image();
2026-01-26 08:26:15 +01:00
let nodes = build_nodes(
self.topology.nodes(),
&image,
platform.as_deref(),
cfgsync_port,
);
2026-01-26 08:26:15 +01:00
ComposeDescriptor { nodes }
}
}
2026-01-26 16:36:51 +01:00
const NODE_ENTRYPOINT: &str = "/etc/nomos/scripts/run_nomos_node.sh";
2026-01-26 16:36:51 +01:00
pub(crate) fn node_instance_name(index: usize) -> String {
format!("node-{index}")
}
fn build_nodes(
nodes: &[GeneratedNodeConfig],
image: &str,
platform: Option<&str>,
cfgsync_port: u16,
) -> Vec<NodeDescriptor> {
nodes
.iter()
.enumerate()
2026-01-26 16:36:51 +01:00
.map(|(index, node)| NodeDescriptor::from_node(index, node, image, platform, cfgsync_port))
.collect()
}
2026-01-26 08:26:15 +01:00
fn base_volumes() -> Vec<String> {
let mut volumes = vec!["./stack:/etc/nomos".into()];
if let Some(host_log_dir) = repo_root()
.map(|root| root.join("tmp").join("node-logs"))
.map(|dir| dir.display().to_string())
{
volumes.push(format!("{host_log_dir}:/tmp/node-logs"));
}
volumes
}
fn repo_root() -> Option<PathBuf> {
if let Ok(root) = env::var("CARGO_WORKSPACE_DIR") {
return Some(PathBuf::from(root));
}
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(Path::parent)
.and_then(Path::parent)
.map(Path::to_path_buf)
}
fn default_extra_hosts() -> Vec<String> {
host_gateway_entry().into_iter().collect()
}
2026-01-26 08:26:15 +01:00
fn base_environment(cfgsync_port: u16) -> Vec<EnvEntry> {
let rust_log = tf_env::rust_log().unwrap_or_else(|| "info".to_string());
let nomos_log_level = tf_env::nomos_log_level().unwrap_or_else(|| "info".to_string());
chore: merge dev into master (#29) * Add node config overrides (#14) * chore: merge master into dev and update configs after merge (#17) * Sdp config structs from logos blockchain (#15) * Update configs after main repo merge --------- Co-authored-by: gusto <bacv@users.noreply.github.com> * Local deployer allows to stop and restart nodes (#16) * Unify local node control and restart support * Add local stop-node support * Use node names for restart/stop control * merge --------- Co-authored-by: hansieodendaal <hansie.odendaal@gmail.com> * Add orphan manual cluster test utilities * Update node rev and align consensus/wallet config * Update node rev and align wallet/KMS configs * Update main repo ref (#23) * Fix genesis utxos and scale leader stake * Document leader stake constants * feat: add custom persistent dir option for working files (#26) * chore: config and naming updates (#27) * Update config and crate naming - Updated configs to the lates main repo configs. - Updated all main repo crate namings to be same as the main repo. - Added `create_dir_all` to `pub(crate) fn create_tempdir(custom_work_dir: Option<PathBuf>) -> std::io::Result<TempDir> {`. - Wired in optional `persist_dir` when using the local deployer. - Update `time` vulnerability **Note:** Unsure about the `service_params` mapping in `pub(crate) fn cryptarchia_deployment(config: &GeneralConfig) -> CryptarchiaDeploymentSettings {` * fix ntp server config --------- Co-authored-by: Andrus Salumets <andrus@status.im> Co-authored-by: gusto <bacv@users.noreply.github.com> Co-authored-by: andrussal <salumets.andrus@gmail.com>
2026-02-09 14:12:26 +02:00
let time_backend = tf_env::lb_time_service_backend().unwrap_or_else(|| "monotonic".into());
vec![
EnvEntry::new("RUST_LOG", rust_log),
2026-01-26 16:36:51 +01:00
EnvEntry::new("LOGOS_BLOCKCHAIN_LOG_LEVEL", nomos_log_level),
EnvEntry::new("LOGOS_BLOCKCHAIN_TIME_BACKEND", time_backend),
EnvEntry::new(
"CFG_SERVER_ADDR",
format!("http://host.docker.internal:{cfgsync_port}"),
),
EnvEntry::new("OTEL_METRIC_EXPORT_INTERVAL", "5000"),
]
}