mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
75 lines
2.7 KiB
Rust
75 lines
2.7 KiB
Rust
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
#![cfg(feature = "e2e")]
|
|
|
|
//! E2E test: build a custom container image and run a sandbox with it.
|
|
//!
|
|
//! Prerequisites:
|
|
//! - A running Docker-backed openshell gateway (`mise run gateway:docker`)
|
|
//! - Docker daemon running (for image build)
|
|
//! - The `openshell` binary (built automatically from the workspace)
|
|
|
|
use std::io::Write;
|
|
|
|
use openshell_e2e::harness::output::strip_ansi;
|
|
use openshell_e2e::harness::sandbox::SandboxGuard;
|
|
|
|
const DOCKERFILE_CONTENT: &str = r#"FROM public.ecr.aws/docker/library/python:3.13-slim
|
|
|
|
# iproute2 is required for sandbox network namespace isolation.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends iproute2 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create the sandbox user/group so the supervisor can switch to it.
|
|
# Use a high UID range to avoid conflicts with host users when running without
|
|
# user namespace remapping (UID in container = UID on host).
|
|
RUN groupadd -g 1000660000 sandbox && \
|
|
useradd -m -u 1000660000 -g sandbox sandbox
|
|
|
|
# Write a marker file so we can verify this is our custom image.
|
|
# Place under /etc (Landlock baseline read-only path) so the sandbox
|
|
# can read it when filesystem restrictions are properly enforced.
|
|
RUN echo "custom-image-e2e-marker" > /etc/marker.txt
|
|
|
|
CMD ["sleep", "infinity"]
|
|
"#;
|
|
|
|
const MARKER: &str = "custom-image-e2e-marker";
|
|
|
|
/// Build a custom Docker image from a Dockerfile and verify that a sandbox
|
|
/// created from it contains the expected marker file.
|
|
#[tokio::test]
|
|
async fn sandbox_from_custom_dockerfile() {
|
|
// Step 1: Write a temporary Dockerfile.
|
|
let tmpdir = tempfile::tempdir().expect("create tmpdir");
|
|
let dockerfile_path = tmpdir.path().join("Dockerfile");
|
|
{
|
|
let mut f = std::fs::File::create(&dockerfile_path).expect("create Dockerfile");
|
|
f.write_all(DOCKERFILE_CONTENT.as_bytes())
|
|
.expect("write Dockerfile");
|
|
}
|
|
|
|
// Step 2: Create a sandbox from the Dockerfile.
|
|
let dockerfile_str = dockerfile_path.to_str().expect("Dockerfile path is UTF-8");
|
|
let mut guard = SandboxGuard::create(&[
|
|
"--from",
|
|
dockerfile_str,
|
|
"--",
|
|
"cat",
|
|
"/etc/marker.txt",
|
|
])
|
|
.await
|
|
.expect("sandbox create from Dockerfile");
|
|
|
|
// Step 3: Verify the marker file content appears in the output.
|
|
let clean_output = strip_ansi(&guard.create_output);
|
|
assert!(
|
|
clean_output.contains(MARKER),
|
|
"expected marker '{MARKER}' in sandbox output:\n{clean_output}"
|
|
);
|
|
|
|
// Explicit cleanup (also happens in Drop, but explicit is clearer in tests).
|
|
guard.cleanup().await;
|
|
}
|