summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-25 13:39:44 +0100
committertv <tv@krebsco.de>2026-10-25 13:39:44 +0100
commit714debc94b0ef2b543949241f1eb04ae5738ad0c (patch)
tree975232c77d5e7be54853555afafc4ed3ab1c8d11 /src/main.rs
parentf52ae6973299fa3c1d81758838951e39904e1d84 (diff)
add force module usable by API and CLI
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs30
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
}