From 7151080e5438157c558f535849edb1e8411836c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 08:41:34 +0000 Subject: [PATCH 1/4] Initial plan From ff63103394118a00882ade2aac11047386815fd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 08:49:47 +0000 Subject: [PATCH 2/4] Fix linux-portable VM mode: install codex and claude via cloud-init on first boot Co-authored-by: mjenkinsx9 <238907794+mjenkinsx9@users.noreply.github.com> Agent-Logs-Url: https://github.com/Mike-Jenkins-Org/PortableCoder/sessions/48619aa9-0370-4a91-a1e8-120bb782f44b --- docs/RUNBOOKS.md | 12 +++++++++--- runtime/linux/cloud-init/user-data | 14 ++++++++++++-- scripts/pcoder.cjs | 1 + scripts/runtime/windows/start-vm.ps1 | 7 +++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/RUNBOOKS.md b/docs/RUNBOOKS.md index c69e76f..3397958 100644 --- a/docs/RUNBOOKS.md +++ b/docs/RUNBOOKS.md @@ -58,9 +58,15 @@ Backend spec: ## Linux-Portable Run Flow 1. `pcoder` starts/ensures VM via `start-vm.cmd`. 2. VM launcher attempts WHPX acceleration, then auto-fallback to TCG. -3. Project is copied into guest over SCP. -4. Tool command runs over SSH in guest project directory. -5. Project is copied back to host after run (unless `--no-sync-back`). +3. On first boot, cloud-init installs Node.js, `codex`, and `claude` CLI tools (may take several minutes). +4. `pcoder run` waits for cloud-init to complete before running the tool. +5. Project is copied into guest over SCP. +6. Tool command runs over SSH in guest project directory. +7. Project is copied back to host after run (unless `--no-sync-back`). + +**First-boot note:** The first time you boot the VM, cloud-init provisions the guest (creates the `portable` user, installs Node.js and the coding CLI tools). This can take 5–15 minutes depending on network speed and host performance. `pcoder run` automatically waits for cloud-init to finish before launching the tool. Subsequent boots skip provisioning and start much faster. + +**Smoke check with tool checks:** Run `scripts/runtime/windows/smoke-check.cmd` after the first boot completes to verify that `codex` and `claude` are installed in the guest. Use `-SkipToolChecks` to skip tool presence checks if only testing VM boot and SSH connectivity. Acceleration override (Windows troubleshooting): - `PCODER_VM_ACCEL_MODE=auto` (default): try WHPX then fallback to TCG if launch fails. diff --git a/runtime/linux/cloud-init/user-data b/runtime/linux/cloud-init/user-data index 0287c1c..20325aa 100644 --- a/runtime/linux/cloud-init/user-data +++ b/runtime/linux/cloud-init/user-data @@ -1,8 +1,18 @@ #cloud-config users: - name: portable - sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + lock_passwd: true + groups: + - sudo + ssh_authorized_keys: + - ssh_pwauth: false -# Placeholder for VM provisioning during image bake. +packages: + - nodejs + - npm + +runcmd: + - npm install -g @openai/codex @anthropic-ai/claude-code diff --git a/scripts/pcoder.cjs b/scripts/pcoder.cjs index beda02e..da57e97 100755 --- a/scripts/pcoder.cjs +++ b/scripts/pcoder.cjs @@ -1258,6 +1258,7 @@ function buildRemoteRunScript(options) { const lines = [ 'set -e', + 'if command -v cloud-init >/dev/null 2>&1; then cloud-init status --wait 2>/dev/null || true; fi', `cd ${shellEscape(remoteProjectPath)}` ]; diff --git a/scripts/runtime/windows/start-vm.ps1 b/scripts/runtime/windows/start-vm.ps1 index 238807d..226714d 100644 --- a/scripts/runtime/windows/start-vm.ps1 +++ b/scripts/runtime/windows/start-vm.ps1 @@ -106,6 +106,13 @@ users: ssh_authorized_keys: - $PublicKey ssh_pwauth: false + +packages: + - nodejs + - npm + +runcmd: + - npm install -g @openai/codex @anthropic-ai/claude-code "@ $userData | Out-File -Encoding utf8 -FilePath $cloudInitUserDataPath } From f43f50af69f94fb19bf4bdf6bf588662b5678b53 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 08:56:25 +0000 Subject: [PATCH 3/4] Switch CI runners from depot-ubuntu-24.04 to blacksmith-2vcpu-ubuntu-2404 Co-authored-by: mjenkinsx9 <238907794+mjenkinsx9@users.noreply.github.com> Agent-Logs-Url: https://github.com/Mike-Jenkins-Org/PortableCoder/sessions/8d3bee99-535f-4958-8347-c5cc786bb1a0 --- .github/workflows/ci.yml | 2 +- .github/workflows/claude-pr-runner.yml | 2 +- README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 143c051..c26b933 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ permissions: jobs: portable-ci: - runs-on: depot-ubuntu-24.04 + runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/claude-pr-runner.yml b/.github/workflows/claude-pr-runner.yml index a24299b..30489bb 100644 --- a/.github/workflows/claude-pr-runner.yml +++ b/.github/workflows/claude-pr-runner.yml @@ -30,7 +30,7 @@ jobs: contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) - runs-on: depot-ubuntu-24.04 + runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/README.md b/README.md index 1c5ec1f..4c1fd6e 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,12 @@ Windows smoke test: ## CI - GitHub Actions workflow: `.github/workflows/ci.yml` -- Runner target: Depot-hosted runner label `depot-ubuntu-24.04` +- Runner target: Blacksmith runner label `blacksmith-2vcpu-ubuntu-2404` ## Claude PR Runner - Workflow: `.github/workflows/claude-pr-runner.yml` - Trigger: mention `@claude` in PR comments/reviews (or run manually via `workflow_dispatch`) -- Runner target: Depot-hosted runner label `depot-ubuntu-24.04` +- Runner target: Blacksmith runner label `blacksmith-2vcpu-ubuntu-2404` - Configure one auth secret: - `ANTHROPIC_API_KEY` (API key mode), or - `CLAUDE_CODE_OAUTH_TOKEN` (OAuth mode) From 5ab835a91d2bf1da5c3249e9df2fa1620d560edd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:12:44 +0000 Subject: [PATCH 4/4] Bound cloud-init wait with timeout; fail with clear message on timeout or error Co-authored-by: mjenkinsx9 <238907794+mjenkinsx9@users.noreply.github.com> Agent-Logs-Url: https://github.com/Mike-Jenkins-Org/PortableCoder/sessions/3e07f31f-0ce7-460c-8081-20c68e9768b5 --- scripts/pcoder.cjs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/pcoder.cjs b/scripts/pcoder.cjs index da57e97..d04c81c 100755 --- a/scripts/pcoder.cjs +++ b/scripts/pcoder.cjs @@ -1258,7 +1258,18 @@ function buildRemoteRunScript(options) { const lines = [ 'set -e', - 'if command -v cloud-init >/dev/null 2>&1; then cloud-init status --wait 2>/dev/null || true; fi', + 'if command -v cloud-init >/dev/null 2>&1; then', + ' _ci_to=${PCODER_CLOUD_INIT_TIMEOUT:-900}', + ' if ! timeout "$_ci_to" cloud-init status --wait 2>/dev/null; then', + ' _ci_rc=$?', + ' if [ "$_ci_rc" -eq 124 ]; then', + ' echo "pcoder: cloud-init wait exceeded ${_ci_to}s; provisioning may be incomplete" >&2', + ' else', + ' echo "pcoder: cloud-init finished with errors (exit ${_ci_rc}); provisioning may have failed" >&2', + ' fi', + ' exit 1', + ' fi', + 'fi', `cd ${shellEscape(remoteProjectPath)}` ];