Enforce exact recovery ownership before cold start
This commit is contained in:
parent
f21a847991
commit
2bc5982a62
1 changed files with 1076 additions and 238 deletions
|
|
@ -7,7 +7,10 @@ use lazaret_core::configuration::ResolvedDomainConfiguration;
|
|||
use lazaret_core::identity::{BundleDigest, ContainerId, MountIdentity};
|
||||
use lazaret_core::network::{CanonicalDerivedNetworkPolicy, ReachabilityExpectation};
|
||||
use lazaret_core::records::Session;
|
||||
use lazaret_core::records::{Generation, GenerationIdentity, PreparedArtifact};
|
||||
use lazaret_core::records::{
|
||||
Generation, GenerationIdentity, Participant, ParticipantOwnership, ParticipantRole,
|
||||
ParticipantState, PreparedArtifact,
|
||||
};
|
||||
use lazaret_linux::process::current_process_identity;
|
||||
use lazaret_runtime_supervisor::network::NetworkProbeRequest;
|
||||
use lazaret_runtime_supervisor::sandbox::SandboxBundle;
|
||||
|
|
@ -20,7 +23,7 @@ use crate::control::{
|
|||
ControlError, NonInteractiveSessionExecutor, PublishedControlFace, SessionRegistry,
|
||||
StagedControlFace, TrustAnchor,
|
||||
};
|
||||
use crate::domain_store::HostCoordinatorDomainStore;
|
||||
use crate::domain_store::{DomainStoreMutation, HostCoordinatorDomainStore};
|
||||
use crate::lifecycle::{
|
||||
HostCoordinatorLifecycle, LifecycleAction, LifecycleAdapter, SessionAdmissionIdentity,
|
||||
SessionLifecycleAdapter,
|
||||
|
|
@ -240,6 +243,10 @@ impl<'a> ProductionLifecycleAdapter<'a> {
|
|||
self.plan.generation_identity.generation_id,
|
||||
self.plan.container_id,
|
||||
&self.plan.runtime_root,
|
||||
self.plan
|
||||
.runtime_staging
|
||||
.runsc_root_identity()
|
||||
.map_err(failure)?,
|
||||
self.plan.bundle_digest,
|
||||
current_process_identity().map_err(failure)?,
|
||||
)
|
||||
|
|
@ -347,36 +354,105 @@ impl<'a> ProductionLifecycleAdapter<'a> {
|
|||
.trust_anchor
|
||||
.take()
|
||||
.ok_or_else(|| ProductionLifecycleError("Trust Anchor is absent".into()))?;
|
||||
self.staged_control = Some(
|
||||
StagedControlFace::stage_with_executor(
|
||||
path_from_host(
|
||||
self.plan
|
||||
.configuration
|
||||
.runtime_domain_root()
|
||||
.canonical_label()
|
||||
.as_bytes(),
|
||||
),
|
||||
self.plan.invoking_uid,
|
||||
anchor,
|
||||
Arc::clone(&self.registry),
|
||||
Arc::clone(&self.plan.non_interactive_executor),
|
||||
)
|
||||
.map_err(failure)?,
|
||||
);
|
||||
let generation_id = self.plan.generation_identity.generation_id;
|
||||
self.plan
|
||||
.store
|
||||
.apply(&[DomainStoreMutation::PutParticipant(
|
||||
Participant::bare_intent(generation_id, ParticipantRole::Publication),
|
||||
)])
|
||||
.map_err(failure)?;
|
||||
let staged = StagedControlFace::stage_with_executor(
|
||||
path_from_host(
|
||||
self.plan
|
||||
.configuration
|
||||
.runtime_domain_root()
|
||||
.canonical_label()
|
||||
.as_bytes(),
|
||||
),
|
||||
self.plan.invoking_uid,
|
||||
anchor,
|
||||
Arc::clone(&self.registry),
|
||||
Arc::clone(&self.plan.non_interactive_executor),
|
||||
)
|
||||
.map_err(failure)?;
|
||||
let ownership = staged.recovery_ownership().map_err(failure)?;
|
||||
self.plan
|
||||
.store
|
||||
.apply(&[DomainStoreMutation::PutParticipant(
|
||||
Participant::snapshot(
|
||||
generation_id,
|
||||
ParticipantRole::Publication,
|
||||
ParticipantState::Intent,
|
||||
Some(ParticipantOwnership::Publication(ownership)),
|
||||
)
|
||||
.map_err(failure)?,
|
||||
)])
|
||||
.map_err(failure)?;
|
||||
self.staged_control = Some(staged);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn expose_publication(&mut self) -> Result<(), ProductionLifecycleError> {
|
||||
self.published_control = Some(Arc::new(
|
||||
self.staged_control
|
||||
.take()
|
||||
.ok_or_else(|| ProductionLifecycleError("staged control face is absent".into()))?
|
||||
.expose()
|
||||
let published = self
|
||||
.staged_control
|
||||
.take()
|
||||
.ok_or_else(|| ProductionLifecycleError("staged control face is absent".into()))?
|
||||
.expose()
|
||||
.map_err(failure)?;
|
||||
let ownership = published.recovery_ownership().map_err(failure)?;
|
||||
self.plan
|
||||
.store
|
||||
.apply(&[DomainStoreMutation::PutParticipant(
|
||||
Participant::snapshot(
|
||||
self.plan.generation_identity.generation_id,
|
||||
ParticipantRole::Publication,
|
||||
ParticipantState::Committed,
|
||||
Some(ParticipantOwnership::Publication(ownership)),
|
||||
)
|
||||
.map_err(failure)?,
|
||||
));
|
||||
)])
|
||||
.map_err(failure)?;
|
||||
self.published_control = Some(Arc::new(published));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clean_publication_after_withdrawal(&self) -> Result<(), ProductionLifecycleError> {
|
||||
let generation_id = self.plan.generation_identity.generation_id;
|
||||
let current = self
|
||||
.plan
|
||||
.store
|
||||
.snapshot()
|
||||
.map_err(failure)?
|
||||
.participants
|
||||
.into_iter()
|
||||
.find(|participant| {
|
||||
participant.generation_id() == generation_id
|
||||
&& participant.role() == ParticipantRole::Publication
|
||||
})
|
||||
.ok_or_else(|| ProductionLifecycleError("Publication participant is absent".into()))?;
|
||||
let release = Participant::snapshot(
|
||||
generation_id,
|
||||
ParticipantRole::Publication,
|
||||
ParticipantState::ReleaseIntent,
|
||||
current.ownership().cloned(),
|
||||
)
|
||||
.map_err(failure)?;
|
||||
let clean = Participant::snapshot(
|
||||
generation_id,
|
||||
ParticipantRole::Publication,
|
||||
ParticipantState::Clean,
|
||||
Some(ParticipantOwnership::empty(ParticipantRole::Publication)),
|
||||
)
|
||||
.map_err(failure)?;
|
||||
self.plan
|
||||
.store
|
||||
.apply(&[
|
||||
DomainStoreMutation::PutParticipant(release),
|
||||
DomainStoreMutation::CleanParticipantAfterAbsence(clean),
|
||||
])
|
||||
.map_err(failure)
|
||||
}
|
||||
|
||||
fn stop_sandbox(&mut self) -> Result<(), ProductionLifecycleError> {
|
||||
let store = Arc::clone(&self.plan.store);
|
||||
let sandbox = SandboxCoordinator::new(&store);
|
||||
|
|
@ -517,6 +593,7 @@ impl LifecycleAdapter for ProductionLifecycleAdapter<'_> {
|
|||
LifecycleAction::BeginTeardown => {
|
||||
if let Some(control) = self.published_control.as_ref() {
|
||||
control.withdraw().map_err(failure)?;
|
||||
self.clean_publication_after_withdrawal()?;
|
||||
}
|
||||
self.published_control.take();
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Reference in a new issue