Integrate routed Git workspaces with persistent state

This commit is contained in:
ms2k 2026-07-18 02:08:14 +09:00
commit 917409fcc6

View file

@ -26,6 +26,7 @@ use rustix::pipe::{PipeFlags, pipe_with};
use rustix::process::Signal;
use crate::domain_store::{DomainStoreError, DomainStoreMutation, HostCoordinatorDomainStore};
use crate::git_routing::GitRoutingCoordinator;
use crate::network::{NetworkCoordinator, NetworkCoordinatorError};
const SUPERVISOR_EXIT_TIMEOUT: Duration = Duration::from_secs(5);
@ -377,6 +378,8 @@ pub struct AwaitingAttachedRunsc {
lifetime: Option<std::os::fd::OwnedFd>,
staged: Option<StagedProcessOwnership>,
helper_staged: Option<StagedProcessOwnership>,
git_routing_required: bool,
git_routing_mount: Option<MountIdentity>,
network_evidence: Option<NetworkReadinessEvidence>,
runsc_command: lazaret_runtime_supervisor::sandbox::RunscCommand,
}
@ -453,6 +456,67 @@ impl AwaitingAttachedRunsc {
Ok(mount)
}
/// Requests generation-local routing and commits exact staged and mount evidence.
///
/// # Errors
/// Refuses missing intent, event mismatch, changed ownership, or channel failure.
pub fn start_git_routing(
&mut self,
coordinator: &GitRoutingCoordinator<'_>,
) -> Result<MountIdentity, SandboxCoordinatorError> {
if !self.git_routing_required || self.git_routing_mount.is_some() {
return Err(SandboxCoordinatorError::InvalidState(
"Git routing is not awaiting start",
));
}
let control = self
.control
.as_ref()
.ok_or(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor control channel is absent",
))?;
control.start_git_routing()?;
let staged = match control.receive()? {
SupervisorEvent::GitRoutingStaged(staged) => staged,
SupervisorEvent::Refused(detail) => {
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
}
_ => {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not stage the Git router",
));
}
};
coordinator
.stage_daemon(staged)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
let acknowledgment = coordinator
.acknowledge_daemon(staged)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
control.acknowledge_git_routing(acknowledgment)?;
let (ready_staged, mount) = match control.receive()? {
SupervisorEvent::GitRoutingReady { staged, mount } => (staged, mount),
SupervisorEvent::Refused(detail) => {
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
}
_ => {
return Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not report Git-routing readiness",
));
}
};
if ready_staged != staged {
return Err(SandboxCoordinatorError::InvalidState(
"Git-routing readiness changed daemon ownership",
));
}
coordinator
.commit_ready(staged, mount)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
self.git_routing_mount = Some(mount);
Ok(mount)
}
/// Releases the RS-owned sidecar install path after exact State Anchor readiness.
///
/// # Errors
@ -550,6 +614,8 @@ impl AwaitingAttachedRunsc {
lifetime: Some(coordinator_lifetime),
staged: None,
helper_staged: None,
git_routing_required: launch.has_git_routing(),
git_routing_mount: None,
network_evidence: None,
runsc_command: launch.runsc_command().clone(),
})
@ -693,6 +759,11 @@ impl AwaitingAttachedRunsc {
"attached runsc cannot start before network attestation",
));
}
if self.git_routing_required && self.git_routing_mount.is_none() {
return Err(SandboxCoordinatorError::InvalidState(
"attached runsc cannot start before Git-routing readiness",
));
}
let event = self
.control
.as_ref()
@ -944,6 +1015,31 @@ impl CommittedSandboxRuntime {
coordinator.complete_clean_after_absence(self.generation_id)
}
/// Stops exact generation-local Git routing after sandbox absence.
///
/// # Errors
/// Refuses missing release intent, changed mount evidence, or an unexpected RS response.
pub fn stop_git_routing(
&mut self,
coordinator: &GitRoutingCoordinator<'_>,
) -> Result<(), SandboxCoordinatorError> {
let expected = coordinator
.begin_release(self.generation_id)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error)))?;
self.control.stop_git_routing()?;
match self.control.receive()? {
SupervisorEvent::GitRoutingStopped { mount } if mount == expected => coordinator
.complete_clean(self.generation_id, mount)
.map_err(|error| SandboxCoordinatorError::Io(io::Error::other(error))),
SupervisorEvent::Refused(detail) => {
Err(SandboxCoordinatorError::Io(io::Error::other(detail)))
}
_ => Err(SandboxCoordinatorError::InvalidState(
"Runtime Supervisor did not stop exact Git routing",
)),
}
}
/// Stops only the RS-owned network resources after sandbox absence.
///
/// # Errors