Make Git router teardown process-bounded
This commit is contained in:
parent
31e9ab0f2d
commit
e60baad993
1 changed files with 191 additions and 35 deletions
|
|
@ -1,15 +1,17 @@
|
|||
use super::{
|
||||
Arc, AwaitingAttachedRunsc, BENCHMARK_GUEST, BTreeMap, BundleDigest, CommittedSandboxRuntime,
|
||||
ConfigurationLoadRequest, ContainerId, CoordinatorId, Domain, DomainStoreMutation,
|
||||
DurableDecision, Generation, GenerationId, HostCoordinatorDomainStore,
|
||||
HostProcessOwnershipSlot, Ipv4Addr, MatrixError, NETWORK_NAMESPACE_PATH, NetworkCoordinator,
|
||||
NetworkSidecarId, Path, PathBuf, ProcessOwnershipContext, ResolvedDomainConfiguration,
|
||||
RootProcess, RunscCommand, RuntimeNetworkLaunch, RuntimeSupervisorLaunch, SandboxBuildRequest,
|
||||
SandboxBundle, SandboxCoordinator, SandboxId, SocketAddr, SocketAddrExt, TcpListener, TempDir,
|
||||
UnixListener, UserNamespaceMap, build_sandbox_bundle, current_mount_identity,
|
||||
current_process_identity, default_sandbox_layout, derive_ipv4_policy, failure, fs, hex,
|
||||
host_path, load_trusted_configuration, lock_file, stage_benchmark_rootfs_and_control,
|
||||
stage_rootfs_and_control, try_exclusive_flock,
|
||||
DurableDecision, File, Generation, GenerationId, GitRoutingCoordinator,
|
||||
HostCoordinatorDomainStore, HostPath, HostProcessOwnershipSlot, Ipv4Addr, MatrixError,
|
||||
NETWORK_NAMESPACE_PATH, NetworkCoordinator, NetworkSidecarId, Path, PathBuf,
|
||||
ProcessOwnershipContext, ResolvedDomainConfiguration, RootProcess, RunscCommand,
|
||||
RuntimeGitRoutingAuthority, RuntimeGitRoutingLaunch, RuntimeNetworkLaunch,
|
||||
RuntimeSupervisorLaunch, SandboxBuildRequest, SandboxBundle, SandboxCoordinator, SandboxId,
|
||||
SocketAddr, SocketAddrExt, TargetCommand, TcpListener, TempDir, UnixListener, UserNamespaceMap,
|
||||
build_sandbox_bundle, build_sandbox_bundle_with_workspace, child_broker,
|
||||
current_mount_identity, current_process_identity, default_sandbox_layout, derive_ipv4_policy,
|
||||
failure, fs, hex, host_path, load_trusted_configuration, lock_file,
|
||||
stage_benchmark_rootfs_and_control, stage_rootfs_and_control, try_exclusive_flock,
|
||||
};
|
||||
|
||||
pub(super) struct Fixture {
|
||||
|
|
@ -19,17 +21,24 @@ pub(super) struct Fixture {
|
|||
pub(super) bundle: SandboxBundle,
|
||||
pub(super) activity: PathBuf,
|
||||
pub(super) benchmark_results: Option<PathBuf>,
|
||||
git_routing: Option<GitRoutingFixture>,
|
||||
}
|
||||
|
||||
impl Fixture {
|
||||
pub(super) fn new() -> Result<Self, MatrixError> {
|
||||
let tree = tempfile::tempdir()?;
|
||||
let root = tree.path().to_path_buf();
|
||||
Self::build(&root, Some(tree))
|
||||
Self::build(&root, Some(tree), false)
|
||||
}
|
||||
|
||||
pub(super) fn new_git_routed() -> Result<Self, MatrixError> {
|
||||
let tree = tempfile::tempdir()?;
|
||||
let root = tree.path().to_path_buf();
|
||||
Self::build(&root, Some(tree), true)
|
||||
}
|
||||
|
||||
pub(super) fn in_directory(root: &Path) -> Result<Self, MatrixError> {
|
||||
Self::build(root, None)
|
||||
Self::build(root, None, false)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
|
@ -136,16 +145,24 @@ impl Fixture {
|
|||
bundle,
|
||||
workspace.join("activity"),
|
||||
Some(results),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn build(root: &Path, tree: Option<TempDir>) -> Result<Self, MatrixError> {
|
||||
fn build(
|
||||
root: &Path,
|
||||
tree: Option<TempDir>,
|
||||
route_git_workspace: bool,
|
||||
) -> Result<Self, MatrixError> {
|
||||
let configuration_directory = root.join("configuration");
|
||||
let workspace = root.join("workspace");
|
||||
let runtime = root.join("runtime");
|
||||
fs::create_dir(&configuration_directory)?;
|
||||
fs::create_dir(&workspace)?;
|
||||
fs::create_dir(&runtime)?;
|
||||
let git_routing = route_git_workspace
|
||||
.then(|| GitRoutingFixture::create(root, &workspace))
|
||||
.transpose()?;
|
||||
let configuration_path = configuration_directory.join("lazaret.toml");
|
||||
fs::write(
|
||||
&configuration_path,
|
||||
|
|
@ -180,14 +197,20 @@ impl Fixture {
|
|||
.map_err(failure)?;
|
||||
let namespace =
|
||||
lazaret_linux::filesystem::namespace_identity(Path::new(NETWORK_NAMESPACE_PATH))?;
|
||||
let bundle = build_sandbox_bundle(SandboxBuildRequest {
|
||||
let request = SandboxBuildRequest {
|
||||
configuration: &configuration,
|
||||
container_id,
|
||||
expected_network_namespace: namespace,
|
||||
root_process,
|
||||
terminal: None,
|
||||
prepared_root: runtime_domain.join("prepared-root"),
|
||||
})
|
||||
};
|
||||
let bundle = match &git_routing {
|
||||
Some(git_routing) => {
|
||||
build_sandbox_bundle_with_workspace(request, git_routing.mountpoint.clone())
|
||||
}
|
||||
None => build_sandbox_bundle(request),
|
||||
}
|
||||
.map_err(failure)?;
|
||||
Self::finish_build(
|
||||
tree,
|
||||
|
|
@ -195,6 +218,7 @@ impl Fixture {
|
|||
bundle,
|
||||
workspace.join("activity"),
|
||||
None,
|
||||
git_routing,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -204,6 +228,7 @@ impl Fixture {
|
|||
bundle: SandboxBundle,
|
||||
activity: PathBuf,
|
||||
benchmark_results: Option<PathBuf>,
|
||||
git_routing: Option<GitRoutingFixture>,
|
||||
) -> Result<Self, MatrixError> {
|
||||
let runtime_domain = host_path(configuration.runtime_domain_root().canonical_label());
|
||||
let container_id = ContainerId::new([6; 32]);
|
||||
|
|
@ -252,6 +277,7 @@ impl Fixture {
|
|||
bundle,
|
||||
activity,
|
||||
benchmark_results,
|
||||
git_routing,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +289,7 @@ impl Fixture {
|
|||
&self,
|
||||
command: &RunscCommand,
|
||||
) -> Result<AwaitingAttachedRunsc, MatrixError> {
|
||||
let launch = RuntimeSupervisorLaunch::from_runsc_command(
|
||||
let mut launch = RuntimeSupervisorLaunch::from_runsc_command(
|
||||
ProcessOwnershipContext {
|
||||
domain_id: self.configuration.domain_id(),
|
||||
generation_id: GenerationId::new(7),
|
||||
|
|
@ -271,10 +297,40 @@ impl Fixture {
|
|||
slot: lazaret_core::records::HostProcessOwnershipSlot::SandboxRuntimeSupervisor,
|
||||
},
|
||||
command,
|
||||
)?
|
||||
.with_user_namespace_map(UserNamespaceMap::resolve_current().map_err(failure)?)?;
|
||||
AwaitingAttachedRunsc::launch(&SandboxCoordinator::new(&self.store), &launch)
|
||||
.map_err(failure)
|
||||
)?;
|
||||
if let Some(git_routing) = &self.git_routing {
|
||||
launch = launch.with_git_routing(git_routing.launch()?)?;
|
||||
}
|
||||
launch = launch
|
||||
.with_user_namespace_map(UserNamespaceMap::resolve_current().map_err(failure)?)?;
|
||||
let mut pending =
|
||||
AwaitingAttachedRunsc::launch(&SandboxCoordinator::new(&self.store), &launch)
|
||||
.map_err(failure)?;
|
||||
if let Some(git_routing) = &self.git_routing {
|
||||
let coordinator = GitRoutingCoordinator::new(&self.store);
|
||||
coordinator
|
||||
.begin_intent(
|
||||
GenerationId::new(7),
|
||||
HostPath::new(
|
||||
git_routing
|
||||
.mountpoint
|
||||
.as_os_str()
|
||||
.as_encoded_bytes()
|
||||
.to_vec(),
|
||||
),
|
||||
HostPath::new(
|
||||
git_routing
|
||||
.workspace
|
||||
.as_os_str()
|
||||
.as_encoded_bytes()
|
||||
.to_vec(),
|
||||
),
|
||||
HostPath::new(git_routing.isolated.as_os_str().as_encoded_bytes().to_vec()),
|
||||
)
|
||||
.map_err(failure)?;
|
||||
pending.start_git_routing(&coordinator).map_err(failure)?;
|
||||
}
|
||||
Ok(pending)
|
||||
}
|
||||
|
||||
pub(super) fn alternate_bundle(&self) -> Result<SandboxBundle, MatrixError> {
|
||||
|
|
@ -316,6 +372,68 @@ impl Fixture {
|
|||
}
|
||||
}
|
||||
|
||||
struct GitRoutingFixture {
|
||||
workspace: PathBuf,
|
||||
isolated: PathBuf,
|
||||
mountpoint: PathBuf,
|
||||
git_common: PathBuf,
|
||||
transient_hooks: PathBuf,
|
||||
transient_config: PathBuf,
|
||||
}
|
||||
|
||||
impl GitRoutingFixture {
|
||||
fn create(root: &Path, workspace: &Path) -> Result<Self, MatrixError> {
|
||||
child_broker()
|
||||
.run_transient(
|
||||
&TargetCommand::new("git")
|
||||
.argument("init")
|
||||
.argument("--quiet")
|
||||
.argument("--initial-branch=main")
|
||||
.argument(workspace),
|
||||
)
|
||||
.map_err(failure)?;
|
||||
let routing = root.join("git-routing");
|
||||
let isolated = routing.join("isolated");
|
||||
let mountpoint = routing.join("workspace");
|
||||
let transient_hooks = routing.join("hooks");
|
||||
let transient_config = routing.join("config");
|
||||
for directory in [&isolated, &mountpoint, &transient_hooks] {
|
||||
fs::create_dir_all(directory)?;
|
||||
}
|
||||
fs::write(&transient_config, b"")?;
|
||||
Ok(Self {
|
||||
workspace: workspace.to_path_buf(),
|
||||
isolated,
|
||||
mountpoint,
|
||||
git_common: workspace.join(".git"),
|
||||
transient_hooks,
|
||||
transient_config,
|
||||
})
|
||||
}
|
||||
|
||||
fn launch(&self) -> Result<RuntimeGitRoutingLaunch, MatrixError> {
|
||||
RuntimeGitRoutingLaunch::new(RuntimeGitRoutingAuthority {
|
||||
workspace: File::open(&self.workspace)?,
|
||||
workspace_label: self.workspace.clone(),
|
||||
isolated: File::open(&self.isolated)?,
|
||||
mountpoint: File::open(&self.mountpoint)?,
|
||||
mountpoint_label: self.mountpoint.clone(),
|
||||
git_common: File::open(&self.git_common)?,
|
||||
git_common_label: self.git_common.clone(),
|
||||
transient_hooks: File::open(&self.transient_hooks)?,
|
||||
transient_hooks_label: self.transient_hooks.clone(),
|
||||
transient_config: File::options()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&self.transient_config)?,
|
||||
transient_config_label: self.transient_config.clone(),
|
||||
global_excludes: None,
|
||||
isolate_ignored: true,
|
||||
})
|
||||
.map_err(failure)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct NetworkFixture {
|
||||
_tree: TempDir,
|
||||
_host_loopback: TcpListener,
|
||||
|
|
|
|||
Loading…
Reference in a new issue