diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 428050799..8ae95d031 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -496,10 +496,12 @@ pub enum Progress { Loading, LoadedReview, HaltLoaded, + PersistingLoaded, Signing, SigningFailed, SignedReview, HaltSigned, + PersistingSigned, } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/crates/cli/src/commands/zone.rs b/crates/cli/src/commands/zone.rs index ed17e6a90..42f136460 100644 --- a/crates/cli/src/commands/zone.rs +++ b/crates/cli/src/commands/zone.rs @@ -705,10 +705,12 @@ pub fn print_status(zone: &ZoneStatus, policy: &PolicyInfo) { Progress::Loading => "loading", Progress::LoadedReview => "waiting for loaded review", Progress::HaltLoaded => "halted after loaded review", + Progress::PersistingLoaded => "persisting loaded zone", Progress::Signing => "signing", Progress::SigningFailed => "signing failed", - Progress::SignedReview => "waiting for siged review", + Progress::SignedReview => "waiting for signed review", Progress::HaltSigned => "halted after signed review", + Progress::PersistingSigned => "persisting signed zone", }; println!("status: {}{progress}{}", ansi::BLUE, ansi::RESET); @@ -725,6 +727,7 @@ pub fn print_status(zone: &ZoneStatus, policy: &PolicyInfo) { current, &zone.unsigned_review_addr, ); + print_persist_loaded_phase(current); print_sign_phase( current, zone.unsigned_serial, @@ -738,6 +741,7 @@ pub fn print_status(zone: &ZoneStatus, policy: &PolicyInfo) { current, &zone.signed_review_addr, ); + print_persist_signed_phase(current); print_publish_phase(); } @@ -846,6 +850,17 @@ fn print_loaded_review_phase( } } +fn print_persist_loaded_phase(current: Progress) { + if current < Progress::PersistingLoaded { + println!(" {Pending} persist loaded zone"); + } else if current > Progress::PersistingLoaded { + println!(" {Done} persist loaded zone"); + } else { + println!(" {Ongoing} persist loaded zone"); + println!(" |"); + } +} + fn print_sign_phase( current: Progress, unsigned_serial: Option, @@ -933,6 +948,17 @@ fn print_signed_review_phase( } } +fn print_persist_signed_phase(current: Progress) { + if current < Progress::PersistingSigned { + println!(" {Pending} persist signed zone"); + } else if current > Progress::PersistingSigned { + println!(" {Done} persist signed zone"); + } else { + println!(" {Ongoing} persist signed zone"); + println!(" |"); + } +} + fn print_publish_phase() { println!(" {Pending} publish"); } diff --git a/src/metrics.rs b/src/metrics.rs index 8aee19b92..d10bec392 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -149,12 +149,14 @@ impl Metrics { ZoneStateMachine::LoadedReview(_) | ZoneStateMachine::HaltLoaded(_) + | ZoneStateMachine::PersistingLoaded(_) | ZoneStateMachine::Signing(_) => { zones_unsigned += 1; } ZoneStateMachine::SigningFailed(_) | ZoneStateMachine::SignedReview(_) + | ZoneStateMachine::PersistingSigned(_) | ZoneStateMachine::HaltSigned(_) => { zones_signed += 1; zones_unsigned += 1; diff --git a/src/units/http_server.rs b/src/units/http_server.rs index 0c95d4d91..b66d2c6a2 100644 --- a/src/units/http_server.rs +++ b/src/units/http_server.rs @@ -479,10 +479,12 @@ impl HttpServer { ZoneStateMachine::Loading(..) => Progress::Loading, ZoneStateMachine::LoadedReview(..) => Progress::LoadedReview, ZoneStateMachine::HaltLoaded(..) => Progress::HaltLoaded, + ZoneStateMachine::PersistingLoaded(..) => Progress::PersistingLoaded, ZoneStateMachine::Signing(..) => Progress::Signing, ZoneStateMachine::SigningFailed(..) => Progress::SigningFailed, ZoneStateMachine::SignedReview(..) => Progress::SignedReview, ZoneStateMachine::HaltSigned(..) => Progress::HaltSigned, + ZoneStateMachine::PersistingSigned(..) => Progress::PersistingSigned, ZoneStateMachine::Poisoned => unreachable!(), }; diff --git a/src/zone/machine.rs b/src/zone/machine.rs index eba6a8254..3442c6c4a 100644 --- a/src/zone/machine.rs +++ b/src/zone/machine.rs @@ -67,10 +67,12 @@ pub enum ZoneStateMachine { Loading(Loading), LoadedReview(LoadedReview), HaltLoaded(HaltLoaded), + PersistingLoaded(PersistingLoaded), Signing(Signing), SigningFailed(SigningFailed), SignedReview(SignedReview), HaltSigned(HaltSigned), + PersistingSigned(PersistingSigned), /// A value to leave the state in when we take it by value. /// @@ -236,7 +238,7 @@ impl<'a> ZoneHandle<'a> { let ZoneStateMachine::LoadedReview(loaded) = state else { panic!("cannot approve loaded in this state"); }; - transition.move_to(ZoneStateMachine::Signing(loaded.approve())); + transition.move_to(ZoneStateMachine::PersistingLoaded(loaded.approve())); // We move to the signing state and start persisting. The actual signing // will be triggered by the zone storage when persisting is done. @@ -289,6 +291,14 @@ impl<'a> ZoneHandle<'a> { impl<'a> ZoneHandle<'a> { /// Begin signing a new approved and persisted loaded instance. pub(crate) fn start_new_sign(&mut self, persisted: LoadedZonePersisted) { + let (transition, state) = self.state.machine.transition(); + + let ZoneStateMachine::PersistingLoaded(persisting) = state else { + panic!("cannot start signing in this state"); + }; + + transition.move_to(ZoneStateMachine::Signing(persisting.done())); + let builder = self.storage().start_new_sign(persisted); self.signer().enqueue_new_sign(builder); } @@ -366,7 +376,7 @@ impl<'a> ZoneHandle<'a> { let ZoneStateMachine::SignedReview(signed) = state else { panic!("The zone must be in signer review") }; - transition.move_to(ZoneStateMachine::Waiting(signed.approve())); + transition.move_to(ZoneStateMachine::PersistingSigned(signed.approve())); // Persist the signed instance while we are already in the Waiting state. // The state machine will only start a new operation when the zone storage @@ -429,6 +439,14 @@ impl<'a> ZoneHandle<'a> { impl<'a> ZoneHandle<'a> { /// Finish persisting an approved signed instance. pub(crate) fn finish_signed_persistence(&mut self, persisted: SignedZonePersisted) { + let (transition, state) = self.state.machine.transition(); + + let ZoneStateMachine::PersistingSigned(persisting) = state else { + panic!("cannot start publishing in this state"); + }; + + transition.move_to(ZoneStateMachine::Waiting(persisting.done())); + let viewer = self.storage().finish_signed_persistence(persisted); self.state.instances.switch(); @@ -521,7 +539,9 @@ impl<'a> ZoneHandle<'a> { return Err(()); }; - transition.move_to(ZoneStateMachine::Signing(halt.override_rejection())); + transition.move_to(ZoneStateMachine::PersistingLoaded( + halt.override_rejection(), + )); // We move to the signing state and start persisting. The actual signing // will be triggered by the zone storage when persisting is done. @@ -542,7 +562,9 @@ impl<'a> ZoneHandle<'a> { return Err(()); }; - transition.move_to(ZoneStateMachine::Waiting(halt_signed.override_rejection())); + transition.move_to(ZoneStateMachine::PersistingSigned( + halt_signed.override_rejection(), + )); // Persist the signed instance while we are already in the Waiting state. // The state machine will only start a new operation when the zone storage @@ -576,10 +598,12 @@ impl ZoneStateMachine { ZoneStateMachine::Loading(_) => "loading", ZoneStateMachine::LoadedReview(_) => "loaded review", ZoneStateMachine::HaltLoaded(_) => "halt loaded", + ZoneStateMachine::PersistingLoaded(_) => "persisting loaded", ZoneStateMachine::Signing(_) => "signing", ZoneStateMachine::SigningFailed(_) => "signing failed", ZoneStateMachine::SignedReview(_) => "signed review", ZoneStateMachine::HaltSigned(_) => "halt signed", + ZoneStateMachine::PersistingSigned(_) => "persisting signed", ZoneStateMachine::Poisoned => "poisoned", } } @@ -648,8 +672,8 @@ impl Loading { pub struct LoadedReview {} impl LoadedReview { - fn approve(self) -> Signing { - Signing {} + fn approve(self) -> PersistingLoaded { + PersistingLoaded {} } fn soft_reject(self) -> Waiting { @@ -665,8 +689,8 @@ impl LoadedReview { pub struct HaltLoaded {} impl HaltLoaded { - fn override_rejection(self) -> Signing { - Signing {} + fn override_rejection(self) -> PersistingLoaded { + PersistingLoaded {} } fn reset(self) -> Waiting { @@ -674,6 +698,15 @@ impl HaltLoaded { } } +#[derive(Debug)] +pub struct PersistingLoaded {} + +impl PersistingLoaded { + fn done(self) -> Signing { + Signing {} + } +} + #[derive(Debug)] pub struct Signing {} @@ -707,8 +740,8 @@ impl SigningFailed { pub struct SignedReview {} impl SignedReview { - fn approve(self) -> Waiting { - Waiting {} + fn approve(self) -> PersistingSigned { + PersistingSigned {} } fn hard_reject(self) -> HaltSigned { @@ -724,11 +757,20 @@ impl SignedReview { pub struct HaltSigned {} impl HaltSigned { - fn override_rejection(self) -> Waiting { - Waiting {} + fn override_rejection(self) -> PersistingSigned { + PersistingSigned {} } fn reset(self) -> Waiting { Waiting {} } } + +#[derive(Debug)] +pub struct PersistingSigned {} + +impl PersistingSigned { + fn done(self) -> Waiting { + Waiting {} + } +}