diff --git a/src/loader/zone.rs b/src/loader/zone.rs index 02f878ac..0a61f64e 100644 --- a/src/loader/zone.rs +++ b/src/loader/zone.rs @@ -112,8 +112,9 @@ impl LoaderZoneHandle<'_> { /// Start a pending enqueued refresh. /// /// This should be called when the zone data storage is in the passive - /// state. If a load has been enqueued, it will be initiated (making the - /// data storage busy), and `true` will be returned. + /// state and the zone is not in maintenance mode. If a load has been + /// enqueued, it will be initiated (making the data storage busy), and + /// `true` will be returned. /// /// ## Panics /// diff --git a/src/signer/zone.rs b/src/signer/zone.rs index 203217b2..1f76a0d8 100644 --- a/src/signer/zone.rs +++ b/src/signer/zone.rs @@ -261,8 +261,9 @@ impl SignerZoneHandle<'_> { /// Start a pending enqueued re-sign. /// /// This should be called when the zone state machine is in the waiting - /// state. If a re-sign has been enqueued, it will be initiated (making the - /// data storage busy), and `true` will be returned. + /// state and the zone is not in maintenance mode. If a re-sign has been + /// enqueued, it will be initiated (making the data storage busy), and + /// `true` will be returned. /// /// This method cannot initiate enqueued new-signing operations (see /// [`Self::enqueue_new_sign()`]); when a new-signing operation is enqueued, diff --git a/src/zone/machine.rs b/src/zone/machine.rs index eba6a825..15bf690d 100644 --- a/src/zone/machine.rs +++ b/src/zone/machine.rs @@ -104,14 +104,10 @@ impl ZoneStateMachine { /// # Initiating operations impl<'a> ZoneHandle<'a> { pub(crate) fn try_start_load(&mut self) -> Option { - // If we're in maintenance mode, then we don't start this operation. - // TODO: distinguish between a manual load and an automatic one. - if self.state.maintenance_mode { - return None; - } - - let ZoneStateMachine::Waiting(_) = &self.state.machine else { - info!("Could not start load since an operation is in progress on the zone."); + if !self.state.ready_for_operation() { + info!( + "Could not start load since an operation is in progress on the zone or the zone is in maintenance mode." + ); return None; }; @@ -138,13 +134,7 @@ impl<'a> ZoneHandle<'a> { } pub(crate) fn try_start_resign(&mut self) -> Option { - // If we're in maintenance mode, then we don't start this operation. - // TODO: distinguish between a manual resign and an automatic one. - if self.state.maintenance_mode { - return None; - } - - let ZoneStateMachine::Waiting(_) = &self.state.machine else { + if !self.state.ready_for_operation() { info!("Could not start load since an operation is in progress on the zone."); return None; }; diff --git a/src/zone/mod.rs b/src/zone/mod.rs index 19714c73..b04c75a4 100644 --- a/src/zone/mod.rs +++ b/src/zone/mod.rs @@ -425,6 +425,14 @@ impl ZoneState { .find(|item| item.event.is_of_type(typ) && (serial.is_none() || item.serial == serial)) } + /// Whether the zone state is ready to start a new loading or signing operation + /// + /// This checks the maintenance mode and the zone state machine. + pub fn ready_for_operation(&self) -> bool { + // TODO: distinguish between a manual load/sign and an automatic one. + !self.maintenance_mode && matches!(&self.machine, ZoneStateMachine::Waiting(_)) + } + /// Get the most recent signed metadata for the zone. /// /// During restore the metadata for the currently published instance is diff --git a/src/zone/state/mod.rs b/src/zone/state/mod.rs index c04443c0..af96437a 100644 --- a/src/zone/state/mod.rs +++ b/src/zone/state/mod.rs @@ -85,6 +85,7 @@ impl Spec { match self { Self::V1(v1::Spec { policy, + maintenance_mode, instances, source, min_expiration, @@ -135,6 +136,7 @@ impl Spec { loader, history, persistence, + maintenance_mode, ..Default::default() }) } diff --git a/src/zone/state/v1.rs b/src/zone/state/v1.rs index eabadb11..ade88415 100644 --- a/src/zone/state/v1.rs +++ b/src/zone/state/v1.rs @@ -50,6 +50,12 @@ pub struct Spec { /// version of the policy that is not yet in use. pub policy: Option, + /// Whether the zone is in maintenance mode + /// + /// Maintenance mode means that Cascade won't start loading and signing + /// operations automatically. + pub maintenance_mode: bool, + /// Instances of the zone. pub instances: InstancesSpec, @@ -125,6 +131,7 @@ impl Spec { pub fn build(zone: &ZoneState) -> Self { Self { policy: zone.policy.as_ref().map(|p| PolicySpec::build(p)), + maintenance_mode: zone.maintenance_mode, instances: InstancesSpec::build(&zone.instances), source: ZoneLoadSourceSpec::build(&zone.loader.source), min_expiration: zone.min_expiration, diff --git a/src/zone/storage.rs b/src/zone/storage.rs index 90238421..8984d5bd 100644 --- a/src/zone/storage.rs +++ b/src/zone/storage.rs @@ -38,7 +38,7 @@ use crate::{ persistence::zone::IxfrZoneDiffs, server::{LoadedReviewServer, PublicationServer, SignedReviewServer}, util::BackgroundTasks, - zone::{Zone, ZoneHandle, ZoneState, machine::ZoneStateMachine}, + zone::{Zone, ZoneHandle, ZoneState}, }; //----------- StorageZoneHandle ------------------------------------------------ @@ -815,7 +815,7 @@ impl StorageZoneHandle<'_> { // loading a new instance. // Ensure a new operation can be started. - let ZoneStateMachine::Waiting(_) = &self.state.machine else { + if !self.state.ready_for_operation() { trace!("Ignoring `on_passive()` because the pipeline is busy"); return; };