Compose cold-start resources under Runtime Supervisor ownership

This commit is contained in:
ms2k 2026-07-16 17:29:23 +09:00
commit 33ac0ba4ee

View file

@ -4,8 +4,10 @@ use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::time::{Duration, Instant};
use crate::state_anchor::StateAnchorCoordinator;
use lazaret_core::identity::{
BundleDigest, ContainerId, GenerationId, HostPath, NamespaceIdentity, PidfsProcessIdentityV1,
BundleDigest, ContainerId, GenerationId, HostPath, MountIdentity, NamespaceIdentity,
PidfsProcessIdentityV1, PreparedArtifactId,
};
use lazaret_core::network::{CanonicalDerivedNetworkPolicy, ReachabilityExpectation};
use lazaret_core::records::{
@ -375,6 +377,88 @@ impl AwaitingAttachedRunsc {
self.supervisor.as_ref().map(RetainedProcess::identity)
}
/// Requests RS-owned State Anchor acquisition and commits exact staged and mount evidence.
///
/// # Errors
/// Refuses missing intent, event mismatch, changed ownership, or channel failure.
pub fn mount_state_anchor(
&mut self,
coordinator: &StateAnchorCoordinator<'_>,
prepared_artifact_id: PreparedArtifactId,
) -> Result<MountIdentity, SandboxCoordinatorError> {
let control = self
.control
.as_ref()
.ok_or(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor control channel is absent",
))?;
control.mount_state_anchor()?;
let staged = match control.receive()? {
SupervisorEvent::StateAnchorStaged(staged) => staged,
SupervisorEvent::Refused(detail) => {
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
}
_ => {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not stage the State Anchor daemon",
));
}
};
coordinator
.stage_daemon(staged)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
let acknowledgment = coordinator
.acknowledge_staged_daemon(staged)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
control.acknowledge_state_anchor(acknowledgment)?;
let (ready_staged, mount) = match control.receive()? {
SupervisorEvent::StateAnchorReady { staged, mount } => (staged, mount),
SupervisorEvent::Refused(detail) => {
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
}
_ => {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not report State Anchor readiness",
));
}
};
if ready_staged != staged {
return Err(SandboxCoordinatorError::InvalidState(
"State Anchor readiness changed daemon ownership",
));
}
let readiness =
lazaret_state_anchor::VerifiedStateAnchorReadiness::from_parts(ready_staged, mount);
coordinator
.commit_daemon_ready(readiness)
.and_then(|()| {
coordinator.commit_prepared(staged.generation_id(), prepared_artifact_id, mount)
})
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
Ok(mount)
}
/// Releases the RS-owned sidecar install path after exact State Anchor readiness.
///
/// # Errors
/// Refuses an unexpected RS response or channel failure.
pub fn start_sidecar(&mut self) -> Result<(), SandboxCoordinatorError> {
let control = self
.control
.as_ref()
.ok_or(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor control channel is absent",
))?;
control.start_sidecar()?;
if control.receive()? == SupervisorEvent::SidecarStarted {
Ok(())
} else {
Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not start the sidecar path",
))
}
}
/// Launches the RS through the HC broker and commits its staged ownership before execution.
///
/// # Errors
@ -827,6 +911,70 @@ impl CommittedSandboxRuntime {
}
}
/// Stops and durably cleans only the exact attached sandbox runtime.
///
/// # Errors
/// Refuses missing release intent, unexpected RS response, or exact cleanup failure.
pub fn stop_sandbox(
&mut self,
coordinator: &SandboxCoordinator<'_>,
) -> Result<(), SandboxCoordinatorError> {
coordinator.begin_release(self.generation_id)?;
self.control.stop_sandbox()?;
if self.control.receive()? != SupervisorEvent::SandboxStopped {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not stop the sandbox",
));
}
coordinator.complete_clean_after_absence(self.generation_id)
}
/// Stops only the RS-owned network resources after sandbox absence.
///
/// # Errors
/// Refuses an unexpected RS response or channel failure.
pub fn stop_sidecar(&mut self) -> Result<(), SandboxCoordinatorError> {
self.control.stop_sidecar()?;
if self.control.receive()? == SupervisorEvent::SidecarStopped {
self.network_evidence = None;
Ok(())
} else {
Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not stop the sidecar",
))
}
}
/// Requests exact RS-owned State Anchor unmount after dependent runtime resources stop.
///
/// # Errors
/// Refuses an unexpected RS response or channel failure.
pub fn unmount_state_anchor(&mut self) -> Result<(), SandboxCoordinatorError> {
self.control.unmount_state_anchor()?;
if self.control.receive()? == SupervisorEvent::StateAnchorUnmounted {
Ok(())
} else {
Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not unmount the State Anchor",
))
}
}
/// Gracefully exits and reaps the resource-empty exact Runtime Supervisor.
///
/// # Errors
/// Refuses an unexpected response or an RS that does not exit.
pub fn graceful_exit(mut self) -> Result<(), SandboxCoordinatorError> {
self.control.exit()?;
if self.control.receive()? != SupervisorEvent::Exited {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not acknowledge graceful exit",
));
}
self.lifetime.take();
wait_and_reap_supervisor(&mut self.supervisor)
}
/// Waits for an exact attached-runsc loss report and reaps the retained RS.
///
/// # Errors