Skip to content

Commit 46a3cee

Browse files
chore: commit in-progress work before Runtime V2 GA wave 1
Stage dirty working tree — health persistence, guest agent improvements, stack CLI/TUI refinements, e2e test additions, and .gitignore hardening. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 46e38d5 commit 46a3cee

11 files changed

Lines changed: 356 additions & 42 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ target/
22
*.swp
33
*.swo
44
.DS_Store
5+
*.db
6+
__pycache__/
7+
.artifacts/

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,21 @@ cargo clippy --workspace -- -D warnings
146146
cargo nextest run --workspace
147147
```
148148

149+
Runtime API adapter local smoke test:
150+
151+
```bash
152+
cd crates
153+
cargo run -p vz-api -- \
154+
--bind 127.0.0.1:8181 \
155+
--state-store-path /tmp/vz-api-state.db \
156+
--stack-baseline \
157+
--capability fs_quick_checkpoint
158+
159+
# in another shell
160+
curl -s http://127.0.0.1:8181/v1/capabilities
161+
curl -s http://127.0.0.1:8181/openapi.json
162+
```
163+
149164
Sandbox-specific real VM integration validation (macOS ARM64):
150165

151166
```bash

crates/vz-cli/src/commands/stack.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,12 @@ fn event_service_name(event: &StackEvent) -> Option<&str> {
18381838
| StackEvent::StackApplyCompleted { .. }
18391839
| StackEvent::StackApplyFailed { .. }
18401840
| StackEvent::VolumeCreated { .. }
1841-
| StackEvent::StackDestroyed { .. } => None,
1841+
| StackEvent::StackDestroyed { .. }
1842+
| StackEvent::SandboxCreating { .. }
1843+
| StackEvent::SandboxReady { .. }
1844+
| StackEvent::SandboxDraining { .. }
1845+
| StackEvent::SandboxTerminated { .. }
1846+
| StackEvent::SandboxFailed { .. } => None,
18421847
}
18431848
}
18441849

@@ -2434,6 +2439,21 @@ fn format_event_summary(event: &StackEvent) -> String {
24342439
"mount recreate: {service_name} ({:?} -> {desired_digest})",
24352440
previous_digest.as_deref().unwrap_or("<none>")
24362441
),
2442+
StackEvent::SandboxCreating { sandbox_id, .. } => {
2443+
format!("sandbox creating: {sandbox_id}")
2444+
}
2445+
StackEvent::SandboxReady { sandbox_id, .. } => {
2446+
format!("sandbox ready: {sandbox_id}")
2447+
}
2448+
StackEvent::SandboxDraining { sandbox_id, .. } => {
2449+
format!("sandbox draining: {sandbox_id}")
2450+
}
2451+
StackEvent::SandboxTerminated { sandbox_id, .. } => {
2452+
format!("sandbox terminated: {sandbox_id}")
2453+
}
2454+
StackEvent::SandboxFailed {
2455+
sandbox_id, error, ..
2456+
} => format!("sandbox failed: {sandbox_id}: {error}"),
24372457
}
24382458
}
24392459

crates/vz-cli/src/commands/stack_output.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,12 @@ impl StackOutput {
226226
}
227227
StackEvent::StackApplyStarted { .. }
228228
| StackEvent::StackApplyCompleted { .. }
229-
| StackEvent::StackDestroyed { .. } => {}
229+
| StackEvent::StackDestroyed { .. }
230+
| StackEvent::SandboxCreating { .. }
231+
| StackEvent::SandboxReady { .. }
232+
| StackEvent::SandboxDraining { .. }
233+
| StackEvent::SandboxTerminated { .. }
234+
| StackEvent::SandboxFailed { .. } => {}
230235
}
231236
self.update_header();
232237
}

crates/vz-cli/src/tui.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ fn event_color(event: &StackEvent) -> Color {
359359
StackEvent::HealthCheckFailed { .. } => Color::Yellow,
360360
StackEvent::DependencyBlocked { .. } => Color::Magenta,
361361
StackEvent::MountTopologyRecreateRequired { .. } => Color::Yellow,
362+
StackEvent::SandboxCreating { .. } => Color::Cyan,
363+
StackEvent::SandboxReady { .. } => Color::Green,
364+
StackEvent::SandboxDraining { .. } => Color::Yellow,
365+
StackEvent::SandboxTerminated { .. } => Color::DarkGray,
366+
StackEvent::SandboxFailed { .. } => Color::Red,
362367
}
363368
}
364369

@@ -428,6 +433,21 @@ fn format_event_summary(event: &StackEvent) -> String {
428433
"MountRecreate {service_name} ({:?} -> {desired_digest})",
429434
previous_digest.as_deref().unwrap_or("<none>")
430435
),
436+
StackEvent::SandboxCreating { sandbox_id, .. } => {
437+
format!("SandboxCreating {sandbox_id}")
438+
}
439+
StackEvent::SandboxReady { sandbox_id, .. } => {
440+
format!("SandboxReady {sandbox_id}")
441+
}
442+
StackEvent::SandboxDraining { sandbox_id, .. } => {
443+
format!("SandboxDraining {sandbox_id}")
444+
}
445+
StackEvent::SandboxTerminated { sandbox_id, .. } => {
446+
format!("SandboxTerminated {sandbox_id}")
447+
}
448+
StackEvent::SandboxFailed {
449+
sandbox_id, error, ..
450+
} => format!("SandboxFailed {sandbox_id}: {error}"),
431451
}
432452
}
433453

crates/vz-guest-agent/src/grpc_server.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -662,38 +662,37 @@ impl oci_service_server::OciService for OciServiceImpl {
662662
.ok_or_else(|| Status::internal("youki state missing pid field"))?;
663663

664664
let mut nsenter_args: Vec<String> = vec![
665-
"nsenter".into(),
666-
"--mount".into(),
667-
"--net".into(),
665+
format!("--mount=/proc/{pid}/ns/mnt"),
666+
format!("--net=/proc/{pid}/ns/net"),
667+
format!("--pid=/proc/{pid}/ns/pid"),
668+
format!("--ipc=/proc/{pid}/ns/ipc"),
669+
format!("--uts=/proc/{pid}/ns/uts"),
668670
format!("--root=/proc/{pid}/root"),
669-
format!("--target={pid}"),
670-
"--".into(),
671-
"env".into(),
672671
];
673-
674-
// Always set a standard PATH so commands like pg_isready are found.
675-
let has_path = req.env.keys().any(|k| k == "PATH");
676-
if !has_path {
677-
nsenter_args
678-
.push("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin".into());
679-
}
680-
681-
for (key, value) in &req.env {
682-
nsenter_args.push(format!("{key}={value}"));
672+
if !req.working_dir.is_empty() {
673+
nsenter_args.push(format!("--wd={}", req.working_dir));
683674
}
675+
nsenter_args.push("--".into());
684676

685-
nsenter_args.push(req.command);
686-
nsenter_args.extend(req.args);
677+
nsenter_args.push(req.command.clone());
678+
nsenter_args.extend(req.args.clone());
687679

688680
info!(pid = pid, args = ?nsenter_args, "oci: exec via nsenter");
689681

690-
let mut cmd = tokio::process::Command::new(&nsenter_args[0]);
691-
for arg in &nsenter_args[1..] {
682+
let mut cmd = tokio::process::Command::new("nsenter");
683+
for arg in nsenter_args {
692684
cmd.arg(arg);
693685
}
694-
if !req.working_dir.is_empty() {
695-
cmd.current_dir(&req.working_dir);
686+
687+
cmd.env_clear();
688+
let has_path = req.env.keys().any(|k| k == "PATH");
689+
if !has_path {
690+
cmd.env(
691+
"PATH",
692+
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
693+
);
696694
}
695+
cmd.envs(&req.env);
697696
cmd.kill_on_drop(true);
698697

699698
let output = match tokio::time::timeout(YOUKI_EXEC_TIMEOUT, cmd.output()).await {

crates/vz-guest-agent/src/listener.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use std::sync::Arc;
1414
use std::task::{Context, Poll};
1515

1616
use tokio::io::{AsyncRead, AsyncWrite};
17-
use tracing::warn;
1817
use tonic::transport::server::Connected;
18+
use tracing::warn;
1919

2020
/// AF_VSOCK listener that accepts connections from the host.
2121
pub struct VsockListener {
@@ -171,8 +171,8 @@ impl VsockListener {
171171
loop {
172172
// Use tokio's blocking task pool for the accept() syscall since
173173
// we can't easily register a vsock fd with epoll/kqueue through tokio.
174-
let (conn_fd, source_cid) = tokio::task::spawn_blocking(
175-
move || -> io::Result<(RawFd, u32)> {
174+
let (conn_fd, source_cid) =
175+
tokio::task::spawn_blocking(move || -> io::Result<(RawFd, u32)> {
176176
let mut addr: SockaddrVm = unsafe { std::mem::zeroed() };
177177
let mut addr_len = std::mem::size_of::<SockaddrVm>() as libc::socklen_t;
178178

@@ -189,10 +189,9 @@ impl VsockListener {
189189
}
190190

191191
Ok((fd, source_cid_from_addr(&addr)))
192-
},
193-
)
194-
.await
195-
.map_err(io::Error::other)??;
192+
})
193+
.await
194+
.map_err(io::Error::other)??;
196195

197196
if !is_host_peer(source_cid) {
198197
// SAFETY: close accepted fd on explicit rejection.

0 commit comments

Comments
 (0)