决定最终的沙箱状态 — 源码 sandbox.rs:162-208 这是整个沙箱系统的核心决策函数。它综合考虑: - 请求的隔离级别 - 系统是否支持(Linux + unshare) - 是否在容器中 - 降级原因 关键设计: 即使命名空间不可用,文件系统隔离仍然可以工作。 这就是"优雅降级"——不是全有或全无。
(request: SandboxRequest, cwd: Path)
| 219 | |
| 220 | |
| 221 | def resolve_sandbox_status(request: SandboxRequest, cwd: Path) -> SandboxStatus: |
| 222 | """决定最终的沙箱状态 — 源码 sandbox.rs:162-208 |
| 223 | |
| 224 | 这是整个沙箱系统的核心决策函数。它综合考虑: |
| 225 | - 请求的隔离级别 |
| 226 | - 系统是否支持(Linux + unshare) |
| 227 | - 是否在容器中 |
| 228 | - 降级原因 |
| 229 | |
| 230 | 关键设计: 即使命名空间不可用,文件系统隔离仍然可以工作。 |
| 231 | 这就是"优雅降级"——不是全有或全无。 |
| 232 | """ |
| 233 | container = detect_container_environment() |
| 234 | |
| 235 | # Linux 上是否有 unshare 命令 |
| 236 | is_linux = sys.platform.startswith("linux") |
| 237 | namespace_supported = is_linux and command_exists("unshare") |
| 238 | network_supported = namespace_supported # 网络隔离也依赖 unshare |
| 239 | |
| 240 | # 文件系统隔离不依赖 unshare,任何平台都可以用 |
| 241 | filesystem_active = ( |
| 242 | request.enabled and |
| 243 | request.filesystem_mode != FilesystemIsolationMode.OFF |
| 244 | ) |
| 245 | |
| 246 | # 收集降级原因 |
| 247 | fallback_reasons = [] |
| 248 | if request.enabled and request.namespace_restrictions and not namespace_supported: |
| 249 | fallback_reasons.append( |
| 250 | "namespace isolation unavailable (requires Linux with `unshare`)" |
| 251 | ) |
| 252 | if request.enabled and request.network_isolation and not network_supported: |
| 253 | fallback_reasons.append( |
| 254 | "network isolation unavailable (requires Linux with `unshare`)" |
| 255 | ) |
| 256 | if (request.enabled |
| 257 | and request.filesystem_mode == FilesystemIsolationMode.ALLOW_LIST |
| 258 | and not request.allowed_mounts): |
| 259 | fallback_reasons.append( |
| 260 | "filesystem allow-list requested without configured mounts" |
| 261 | ) |
| 262 | |
| 263 | # 最终判断: 沙箱是否真正生效 |
| 264 | active = ( |
| 265 | request.enabled |
| 266 | and (not request.namespace_restrictions or namespace_supported) |
| 267 | and (not request.network_isolation or network_supported) |
| 268 | ) |
| 269 | |
| 270 | return SandboxStatus( |
| 271 | enabled=request.enabled, |
| 272 | requested=request, |
| 273 | supported=namespace_supported, |
| 274 | active=active, |
| 275 | namespace_supported=namespace_supported, |
| 276 | namespace_active=request.enabled and request.namespace_restrictions and namespace_supported, |
| 277 | network_supported=network_supported, |
| 278 | network_active=request.enabled and request.network_isolation and network_supported, |
no test coverage detected