[PR #300] [MERGED] fix(cli): tolerate BuildKit tunnel closure during publication #330

Closed
opened 2026-10-29 14:22:16 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/kvcache-ai/AgentENV/pull/300
Author: @yingdi-shan
Created: 9/16/2026
Status: ✅ Merged
Merged: 9/17/2026
Merged by: @yingdi-shan

Base: main ← Head: fix/cli-buildkit-publication-disconnect


📝 Commits (1)

  • c7f5b3f fix(cli): tolerate BuildKit tunnel closure during publication

📊 Changes

1 file changed (+47 additions, -2 deletions)

View changed files

📝 crates/aenv/src/client/buildkit.rs (+47 -2)

📄 Description

What

Treat peer disconnect I/O errors as clean termination in the CLI's BuildKit bridge, and add a regression test using a real Unix socket with its peer's read side closed.

Why

An aenv build can fail with Broken pipe (os error 32) even after the server has started publishing the template. The ensuing cleanup request then returns HTTP 409 because publication cannot be cancelled.

If buildctl closes a socket while final status traffic is still arriving, a failed bridge write can terminate the tunnel before the CLI observes buildctl's successful exit. Finishing that connection cleanly lets the existing process-exit and template-status checks determine the build result.

No linked issue; addresses the reported intermittent CI build failure.

Scope and non-goals

Limited to crates/aenv/src/client/buildkit.rs: disconnect handling, an explanatory comment, and a socket regression test.

Design and behavior changes

  • Treat broken pipe, connection reset, unexpected EOF, and not-connected I/O errors as clean connection termination when forwarding upstream or writing to the local buildctl socket.
  • Preserve other errors, including WebSocket handshake and protocol failures.
  • Keep the existing requirement that buildctl exits successfully and template status reaches ready.
  • The regression keeps the local peer's write side open while closing its read side, forcing a failed write rather than allowing upstream EOF to finish the bridge first.

Compatibility and operations

  • Public API or generated protocol: unchanged.
  • Configuration or defaults: unchanged.
  • Snapshot manifest, artifact layout, or storage format: unchanged.
  • Upgrade and rollback: CLI-only change; no migration required.
  • Host requirements, permissions, ports, or dependencies: unchanged.

Validation

  • make fmt
  • make clippy
  • make test-unit
  • Relevant Rust integration tests
  • make -C services test (required when services/ changes)
  • Generated clients/server regenerated with the documented make target
  • Documentation updated
  • Benchmarks or performance comparison completed

Commands and results:

make fmt                                                   PASS
cargo test -p aenv                                          PASS (56 tests)
cargo clippy -p aenv --tests -- -D warnings                  PASS
git diff --check                                           PASS

Confirmed that local_read_shutdown_does_not_fail_bridge fails with Broken pipe (os error 32) when the local write fix is temporarily removed, and passes with the fix restored.

Skipped checks and reasons:

  • Full workspace clippy and test-unit targets: validation scoped to the affected CLI package.
  • VM/BuildKit E2E suite: not run; requires an authenticated, otherwise idle AgentENV node and VM/BuildKit setup.
  • Go, code generation, documentation, and performance checks: no corresponding changes.

Risks and reviewer notes

Disconnects do not directly mark a build successful: buildctl's exit status and the server's terminal template status still determine success. The regression reproduces the socket failure locally; it does not reproduce the entire CI publication sequence.

Checklist

  • The PR contains one coherent change and no unrelated formatting or refactoring.
  • New behavior is covered by tests, or I explained why testing is impractical.
  • Logs and examples contain no credentials, tokens, or private registry information.
  • I did not manually edit generated code without updating its source and regenerating it.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/kvcache-ai/AgentENV/pull/300 **Author:** [@yingdi-shan](https://github.com/yingdi-shan) **Created:** 9/16/2026 **Status:** ✅ Merged **Merged:** 9/17/2026 **Merged by:** [@yingdi-shan](https://github.com/yingdi-shan) **Base:** `main` ← **Head:** `fix/cli-buildkit-publication-disconnect` --- ### 📝 Commits (1) - [`c7f5b3f`](https://github.com/kvcache-ai/AgentENV/commit/c7f5b3fe8386a41aa5421f2c279543c2cd97eb4c) fix(cli): tolerate BuildKit tunnel closure during publication ### 📊 Changes **1 file changed** (+47 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `crates/aenv/src/client/buildkit.rs` (+47 -2) </details> ### 📄 Description ## What Treat peer disconnect I/O errors as clean termination in the CLI's BuildKit bridge, and add a regression test using a real Unix socket with its peer's read side closed. ## Why An `aenv build` can fail with `Broken pipe (os error 32)` even after the server has started publishing the template. The ensuing cleanup request then returns HTTP 409 because publication cannot be cancelled. If buildctl closes a socket while final status traffic is still arriving, a failed bridge write can terminate the tunnel before the CLI observes buildctl's successful exit. Finishing that connection cleanly lets the existing process-exit and template-status checks determine the build result. ## Related issue No linked issue; addresses the reported intermittent CI build failure. ## Scope and non-goals Limited to `crates/aenv/src/client/buildkit.rs`: disconnect handling, an explanatory comment, and a socket regression test. ## Design and behavior changes - Treat broken pipe, connection reset, unexpected EOF, and not-connected I/O errors as clean connection termination when forwarding upstream or writing to the local buildctl socket. - Preserve other errors, including WebSocket handshake and protocol failures. - Keep the existing requirement that buildctl exits successfully and template status reaches `ready`. - The regression keeps the local peer's write side open while closing its read side, forcing a failed write rather than allowing upstream EOF to finish the bridge first. ## Compatibility and operations - Public API or generated protocol: unchanged. - Configuration or defaults: unchanged. - Snapshot manifest, artifact layout, or storage format: unchanged. - Upgrade and rollback: CLI-only change; no migration required. - Host requirements, permissions, ports, or dependencies: unchanged. ## Validation - [x] `make fmt` - [ ] `make clippy` - [ ] `make test-unit` - [ ] Relevant Rust integration tests - [ ] `make -C services test` (required when `services/` changes) - [ ] Generated clients/server regenerated with the documented `make` target - [ ] Documentation updated - [ ] Benchmarks or performance comparison completed Commands and results: ```text make fmt PASS cargo test -p aenv PASS (56 tests) cargo clippy -p aenv --tests -- -D warnings PASS git diff --check PASS ``` Confirmed that `local_read_shutdown_does_not_fail_bridge` fails with `Broken pipe (os error 32)` when the local write fix is temporarily removed, and passes with the fix restored. Skipped checks and reasons: - Full workspace clippy and test-unit targets: validation scoped to the affected CLI package. - VM/BuildKit E2E suite: not run; requires an authenticated, otherwise idle AgentENV node and VM/BuildKit setup. - Go, code generation, documentation, and performance checks: no corresponding changes. ## Risks and reviewer notes Disconnects do not directly mark a build successful: buildctl's exit status and the server's terminal template status still determine success. The regression reproduces the socket failure locally; it does not reproduce the entire CI publication sequence. ## Checklist - [x] The PR contains one coherent change and no unrelated formatting or refactoring. - [x] New behavior is covered by tests, or I explained why testing is impractical. - [x] Logs and examples contain no credentials, tokens, or private registry information. - [x] I did not manually edit generated code without updating its source and regenerating it. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-29 14:22:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kvcache-ai/AgentENV#330
No description provided.