mirror of
https://github.com/logos-blockchain/logos-blockchain-testing.git
synced 2026-02-24 07:03:09 +00:00
refactor cfgsync rendering to generic runtime config
This commit is contained in:
parent
114b84698d
commit
85a6f9d054
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2894,8 +2894,6 @@ dependencies = [
|
||||
"cfgsync-runtime",
|
||||
"kube",
|
||||
"logos-blockchain-http-api-common",
|
||||
"logos-blockchain-tracing",
|
||||
"logos-blockchain-tracing-service",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
port: 4400
|
||||
n_hosts: 4
|
||||
timeout: 10
|
||||
global_params_path: "/etc/logos/global_params"
|
||||
# Optional: serve prebuilt configs from a bundle file.
|
||||
# bundle_path: cfgsync.bundle.yaml
|
||||
|
||||
# ConsensusConfig related parameters
|
||||
security_param: 10
|
||||
active_slot_coeff: 0.9
|
||||
wallet:
|
||||
accounts: []
|
||||
|
||||
# DaConfig related parameters
|
||||
subnetwork_size: 2
|
||||
dispersal_factor: 2
|
||||
num_samples: 1
|
||||
num_subnets: 2
|
||||
old_blobs_check_interval: "5.0"
|
||||
blobs_validity_duration: "60.0"
|
||||
min_dispersal_peers: 1
|
||||
min_replication_peers: 1
|
||||
monitor_failure_time_window: "5.0"
|
||||
balancer_interval: "5.0"
|
||||
# Dispersal mempool publish strategy
|
||||
mempool_publish_strategy: !SampleSubnetworks
|
||||
sample_threshold: 2
|
||||
timeout: "2.0"
|
||||
cooldown: "0.0001"
|
||||
|
||||
replication_settings:
|
||||
seen_message_cache_size: 204800
|
||||
seen_message_ttl: "900.0"
|
||||
retry_shares_limit: 5
|
||||
retry_commitments_limit: 5
|
||||
|
||||
# Tracing
|
||||
tracing_settings:
|
||||
# Default to stdout so `docker logs` / `kubectl logs` shows node output.
|
||||
# Switch to `!File` if you want per-node log files inside the container/pod.
|
||||
logger: Stdout
|
||||
# Disable OTLP traces to remove DNS errors; metrics stay enabled below.
|
||||
tracing: None
|
||||
filter: !EnvFilter
|
||||
filters:
|
||||
nomos: debug
|
||||
cryptarchia: debug
|
||||
logos_blockchain_chain_leader_service: debug
|
||||
metrics: None
|
||||
console: None
|
||||
level: DEBUG
|
||||
@ -64,7 +64,7 @@ export CFG_FILE_PATH="/config.yaml" \
|
||||
CFG_HOST_KIND="${CFG_HOST_KIND:-$role}" \
|
||||
CFG_HOST_IDENTIFIER="${CFG_HOST_IDENTIFIER:-$host_identifier_default}" \
|
||||
LOGOS_BLOCKCHAIN_TIME_BACKEND="${LOGOS_BLOCKCHAIN_TIME_BACKEND:-monotonic}" \
|
||||
LOG_LEVEL="${LOG_LEVEL:-INFO}"``"
|
||||
LOG_LEVEL="${LOG_LEVEL:-INFO}"
|
||||
|
||||
# Ensure recovery directory exists to avoid early crashes in services that
|
||||
# persist state.
|
||||
|
||||
@ -17,8 +17,6 @@ testing-framework-runner-local = { workspace = true }
|
||||
|
||||
# Logos / Nomos deps
|
||||
lb_http_api_common = { workspace = true }
|
||||
lb_tracing = { workspace = true }
|
||||
lb_tracing_service = { workspace = true }
|
||||
|
||||
# External
|
||||
anyhow = "1"
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
mod template;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
pub(crate) use cfgsync_runtime::render::CfgsyncOutputPaths;
|
||||
use cfgsync_runtime::{
|
||||
bundle::build_cfgsync_bundle_with_hostnames,
|
||||
render::{RenderedCfgsync, apply_timeout_floor, ensure_bundle_path, write_rendered_cfgsync},
|
||||
render::{
|
||||
CfgsyncConfigOverrides, RenderedCfgsync, ensure_bundle_path,
|
||||
render_cfgsync_yaml_from_template, write_rendered_cfgsync,
|
||||
},
|
||||
};
|
||||
use lb_tracing::metrics::otlp::OtlpMetricsConfig;
|
||||
use lb_tracing_service::MetricsLayerSettings;
|
||||
use reqwest::Url;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use testing_framework_core::cfgsync::CfgsyncEnv;
|
||||
|
||||
pub(crate) struct CfgsyncRenderOptions {
|
||||
@ -21,16 +19,14 @@ pub(crate) struct CfgsyncRenderOptions {
|
||||
}
|
||||
|
||||
pub(crate) fn render_cfgsync_from_template<E: CfgsyncEnv>(
|
||||
template_path: &Path,
|
||||
topology: &E::Deployment,
|
||||
hostnames: &[String],
|
||||
options: CfgsyncRenderOptions,
|
||||
) -> Result<RenderedCfgsync> {
|
||||
let mut cfg = template::load_cfgsync_template(template_path)?;
|
||||
apply_render_options::<E>(&mut cfg, topology, options);
|
||||
|
||||
let cfg = build_cfgsync_server_config();
|
||||
let overrides = build_overrides::<E>(topology, options);
|
||||
let config_yaml = render_cfgsync_yaml_from_template(cfg, &overrides)?;
|
||||
let bundle = build_cfgsync_bundle_with_hostnames::<E>(topology, hostnames)?;
|
||||
let config_yaml = serde_yaml::to_string(&cfg)?;
|
||||
let bundle_yaml = serde_yaml::to_string(&bundle)?;
|
||||
|
||||
Ok(RenderedCfgsync {
|
||||
@ -39,8 +35,22 @@ pub(crate) fn render_cfgsync_from_template<E: CfgsyncEnv>(
|
||||
})
|
||||
}
|
||||
|
||||
fn build_cfgsync_server_config() -> Value {
|
||||
let mut root = Mapping::new();
|
||||
root.insert(
|
||||
Value::String("port".to_string()),
|
||||
Value::Number(4400_u64.into()),
|
||||
);
|
||||
|
||||
root.insert(
|
||||
Value::String("bundle_path".to_string()),
|
||||
Value::String("cfgsync.bundle.yaml".to_string()),
|
||||
);
|
||||
|
||||
Value::Mapping(root)
|
||||
}
|
||||
|
||||
pub(crate) fn render_and_write_cfgsync_from_template<E: CfgsyncEnv>(
|
||||
template_path: &Path,
|
||||
topology: &E::Deployment,
|
||||
hostnames: &[String],
|
||||
mut options: CfgsyncRenderOptions,
|
||||
@ -48,16 +58,16 @@ pub(crate) fn render_and_write_cfgsync_from_template<E: CfgsyncEnv>(
|
||||
) -> Result<RenderedCfgsync> {
|
||||
ensure_bundle_path(&mut options.bundle_path, output.bundle_path);
|
||||
|
||||
let rendered = render_cfgsync_from_template::<E>(template_path, topology, hostnames, options)?;
|
||||
let rendered = render_cfgsync_from_template::<E>(topology, hostnames, options)?;
|
||||
write_rendered_cfgsync(&rendered, output)?;
|
||||
|
||||
Ok(rendered)
|
||||
}
|
||||
|
||||
fn apply_render_options<E: CfgsyncEnv>(
|
||||
cfg: &mut template::CfgSyncConfig,
|
||||
fn build_overrides<E: CfgsyncEnv>(
|
||||
topology: &E::Deployment,
|
||||
options: CfgsyncRenderOptions,
|
||||
) {
|
||||
) -> CfgsyncConfigOverrides {
|
||||
let CfgsyncRenderOptions {
|
||||
port,
|
||||
bundle_path,
|
||||
@ -65,21 +75,11 @@ fn apply_render_options<E: CfgsyncEnv>(
|
||||
metrics_otlp_ingest_url,
|
||||
} = options;
|
||||
|
||||
if let Some(port) = port {
|
||||
cfg.port = port;
|
||||
}
|
||||
|
||||
cfg.n_hosts = E::nodes(topology).len();
|
||||
cfg.bundle_path = bundle_path;
|
||||
apply_metrics_endpoint(cfg, metrics_otlp_ingest_url);
|
||||
apply_timeout_floor(&mut cfg.timeout, min_timeout_secs);
|
||||
}
|
||||
|
||||
fn apply_metrics_endpoint(cfg: &mut template::CfgSyncConfig, endpoint: Option<Url>) {
|
||||
if let Some(endpoint) = endpoint {
|
||||
cfg.tracing_settings.metrics = MetricsLayerSettings::Otlp(OtlpMetricsConfig {
|
||||
endpoint,
|
||||
host_identifier: "node".into(),
|
||||
});
|
||||
CfgsyncConfigOverrides {
|
||||
port,
|
||||
n_hosts: Some(E::nodes(topology).len()),
|
||||
timeout_floor_secs: min_timeout_secs,
|
||||
bundle_path,
|
||||
metrics_otlp_ingest_url: metrics_otlp_ingest_url.map(|url| url.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
use std::{fs::File, path::Path};
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use lb_tracing_service::TracingSettings;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CfgSyncConfig {
|
||||
pub port: u16,
|
||||
#[serde(default)]
|
||||
pub n_hosts: usize,
|
||||
pub timeout: u64,
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub bundle_path: Option<String>,
|
||||
#[serde(default)]
|
||||
pub tracing_settings: TracingSettings,
|
||||
}
|
||||
|
||||
pub fn load_cfgsync_template(path: &Path) -> Result<CfgSyncConfig> {
|
||||
debug!(path = %path.display(), "loading cfgsync template");
|
||||
let file = File::open(path)
|
||||
.with_context(|| format!("opening cfgsync template at {}", path.display()))?;
|
||||
serde_yaml::from_reader(file).context("parsing cfgsync template")
|
||||
}
|
||||
@ -120,8 +120,8 @@ impl ComposeDeployEnv for LbcExtEnv {
|
||||
let bundle_path = cfgsync_bundle_path(path);
|
||||
let hostnames = topology_hostnames(topology);
|
||||
let options = cfgsync_render_options(port, metrics_otlp_ingest_url);
|
||||
|
||||
render_and_write_cfgsync_from_template::<lb_framework::LbcEnv>(
|
||||
path,
|
||||
topology,
|
||||
&hostnames,
|
||||
options,
|
||||
|
||||
@ -183,7 +183,7 @@ pub fn prepare_assets(
|
||||
let tempdir = create_assets_tempdir()?;
|
||||
|
||||
let (cfgsync_file, cfgsync_yaml, bundle_yaml) =
|
||||
render_and_write_cfgsync(&root, topology, metrics_otlp_ingest_url, &tempdir)?;
|
||||
render_and_write_cfgsync(topology, metrics_otlp_ingest_url, &tempdir)?;
|
||||
let scripts = validate_scripts(&root)?;
|
||||
let chart_path = helm_chart_path()?;
|
||||
let values_file = render_and_write_values(topology, &tempdir, &cfgsync_yaml, &bundle_yaml)?;
|
||||
@ -346,7 +346,6 @@ fn create_assets_tempdir() -> Result<TempDir, AssetsError> {
|
||||
}
|
||||
|
||||
fn render_and_write_cfgsync(
|
||||
root: &Path,
|
||||
topology: &DeploymentPlan,
|
||||
metrics_otlp_ingest_url: Option<&Url>,
|
||||
tempdir: &TempDir,
|
||||
@ -354,12 +353,12 @@ fn render_and_write_cfgsync(
|
||||
let cfgsync_file = tempdir.path().join("cfgsync.yaml");
|
||||
let bundle_file = tempdir.path().join("cfgsync.bundle.yaml");
|
||||
let (cfgsync_yaml, bundle_yaml) = render_cfgsync_config(
|
||||
root,
|
||||
topology,
|
||||
metrics_otlp_ingest_url,
|
||||
&cfgsync_file,
|
||||
&bundle_file,
|
||||
)?;
|
||||
|
||||
Ok((cfgsync_file, cfgsync_yaml, bundle_yaml))
|
||||
}
|
||||
|
||||
@ -378,17 +377,13 @@ fn testnet_image() -> String {
|
||||
}
|
||||
|
||||
fn render_cfgsync_config(
|
||||
root: &Path,
|
||||
topology: &DeploymentPlan,
|
||||
metrics_otlp_ingest_url: Option<&Url>,
|
||||
cfgsync_file: &Path,
|
||||
bundle_file: &Path,
|
||||
) -> Result<(String, String), AssetsError> {
|
||||
let cfgsync_template_path = cfgsync_template_path(root);
|
||||
debug!(path = %cfgsync_template_path.display(), "loading cfgsync template");
|
||||
let hostnames = k8s_node_hostnames(topology);
|
||||
let rendered = render_and_write_cfgsync_from_template::<lb_framework::LbcEnv>(
|
||||
&cfgsync_template_path,
|
||||
topology,
|
||||
&hostnames,
|
||||
CfgsyncRenderOptions {
|
||||
@ -407,10 +402,6 @@ fn render_cfgsync_config(
|
||||
Ok((rendered.config_yaml, rendered.bundle_yaml))
|
||||
}
|
||||
|
||||
fn cfgsync_template_path(root: &Path) -> PathBuf {
|
||||
stack_assets_root(root).join("cfgsync.yaml")
|
||||
}
|
||||
|
||||
fn k8s_node_hostnames(topology: &DeploymentPlan) -> Vec<String> {
|
||||
topology
|
||||
.nodes()
|
||||
@ -517,15 +508,6 @@ pub fn workspace_root() -> AnyhowResult<PathBuf> {
|
||||
))
|
||||
}
|
||||
|
||||
fn stack_assets_root(root: &Path) -> PathBuf {
|
||||
if let Some(override_dir) = assets_override_dir(root)
|
||||
&& override_dir.exists()
|
||||
{
|
||||
return override_dir;
|
||||
}
|
||||
root.join(DEFAULT_ASSETS_STACK_DIR)
|
||||
}
|
||||
|
||||
fn stack_scripts_root(root: &Path) -> PathBuf {
|
||||
if let Some(scripts) = override_scripts_dir(root)
|
||||
&& scripts.exists()
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context as _, Result};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RenderedCfgsync {
|
||||
@ -42,3 +43,100 @@ pub fn write_rendered_cfgsync(
|
||||
fs::write(output.bundle_path, &rendered.bundle_yaml)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct CfgsyncConfigOverrides {
|
||||
pub port: Option<u16>,
|
||||
pub n_hosts: Option<usize>,
|
||||
pub timeout_floor_secs: Option<u64>,
|
||||
pub bundle_path: Option<String>,
|
||||
pub metrics_otlp_ingest_url: Option<String>,
|
||||
}
|
||||
|
||||
pub fn load_cfgsync_template_yaml(path: &Path) -> Result<Value> {
|
||||
let file = fs::File::open(path)
|
||||
.with_context(|| format!("opening cfgsync template at {}", path.display()))?;
|
||||
serde_yaml::from_reader(file).context("parsing cfgsync template")
|
||||
}
|
||||
|
||||
pub fn render_cfgsync_yaml_from_template(
|
||||
mut template: Value,
|
||||
overrides: &CfgsyncConfigOverrides,
|
||||
) -> Result<String> {
|
||||
apply_cfgsync_overrides(&mut template, overrides)?;
|
||||
serde_yaml::to_string(&template).context("serializing rendered cfgsync config")
|
||||
}
|
||||
|
||||
pub fn apply_cfgsync_overrides(
|
||||
template: &mut Value,
|
||||
overrides: &CfgsyncConfigOverrides,
|
||||
) -> Result<()> {
|
||||
let root = mapping_mut(template)?;
|
||||
|
||||
if let Some(port) = overrides.port {
|
||||
root.insert(
|
||||
Value::String("port".to_string()),
|
||||
serde_yaml::to_value(port)?,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(n_hosts) = overrides.n_hosts {
|
||||
root.insert(
|
||||
Value::String("n_hosts".to_string()),
|
||||
serde_yaml::to_value(n_hosts)?,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(bundle_path) = &overrides.bundle_path {
|
||||
root.insert(
|
||||
Value::String("bundle_path".to_string()),
|
||||
Value::String(bundle_path.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(timeout_floor_secs) = overrides.timeout_floor_secs {
|
||||
let timeout_key = Value::String("timeout".to_string());
|
||||
let timeout_value = root
|
||||
.get(&timeout_key)
|
||||
.and_then(Value::as_u64)
|
||||
.unwrap_or(timeout_floor_secs)
|
||||
.max(timeout_floor_secs);
|
||||
root.insert(timeout_key, serde_yaml::to_value(timeout_value)?);
|
||||
}
|
||||
|
||||
if let Some(endpoint) = &overrides.metrics_otlp_ingest_url {
|
||||
let tracing_settings = nested_mapping_mut(root, "tracing_settings");
|
||||
tracing_settings.insert(
|
||||
Value::String("metrics".to_string()),
|
||||
parse_otlp_metrics_layer(endpoint)?,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mapping_mut(value: &mut Value) -> Result<&mut Mapping> {
|
||||
value
|
||||
.as_mapping_mut()
|
||||
.context("cfgsync template root must be a YAML map")
|
||||
}
|
||||
|
||||
fn nested_mapping_mut<'a>(mapping: &'a mut Mapping, key: &str) -> &'a mut Mapping {
|
||||
let key = Value::String(key.to_string());
|
||||
let entry = mapping
|
||||
.entry(key)
|
||||
.or_insert_with(|| Value::Mapping(Mapping::new()));
|
||||
|
||||
if !entry.is_mapping() {
|
||||
*entry = Value::Mapping(Mapping::new());
|
||||
}
|
||||
|
||||
entry
|
||||
.as_mapping_mut()
|
||||
.expect("mapping entry should always be a mapping")
|
||||
}
|
||||
|
||||
fn parse_otlp_metrics_layer(endpoint: &str) -> Result<Value> {
|
||||
let yaml = format!("!Otlp\nendpoint: \"{endpoint}\"\nhost_identifier: \"node\"\n");
|
||||
serde_yaml::from_str(&yaml).context("building metrics OTLP layer")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user