Browse Source

Merge jobdori/fix-ci-sandbox: probe unshare capability for CI fix

Jobdori 2 tháng trước cách đây
mục cha
commit
f1969cedd5
1 tập tin đã thay đổi với 22 bổ sung1 xóa
  1. 22 1
      rust/crates/runtime/src/sandbox.rs

+ 22 - 1
rust/crates/runtime/src/sandbox.rs

@@ -161,7 +161,7 @@ pub fn resolve_sandbox_status(config: &SandboxConfig, cwd: &Path) -> SandboxStat
 #[must_use]
 pub fn resolve_sandbox_status_for_request(request: &SandboxRequest, cwd: &Path) -> SandboxStatus {
     let container = detect_container_environment();
-    let namespace_supported = cfg!(target_os = "linux") && command_exists("unshare");
+    let namespace_supported = cfg!(target_os = "linux") && unshare_user_namespace_works();
     let network_supported = namespace_supported;
     let filesystem_active =
         request.enabled && request.filesystem_mode != FilesystemIsolationMode::Off;
@@ -282,6 +282,27 @@ fn command_exists(command: &str) -> bool {
         .is_some_and(|paths| env::split_paths(&paths).any(|path| path.join(command).exists()))
 }
 
+/// Check whether `unshare --user` actually works on this system.
+/// On some CI environments (e.g. GitHub Actions), the binary exists but
+/// user namespaces are restricted, causing silent failures.
+fn unshare_user_namespace_works() -> bool {
+    use std::sync::OnceLock;
+    static RESULT: OnceLock<bool> = OnceLock::new();
+    *RESULT.get_or_init(|| {
+        if !command_exists("unshare") {
+            return false;
+        }
+        std::process::Command::new("unshare")
+            .args(["--user", "--map-root-user", "true"])
+            .stdin(std::process::Stdio::null())
+            .stdout(std::process::Stdio::null())
+            .stderr(std::process::Stdio::null())
+            .status()
+            .map(|s| s.success())
+            .unwrap_or(false)
+    })
+}
+
 #[cfg(test)]
 mod tests {
     use super::{