diff options
| author | tv <tv@krebsco.de> | 2026-10-25 13:39:44 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-25 13:39:44 +0100 |
| commit | 714debc94b0ef2b543949241f1eb04ae5738ad0c (patch) | |
| tree | 975232c77d5e7be54853555afafc4ed3ab1c8d11 /src/main.rs | |
| parent | f52ae6973299fa3c1d81758838951e39904e1d84 (diff) | |
add force module usable by API and CLI
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index 76e5ff0..88cbc6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use std::time::Duration; -use anyhow::{Context, Result}; +use anyhow::{Context, Result, bail}; use automerge::AutoCommit; use tokio::sync::{RwLock, broadcast, mpsc, watch}; use tracing::{debug, error, info, trace, warn}; @@ -19,6 +19,7 @@ mod backoff; mod config; mod document; mod files; +mod force; mod logging; mod remake; mod state; @@ -87,6 +88,8 @@ async fn main() -> Result<()> { "Using Mycelium REST API" ); + let force = force::Force::parse(args.force.iter().map(String::as_str), config::FORCE) + .map_err(anyhow::Error::msg)?; let files = Arc::new(files::Files::default()); let mut seeds: Vec<String> = args.seeds.clone(); let (state_file, remembered) = match &args.state_file { @@ -123,6 +126,22 @@ async fn main() -> Result<()> { Some(path) => Some(bootstrap::load_backup(path, &files)?), None => None, }; + if let (Some(backup), Some(remembered)) = (&recovered, &remembered) { + if backup.swarm_id != remembered.swarm_id { + if !force.allows("swarmId") { + bail!( + "The backup is of swarm {}, but the state file remembers swarm {}; add --force swarmId to recover the backup's swarm anyway", + backup.swarm_id, + remembered.swarm_id + ); + } + warn!( + backup = %backup.swarm_id, + remembered = %remembered.swarm_id, + "The backup is of another swarm than the remembered one; recovering the backup's (--force swarmId)" + ); + } + } let (initial_doc, recovered_epoch, recovered_swarm) = match recovered { Some(backup) => (backup.doc, Some(backup.epoch), Some(backup.swarm_id)), None => (AutoCommit::new(), None, None), @@ -193,16 +212,9 @@ async fn main() -> Result<()> { trace!("Application state initialized"); // Join the remembered swarm and no other; HELLOs claim it. A backup to recover from - // names its swarm itself, which wins. + // names its swarm itself (checked against the remembered one above). let start = match recovered_swarm { Some(swarm_id) => { - if let Some(remembered) = remembered.filter(|r| r.swarm_id != swarm_id) { - warn!( - backup = %swarm_id, - remembered = %remembered.swarm_id, - "The backup is of another swarm than the remembered one; recovering the backup's" - ); - } state.set_expected_swarm_id(swarm_id).await?; bootstrap::Start::Recovered } |
