Skip to content

fix: import workspace snapshot before setup - #139

Merged
delete-cloud merged 1 commit into
mainfrom
fix/setup-after-workspace-import
May 12, 2026
Merged

delete-cloud merged 1 commit into
mainfrom
fix/setup-after-workspace-import

Conversation

@delete-cloud

@delete-cloud delete-cloud commented May 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • move remote snapshot import into Docker workspace provisioning before setup commands run
  • remove HTTP post-provision archive import so setup and agent see the same initialized workspace
  • add regression coverage for setup seeing uploaded files before the agent container starts

Validation

  • uv run pytest tests/coding_agent/environment/test_docker_workspace_provider.py -k "imports_snapshot_before_setup_phase" -q
  • uv run pytest tests/coding_agent/environment/test_docker_workspace_provider.py tests/coding_agent/environment/test_docker_workspace_provider_transfer.py tests/ui/test_http_server_workspace_transfer.py tests/ui/test_http_server.py -k "workspace or setup or remote_phases or provision" -q
  • uv run pytest tests/coding_agent/environment/test_docker_workspace_provider.py tests/coding_agent/environment/test_docker_workspace_provider_transfer.py tests/ui/test_http_server_workspace_transfer.py tests/ui/test_http_server.py tests/cli/test_remote_client.py -q
  • uv run basedpyright --level error src/coding_agent/environment/docker_workspace_provider.py src/coding_agent/ui/http_server.py tests/coding_agent/environment/test_docker_workspace_provider.py tests/ui/test_http_server_workspace_transfer.py
  • git diff --check
  • dogfood remote run with DeepSeek deepseek-v4-pro: setup marker present, setup secret absent from agent phase, agent network blocked, cleanup left no sessions/workspaces

Summary by CodeRabbit

  • New Features

    • Docker workspaces now support initialization from base64-encoded snapshot archives, enabling users to restore pre-configured workspace states and content.
  • Refactor

    • Improved workspace snapshot initialization architecture for better separation of concerns.
  • Tests

    • Added test coverage for snapshot-based workspace initialization to verify proper file extraction and execution order.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Snapshot archive initialization moves from HTTP server asynchronous pre-population to Docker workspace provider extraction during provisioning. The provider now validates and extracts base64 snapshots into the workspace root before running the setup phase. Corresponding HTTP server snapshot code is removed, and test configuration is consolidated via a helper function.

Changes

Workspace Snapshot Initialization Migration

Layer / File(s) Summary
Docker Provider Snapshot Extraction
src/coding_agent/environment/docker_workspace_provider.py, tests/coding_agent/environment/test_docker_workspace_provider.py
provision_cloud_workspace_binding validates and extracts base64-encoded snapshots into the workspace root before running setup and starting the container. New test verifies snapshot presence during setup phase execution and validates final file state in the workspace directory.
HTTP Server Snapshot Code Removal
src/coding_agent/ui/http_server.py
Removes import_workspace_archive_from_config import, deletes the internal _populate_provisioned_cloud_binding helper, and removes snapshot detection logic from create_session flow.
Test Configuration Helper
tests/ui/test_http_server_workspace_transfer.py
Adds _test_runtime_profile_config() helper to centralize runtime profile configuration fields and applies it across multiple test cases via dictionary unpacking for consistent mock setup.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 Snapshots migrate from server to provider,
Extracted before setup, delivered quicker,
Docker roots grow with archive precision,
Tests confirm the execution's decision,
One helper config keeps the tests in line! 📦

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving workspace snapshot import before setup execution, which is the core objective of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/setup-after-workspace-import

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@coding-agent/src/coding_agent/environment/docker_workspace_provider.py`:
- Around line 402-411: The extraction of snapshot_archive_base64 via
extract_workspace_archive_base64 can fail before any container is started, and
currently the outer exception path may skip removing workspace_root if docker
cleanup also errors; update the logic around extract_workspace_archive_base64 in
DockerWorkspaceProvider (refer to workspace_root and
extract_workspace_archive_base64) so that any exception raised during extraction
immediately deletes/cleans up workspace_root (or uses a finally block that
guarantees workspace_root removal if containers were never created) before
re-raising the error, rather than relying on later docker cleanup; ensure the
cleanup is robust (ignore errors during deletion) so no workspace directories
are leaked on extraction failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d7a976a-5757-40b9-88b0-b9fc97653fd2

📥 Commits

Reviewing files that changed from the base of the PR and between 7172082 and 318117f.

📒 Files selected for processing (4)
  • coding-agent/src/coding_agent/environment/docker_workspace_provider.py
  • coding-agent/src/coding_agent/ui/http_server.py
  • coding-agent/tests/coding_agent/environment/test_docker_workspace_provider.py
  • coding-agent/tests/ui/test_http_server_workspace_transfer.py
💤 Files with no reviewable changes (1)
  • coding-agent/src/coding_agent/ui/http_server.py

Comment on lines +402 to +411
snapshot_archive_base64 = source.get("snapshot_archive_base64")
if snapshot_archive_base64 is not None:
if not isinstance(snapshot_archive_base64, str):
raise ValueError(
"workspace_source.snapshot_archive_base64 must be a string"
)
extract_workspace_archive_base64(
workspace_root,
snapshot_archive_base64,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid leaking workspace directories when snapshot extraction fails before any container starts.

If extract_workspace_archive_base64(...) fails here, the except block still attempts docker cleanup; if that cleanup errors, workspace_root is not deleted (Line 429), leaking directories and potentially consuming quota over repeated failures.

Suggested fix
         try:
+            docker_cleanup_needed = False
             snapshot_archive_base64 = source.get("snapshot_archive_base64")
             if snapshot_archive_base64 is not None:
                 if not isinstance(snapshot_archive_base64, str):
                     raise ValueError(
                         "workspace_source.snapshot_archive_base64 must be a string"
                     )
                 extract_workspace_archive_base64(
                     workspace_root,
                     snapshot_archive_base64,
                 )
+            docker_cleanup_needed = True
             _run_docker_setup_phase_if_configured(provider_config, config, binding)
             _start_docker_workspace_container(provider_config, binding)
         except Exception as exc:
             logger.exception(
                 "Docker workspace creation failed for workspace_id=%s",
                 workspace_id,
             )
             cleanup_failed = False
-            try:
-                _remove_docker_workspace_container(provider_config, workspace_id)
-            except Exception as cleanup_exc:
-                cleanup_failed = True
-                note = (
-                    "failed to clean up docker workspace container after start failure: "
-                    + str(cleanup_exc)
-                )
-                exc.add_note(note)
+            if docker_cleanup_needed:
+                try:
+                    _remove_docker_workspace_container(provider_config, workspace_id)
+                except Exception as cleanup_exc:
+                    cleanup_failed = True
+                    note = (
+                        "failed to clean up docker workspace container after start failure: "
+                        + str(cleanup_exc)
+                    )
+                    exc.add_note(note)
             if not cleanup_failed and workspace_root.exists():
                 shutil.rmtree(workspace_root)
             raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-agent/src/coding_agent/environment/docker_workspace_provider.py`
around lines 402 - 411, The extraction of snapshot_archive_base64 via
extract_workspace_archive_base64 can fail before any container is started, and
currently the outer exception path may skip removing workspace_root if docker
cleanup also errors; update the logic around extract_workspace_archive_base64 in
DockerWorkspaceProvider (refer to workspace_root and
extract_workspace_archive_base64) so that any exception raised during extraction
immediately deletes/cleans up workspace_root (or uses a finally block that
guarantees workspace_root removal if containers were never created) before
re-raising the error, rather than relying on later docker cleanup; ensure the
cleanup is robust (ignore errors during deletion) so no workspace directories
are leaked on extraction failure.

@delete-cloud
delete-cloud merged commit 14a5b0f into main May 12, 2026
1 check passed
@delete-cloud
delete-cloud deleted the fix/setup-after-workspace-import branch May 12, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant