fix: name the agent binary devpod picked from a hostname (#560 section 3) - #562
Open
blooop wants to merge 1 commit into
Open
fix: name the agent binary devpod picked from a hostname (#560 section 3)#562blooop wants to merge 1 commit into
blooop wants to merge 1 commit into
Conversation
Reviewer's GuideThe PR diagnoses devpod’s hostname-sensitive ARM agent selection without changing devpod or piping its Sequence diagram for conditional ARM agent hint on failed devpod upsequenceDiagram
participant User
participant Dl as dl
participant Devpod
participant Container
participant Host
User->>Dl: Launch workspace
Dl->>Devpod: up(workspace)
Devpod->>Container: Match uname -a against *arm*
Container-->>Devpod: Host architecture and workspace hostname
Devpod-->>Dl: Refused with exit status
Dl->>Dl: reads_as_arm(workspace_id)
Dl->>Dl: reads_as_arm(host_arch)
alt workspace id matches and host is not ARM
Dl-->>User: Conditional agent-binary hint
else ordinary id or ARM host
Dl-->>User: Preserve devpod diagnostics only
end
Dl-->>User: Return devpod exit code
Flow diagram for hostname-triggered ARM agent selectionflowchart LR
Branch[Branch contains arm] --> Workspace[Workspace ID contains arm]
Workspace --> Hostname[dl sets container hostname]
Hostname --> Uname[uname -a includes hostname]
Uname --> Match[devpod matches *arm*]
Match --> Agent[devpod downloads arm64 agent]
Agent --> Failure[Agent cannot execute: exit status 126]
Failure --> Hint[dl suggests rename or docker cp on non-ARM host]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report❌ Patch coverage is
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Base automatically changed from
fix/560-a-warm-launch-says-what-it-skipped
to
main
September 4, 2026 12:55
Section 3 of #560, as far as dl can honestly reach it. devpod chooses which agent binary to inject by globbing `uname -a` for `arm`, and `uname -a` prints the nodename beside the machine. So a container whose hostname holds `arm` reads as an ARM machine, devpod downloads the arm64 agent, the version check cannot execute it, and the launch dies with `exit status 126` -- "not executable", which names neither the architecture nor the word that chose it. dl is one of the ways the word gets there: its setup pass sets the container's hostname to the workspace id, and a workspace id is derived from the branch, so `feature/armature` is enough. A refused `devpod up` of a workspace whose id contains `arm` now carries one line of dl's own, beside devpod's sentence and without changing the exit code. The line is a conditional, and that is the honest limit rather than hedging. dl runs the `up` as a passthrough, because an image build's progress belongs on the user's terminal rather than through a pipe, so dl never reads devpod's message: what it holds is a nonzero exit and a name. That is enough to know the trap is set and not enough to know it fired, so the sentence says what to look for in devpod's own output above it. Reading that output instead would mean piping the build through dl -- changing what devpod renders, and dropping the process group that lets a Ctrl-C tear a build down rather than orphan it holding the launch lock, since `Runner::session` starts its child with `OwnGroup::No` where the `up` needs `Yes` (#304). `clients::devpod::reads_as_arm` transcribes devpod's four globs, uncase-folded because a shell `case` is, and answers for a machine name as readily as for a hostname -- which is what the exemption reads: a host that is itself ARM gets no line, because there devpod's guess is right. The upstream fix is one line (glob `uname -m`) and is not here. Claude-Session: https://claude.ai/code/session_01Dn4qJGhkW4KdwQnMuNSXsN
blooop
force-pushed
the
fix/560-name-the-arm-agent-126
branch
from
September 4, 2026 12:55
de863a5 to
ee6ba5d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Section 3 of #560 — A warm attach reports neither a stale checkout nor a skipped setup pass, and an
armin a workspace id kills the launch with exit 126.Stacked on #561 (sections 1 and 2), because that PR added the
docs/cli.mdtroubleshooting section this one extends. Base retargets tomainwhen #561 merges.The bug
devpod chooses which agent binary to inject by globbing
uname -aforarm.uname -aprints the nodename beside the machine, so any container whose hostname containsarmreads as an ARM machine: devpod downloads the arm64 agent,performVersionCheckcannot execute it, and the launch dies withexit status 126. That means "not executable", which is true and names neither the architecture nor the word that chose it.dl is one of the ways the word gets there. The setup pass runs
sudo hostname <workspace-id>in every container it opens, and a workspace id is derived from the branch — sofeature/armaturebecomesdevlaunch-feature-armature-17uubecomes a container that reads as ARM.alarm,warm,charm,swarm,harmandfarmare the same trap.What this adds
A refused
devpod upof a workspace whose id containsarmgains one line beside devpod's own, with no change to the exit code:Silent for every other refusal, for an id with no
armin it, and on a host whose own architecture reads as ARM — there devpod's guess is the right one and the failure is something else. Both of those questions go through one predicate,clients::devpod::reads_as_arm, since "would that glob match" is the same question asked of a hostname or of a machine.Why the sentence is a conditional
Because dl never reads devpod's message, and that is worth keeping. The issue proposed matching devpod's stderr for
inject agenttogether withexit status 126, citingclients/devpod.rsas already reading it. That reader isdevpod::run_watching_stderr, and its only caller isflows/lifecycle/delete.rs.devpod upgoes throughdevpod::run, a passthrough, deliberately: an image build's progress belongs on the user's terminal.Switching the
upover would cost two things, not one:runner.sessionstarts the child withStdio::piped()stderr, so whatever devpod renders based on stderr being a tty changes, and every line goes through dl'seprintln!— for the several minutes an image build takes.sessionhardcodesOwnGroup::No, and theupneedsYes.upis the one call withleading_its_own_group(), which is what lets dl's interrupt handlerkillpgthe build. Without it a Ctrl-C releases the launch lock while the build carries on holding it, which is the orphaned-build bug from #304 (divergence row 27).So dl holds a nonzero exit and a workspace id. That is enough to know the trap is set and not enough to know it fired, and the line says so in those words rather than asserting what happened. An
upthat failed on an image pull for a workspace calledalarm-clockgets one sentence it can discard on sight; that is the price of not piping the build, and it is the cheaper side of the trade.This also means the issue's suggested negatives — a 126 that is not an agent injection, an
inject agentfailure that is not 126 — cannot be pinned as tests, because dl cannot see either. The conditional wording is what handles them instead, anda_failed_up_of_an_arm_named_workspace_names_the_trap_as_a_possibilityasserts the line still opens withIf devpod saidfor exactly that reason.Tests
reads_as_arminclients/devpod.rs: the substring behaviour on ordinary English branch names, the names that hold noarm, that it is not case-folded (a shellcaseis not, so a fold would answer a question devpod does not ask), and that the same predicate answers foraarch64/armv7las for a hostname.arm_agent_hintindl/src/render.rs: the line's contents, absence on an ARM host, absence for an ordinary id, and absence for every other refusal.a_failed_up_of_an_arm_named_workspace_names_the_agent_binary_devpod_pickedindl/tests/launch.rs: the whole line at the binary boundary, after devpod's own, with the exit code still devpod's 7. It follows the binary rather than assuming the runner — on an ARM host it asserts nothing was added.an_ordinary_workspace_whose_up_failed_gets_no_arm_explanation: the negative that keeps this off every failed build.New fixture
--arm-branchinlaunch_scenario.py: a third branch onorigin.gitcalledarmature, with no clone and no record, sodl blooop/devlaunch@armatureis a cold launch whose derived id containsarm. The branch name is an ordinary English word on purpose.LaunchRefusal::UpRefusedgrew aworkspace_id. It is for the renderer alone — the exit code is stillexit— and its doc comment says so.Testing
cargo test --workspace,cargo clippy --locked --all-targets -- -D warnings,cargo fmt --check,pytest test/(707) clean, with two exceptions worth naming:flows::provision::tests::the_probe_reports_the_config_facts_when_it_actually_runsfails onmainin this devcontainer too and is untouched here: it expectsclaudemountsempty and this container's own mount table answers/. It passed on CI's runners for fix: a warm launch says what it skipped (#560 sections 1 and 2) #561.a_devpod_that_refuses_the_listing_is_exit_1_and_one_linefailed once under a parallel--workspacerun and did not reproduce in five repeats of its own test binary. Nothing in this change touches the listing path; noting it rather than claiming it is clean.rust/devlaunch-core/public-api.rest.txtwas hand-edited again (two rows, in sorted position). #561'spublic-apijob confirmed the same method works, but CI's diff is still the real check.Divergence row 35 records the line.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Dn4qJGhkW4KdwQnMuNSXsN
Summary by Sourcery
Explain likely agent-binary misselection when a failed devpod launch uses a workspace ID containing
arm, without intercepting devpod's own output or changing its failure status.Bug Fixes:
devpod upoperations where workspace names containingarmmay cause the wrong agent binary to be selected and produce exit status 126.Enhancements:
Documentation:
Tests:
armaturebranch fixture for end-to-end launch scenarios.