20260401 live recorder 扩展到1+N个delta,完成5个RIR录制,以及三方replay,结果三方均对齐vrps和vaps
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use rpki::bundle::{
|
||||
BundleManifest, BundleManifestEntry, RecordingHttpFetcher,
|
||||
RecordingRsyncFetcher, build_vap_compare_rows, build_vrp_compare_rows,
|
||||
write_live_delta_replay_bundle_inputs, write_vap_csv, write_vrp_csv,
|
||||
RecordingHttpFetcher, RecordingRsyncFetcher, build_single_rir_bundle_manifest,
|
||||
build_vap_compare_rows, build_vrp_compare_rows, copy_dir_all, load_validation_time,
|
||||
sha256_hex, write_json, write_live_delta_replay_bundle_inputs, write_vap_csv, write_vrp_csv,
|
||||
};
|
||||
use rpki::ccr::{build_ccr_from_run, decode_content_info, verify_content_info, write_ccr_file};
|
||||
use rpki::fetch::http::{BlockingHttpFetcher, HttpFetcherConfig};
|
||||
@@ -15,7 +15,6 @@ use rpki::validation::run_tree_from_tal::{
|
||||
run_tree_from_tal_and_ta_der_serial_audit,
|
||||
};
|
||||
use rpki::validation::tree::TreeRunConfig;
|
||||
use sha2::Digest;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Instant;
|
||||
@@ -130,56 +129,6 @@ fn parse_args(argv: &[String]) -> Result<Args, String> {
|
||||
Ok(args)
|
||||
}
|
||||
|
||||
fn sha256_hex(bytes: &[u8]) -> String {
|
||||
hex::encode(sha2::Sha256::digest(bytes))
|
||||
}
|
||||
|
||||
fn write_json(path: &Path, value: &impl serde::Serialize) -> Result<(), String> {
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.map_err(|e| format!("create parent failed: {}: {e}", parent.display()))?;
|
||||
}
|
||||
let bytes = serde_json::to_vec_pretty(value).map_err(|e| e.to_string())?;
|
||||
fs::write(path, bytes).map_err(|e| format!("write json failed: {}: {e}", path.display()))
|
||||
}
|
||||
|
||||
fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), String> {
|
||||
fs::create_dir_all(dst)
|
||||
.map_err(|e| format!("create directory failed: {}: {e}", dst.display()))?;
|
||||
for entry in fs::read_dir(src).map_err(|e| format!("read_dir failed: {}: {e}", src.display()))? {
|
||||
let entry = entry.map_err(|e| format!("read_dir entry failed: {}: {e}", src.display()))?;
|
||||
let ty = entry
|
||||
.file_type()
|
||||
.map_err(|e| format!("file_type failed: {}: {e}", entry.path().display()))?;
|
||||
let to = dst.join(entry.file_name());
|
||||
if ty.is_dir() {
|
||||
copy_dir_all(&entry.path(), &to)?;
|
||||
} else if ty.is_file() {
|
||||
if let Some(parent) = to.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.map_err(|e| format!("create parent failed: {}: {e}", parent.display()))?;
|
||||
}
|
||||
fs::copy(entry.path(), &to)
|
||||
.map_err(|e| format!("copy failed: {} -> {}: {e}", entry.path().display(), to.display()))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_validation_time(path: &Path) -> Result<time::OffsetDateTime, String> {
|
||||
let json: serde_json::Value = serde_json::from_slice(
|
||||
&fs::read(path).map_err(|e| format!("read json failed: {}: {e}", path.display()))?,
|
||||
)
|
||||
.map_err(|e| format!("parse json failed: {}: {e}", path.display()))?;
|
||||
let value = json
|
||||
.get("validationTime")
|
||||
.or_else(|| json.get("validation_time"))
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| format!("validationTime missing in {}", path.display()))?;
|
||||
time::OffsetDateTime::parse(value, &Rfc3339)
|
||||
.map_err(|e| format!("invalid validationTime in {}: {e}", path.display()))
|
||||
}
|
||||
|
||||
fn ensure_recorded_target_snapshots(
|
||||
store: &RocksStore,
|
||||
base_bundle_dir: &Path,
|
||||
@@ -466,27 +415,14 @@ fn run(args: Args) -> Result<PathBuf, String> {
|
||||
});
|
||||
write_json(&rir_dir.join("verification.json"), &verification_json)?;
|
||||
|
||||
let bundle_manifest = BundleManifest {
|
||||
schema_version: "20260330-v1".to_string(),
|
||||
bundle_producer: "ours".to_string(),
|
||||
recorded_at_rfc3339_utc: time::OffsetDateTime::now_utc()
|
||||
.format(&Rfc3339)
|
||||
.map_err(|e| format!("format recorded_at failed: {e}"))?,
|
||||
rirs: vec![rir_normalized.clone()],
|
||||
per_rir_bundles: vec![BundleManifestEntry {
|
||||
rir: rir_normalized.clone(),
|
||||
relative_path: rir_normalized,
|
||||
base_validation_time: base_validation_time
|
||||
.format(&Rfc3339)
|
||||
.map_err(|e| format!("format base validation time failed: {e}"))?,
|
||||
delta_validation_time: Some(
|
||||
target_validation_time
|
||||
.format(&Rfc3339)
|
||||
.map_err(|e| format!("format delta validation time failed: {e}"))?,
|
||||
),
|
||||
has_aspa: bundle_json["hasAspa"].as_bool().unwrap_or(false),
|
||||
}],
|
||||
};
|
||||
let bundle_manifest = build_single_rir_bundle_manifest(
|
||||
"20260330-v1",
|
||||
"ours",
|
||||
&rir_normalized,
|
||||
&base_validation_time,
|
||||
Some(&target_validation_time),
|
||||
bundle_json["hasAspa"].as_bool().unwrap_or(false),
|
||||
)?;
|
||||
write_json(&out_root.join("bundle-manifest.json"), &bundle_manifest)?;
|
||||
|
||||
let _ = fs::remove_dir_all(&target_store_dir);
|
||||
|
||||
Reference in New Issue
Block a user