Address remaining review items: L4/M1 + L2/L5 cleanup
Build App / compute-version (pull_request) Successful in 3s
Build Container / build-container (pull_request) Successful in 57s
Build App / build-macos (pull_request) Successful in 2m15s
Build App / build-windows (pull_request) Successful in 2m54s
Build App / build-linux (pull_request) Successful in 5m44s
Build App / create-tag (pull_request) Has been skipped
Build App / sync-to-github (pull_request) Has been skipped

- L4: sync_bedrock_credentials (renamed from write_bedrock_static_
  credentials) now also clears a stale ~/.aws/credentials when the
  project no longer uses static-credential Bedrock, so static keys don't
  linger unused in the persistent home volume after switching backends.
  Skipped when /tmp/.host-aws is mounted (host-managed ~/.aws). HOME is
  also set explicitly on the exec env for robustness.
- M1: the Backup button now has a tooltip and the success toast notes
  that the archive includes MCP/config which may contain MCP-embedded
  API keys (OAuth tokens are excluded) — keep it private.
- L2: backup now uses async file IO (tokio::fs::File + AsyncWriteExt,
  tokio::fs::remove_file) instead of blocking std::fs between awaits;
  dropped-file reads use tokio::fs::metadata/read.
- L5: upload_host_file_to_terminal explicitly `mkdir -p`s
  /tmp/triple-c-drops instead of relying on Docker's tar extractor to
  create the parent dir.

Verified L4 cleanup guard, L5 mkdir, async IO, and exit-code paths
against real containers. cargo check / tsc / vitest all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 14:37:33 -07:00
parent edf0698774
commit d65872dc94
5 changed files with 77 additions and 33 deletions
+8 -7
View File
@@ -254,10 +254,11 @@ rm -rf "$STAGE""#;
StartExecResults::Detached => return Err("Backup exec started detached".to_string()),
};
use std::io::Write;
let file =
std::fs::File::create(&host_path).map_err(|e| format!("Failed to create backup file: {}", e))?;
let mut writer = std::io::BufWriter::new(file);
use tokio::io::AsyncWriteExt;
let file = tokio::fs::File::create(&host_path)
.await
.map_err(|e| format!("Failed to create backup file: {}", e))?;
let mut writer = tokio::io::BufWriter::new(file);
let mut total: u64 = 0;
let mut stderr_text = String::new();
let mut stream_err: Option<String> = None;
@@ -265,7 +266,7 @@ rm -rf "$STAGE""#;
while let Some(msg) = output.next().await {
match msg {
Ok(LogOutput::StdOut { message }) => {
if let Err(e) = writer.write_all(&message) {
if let Err(e) = writer.write_all(&message).await {
stream_err = Some(format!("Failed to write backup file: {}", e));
break;
}
@@ -282,7 +283,7 @@ rm -rf "$STAGE""#;
}
}
if stream_err.is_none() {
if let Err(e) = writer.flush() {
if let Err(e) = writer.flush().await {
stream_err = Some(format!("Failed to finalize backup file: {}", e));
}
}
@@ -321,7 +322,7 @@ rm -rf "$STAGE""#;
if let Some(err) = stream_err {
// Don't leave a partial/corrupt archive behind.
let _ = std::fs::remove_file(&host_path);
let _ = tokio::fs::remove_file(&host_path).await;
return Err(err);
}