GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — fix: write agent host entries with `config-ssh --no-wildcard` by matifali · Pull Request #31192 · coder/coder Conversation
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Docs previewCheck off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
config-ssh --no-wildcardconfig-ssh --no-wildcard
Documentation CheckUpdates Needed
Automated review via Coder Agents |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I reviewed the changed docs against the code at the PR head: the flag description in docs/reference/cli/config-ssh.md and the tip in docs/user-guides/workspace-access/index.md both match the new behavior of coder config-ssh --no-wildcard, which now writes one Host entry per workspace and one <agent>.<workspace>.<owner> entry per agent. I found nothing new to change.
I also checked the unchanged tip in docs/user-guides/workspace-access/jetbrains/gateway.md and found it still says --no-wildcard generates an entry per workspace only; that was already raised in the existing doc-check review thread on this PR, so it is not repeated here.
Generated by Coder Agents on behalf of @nickvigilante, using the proposed doc-check skill from #31193 on Solstice-1 Local. Reply in a thread if a finding is wrong.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
e84c93e to
8e2986f
Compare
|
Addressed in 8e2986f. The Gateway tip now says
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Fixed the CI lint failure in f0af2a0. Resource fetching now uses a wait group with the same eight-worker limit, preserving per-version warnings. Config-ssh race tests and the strict new-code lint target pass.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Docs LGTM
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
8b30808 to
841023f
Compare
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Docs LGTM. Let me know if you need me to review the rest of the PR.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Yes please I would appreciate that. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reworking the stopped-workspace path to use build history. Basing agent entries on each workspace's own last start, with a fallback to the plain workspace entry on any miss, is the right failure mode. The agent-name filter also closes a real gap, since agent names that devcontainers declare in Terraform aren't validated on the server.
I reviewed the code and docs at 841023f. Nothing I found blocks merge. The main thing worth fixing first is the cost of the build-history lookup (P2). The rest are P3s and nits, plus one docs fix that limits the new stopped-workspace paragraph to --no-wildcard.
aslilac's question about how stopped agents are reported is still open, so I'm leaving sign-off on the approach to the CLI reviewers.
🤖 Review generated with Coder Agents on behalf of @nickvigilante.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if build.BuildNumber > ws.LatestBuild.BuildNumber || build.Transition != codersdk.WorkspaceTransitionStart || build.Job.Status != codersdk.ProvisionerJobSucceeded { | ||
| continue | ||
| } | ||
| if build.TemplateVersionID != ws.LatestBuild.TemplateVersionID { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
P3 A template version mismatch drops agent entries without a warning.
This compares against the template version of the latest build, not the template's active version. If an update fails (the latest build is a failed start on the new version), the workspace's agent entries disappear on the next run and nothing is printed, while a fetch error does print a warning. Is the silence intended? Returning a sentinel error that the caller reports with the existing Skipping agent host entries warning would make the missing entries explainable.
The docs sentence at index.md:118 has the same ambiguity. See the comment there.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // ws-alpha sorts before ws-beta even though ws-alpha was created second, | ||
| // and the stopped workspaces come after the running workspaces. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Nit ws-delta and ws-gamma also sort after ws-beta by name, so this list can't tell running-first ordering apart from name ordering. Either drop the clause, or name a stopped workspace so it sorts first (for example ws-aaa) if the ordering matters.
| // ws-alpha sorts before ws-beta even though ws-alpha was created second, | |
| // and the stopped workspaces come after the running workspaces. | |
| // ws-alpha sorts before ws-beta even though ws-alpha was created second. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| // Precreated devcontainer agents retain Terraform labels, including underscores. | ||
| // Hostname components must exclude SSH syntax and doubled-hyphen delimiters. | ||
| var sshAgentNameRegex = regexp.MustCompile(`^[a-zA-Z0-9_][a-zA-Z0-9_-]*$`) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
P3 Entries for agents with uppercase names are written but can't connect.
provisioner.AgentNameRegex is case-insensitive, so Dev is a valid agent name, and this regex accepts it. OpenSSH lowercases the destination it hands to the ProxyCommand: with OpenSSH 10.2, ssh -G Main.ws.alice.coder against a Host Main.ws.alice.coder block reports hostname main.ws.alice.coder, which is what %h expands to. coder ssh then looks up main, and getWorkspaceAgent (cli/ssh.go:1181) compares names exactly, so it fails with agent not found by name "main".
Wildcard mode already has this bug, but this PR now writes these hosts into the config, where tools like Gateway list them. strings.EqualFold in getWorkspaceAgent would fix both modes. Skipping names that aren't lowercase here would also work.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| @@ -112,7 +112,15 @@ Your workspace is now accessible via `ssh coder.<workspace_name>` (for example, | |||
|
|
|||
| > [!TIP] | |||
| > If you use a third-party SSH client that discovers hosts by parsing `~/.ssh/config` (such as the VS Code Remote-SSH sidebar or scripts that enumerate known hosts), run `coder config-ssh --no-wildcard` instead. | |||
| > This generates an individual `Host` entry per workspace rather than a single wildcard block, making your workspaces visible to those tools. | |||
| > This generates an individual `Host` entry for each workspace and its known agents rather than a single wildcard block, making your workspaces visible to those tools. | |||
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Optional: this tip says the command writes entries for each agent, but nothing in this PR shows what an agent host looks like, so readers can't tell what to type or look for in a host list. #31188, which is stacked on this PR, adds the format to this section. If the two might merge far apart, consider adding it here:
| > This generates an individual `Host` entry for each workspace and its known agents rather than a single wildcard block, making your workspaces visible to those tools. | |
| > This generates an individual `Host` entry for each workspace and its known agents rather than a single wildcard block, making your workspaces visible to those tools. | |
| > Agent entries use the same hostname as the **Connect via SSH** button, such as `<agent>.<workspace_name>.<owner>.coder`. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // dashboard and served by Coder Connect. While a workspace runs, its latest | ||
| // build also lists devcontainer sub-agents, so they get entries too. A |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
P3 Entries for devcontainer sub-agents created at runtime go stale when the workspace stops.
The agent deletes the sub-agents it injected when it shuts down (agent/agentcontainers/api.go:2208), and GetWorkspaceAgentsByResourceIDs filters deleted agents out. The entry stays in ~/.ssh/config until the next config-ssh run. ssh to it starts the workspace and then fails with agent not found, because GetWorkspaceAndAgent looks up the agent as soon as the build finishes, before the sub-agent registers again. Running config-ssh while the workspace is stopped removes these entries, so host lists in Gateway and VS Code change with workspace state.
The autostart race isn't new to this PR, so accepting it is reasonable. Could the docs at least say that sub-agent entries only appear while the workspace is running?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // it used the workspace's current template version. Older versions and template | ||
| // imports cannot reliably describe the agents that will exist when it restarts. | ||
| func previousStartResources(ctx context.Context, client *codersdk.Client, ws codersdk.Workspace) ([]codersdk.WorkspaceResource, error) { | ||
| const pageSize = 20 |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
P2 Each history lookup loads up to 20 full builds, and there's no page cap.
GET /workspaces/{id}/builds returns every build on the page fully loaded: job with queue position, resources, agents, apps, app statuses, scripts and log sources (workspaceBuilds calls workspaceBuildsData with wsrelated.AllLatestBuild()). This runs on every config-ssh --no-wildcard for every workspace whose latest build has no agents.
Giving up already falls back to the workspace entry, so could this ask for a small page (say 5) and stop after a few pages? Fetching build N-1 directly with WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber, and paging only on a miss, would also work.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // Precreated devcontainer agents retain Terraform labels, including underscores. | ||
| // Hostname components must exclude SSH syntax and doubled-hyphen delimiters. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Nit Go doc comments usually start with the identifier. This one also implies the regex excludes --, but that check lives in startAgentNames.
| // Precreated devcontainer agents retain Terraform labels, including underscores. | |
| // Hostname components must exclude SSH syntax and doubled-hyphen delimiters. | |
| // sshAgentNameRegex matches agent names that are safe to write as SSH hostname | |
| // components. It allows underscores because precreated devcontainer agents keep | |
| // their Terraform labels. startAgentNames separately rejects "--", which | |
| // coder ssh treats as a delimiter. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // resources of its most recent successful start build instead. Agent entries | ||
| // are only written when every name in them is valid, so a server-supplied value | ||
| // can never be written into ssh_config as syntax. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Nit The guarantee covers agent entries only. ws.Name is appended at line 1030, before the NameValid check, so the workspace entry is still written as returned. That predates this PR, but this comment reads as covering every name.
| // resources of its most recent successful start build instead. Agent entries | |
| // are only written when every name in them is valid, so a server-supplied value | |
| // can never be written into ssh_config as syntax. | |
| // resources of its most recent successful start build instead. Agent entries | |
| // are only written when every name in them is valid, so a server-supplied | |
| // value can never be written into an agent entry as ssh_config syntax. The | |
| // workspace entry uses ws.Name without this check. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| workspace("unknown", missing), | ||
| // So does a workspace whose name is not a valid name, such as one | ||
| // created before underscores were rejected. | ||
| workspace("legacy_name", fetched, resource(codersdk.WorkspaceTransitionStart, "dev")), |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
P3 Two cheap coverage gaps:
codersdk.NameValid(ws.OwnerName) from the guard wouldn't fail any test. The workspace helper hardcodes OwnerName: "alice", so one row that overrides it (for example "bad owner") would pin that check.workspaceAgentResources directly, so the Skipping agent host entries warning is untested. A small httptest server that fails one workspace's history, plus assertions on the warning and the bare entry, would cover it.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| For a stopped workspace, Coder uses agent names from its most recent successful start. | ||
| If that start is unavailable or used a different version from the workspace's current template version, Coder generates only the workspace entry. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This paragraph sits outside the tip and never says it applies only to --no-wildcard, so someone who ran plain coder config-ssh will read it as applying to them. "The workspace's current template version" also reads as the template's active version, but the code compares against the version of the workspace's latest build (configssh.go:1116).
| For a stopped workspace, Coder uses agent names from its most recent successful start. | |
| If that start is unavailable or used a different version from the workspace's current template version, Coder generates only the workspace entry. | |
| With `--no-wildcard`, a workspace whose latest build has no agents, such as a stopped workspace, gets agent entries from its most recent successful start. | |
| If Coder can't find that start, or the start used a different template version than the workspace's latest build, Coder generates only the workspace entry. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
841023f to
bded5be
Compare
`coder config-ssh --no-wildcard` wrote one Host entry per workspace and none per agent. OpenSSH only applies exact Host matches, so the `<agent>.<workspace>.<owner>.coder` hostname shown by the dashboard and served by Coder Connect did not work, and agents in multi-agent workspaces could not be reached with plain ssh. Also write an `<agent>.<workspace>.<owner>` entry for each agent, with the same prefix and suffix as the workspace entries. Existing workspace entries are unchanged. Agents of stopped workspaces come from the template version. Server-supplied names are validated before they are written into ssh_config.
Address review findings on the --no-wildcard agent entries: - Fetch the template version of workspaces without agents once per version, concurrently, instead of once per workspace in sequence. - Fall back to the template version whenever the latest build has no agents, not only for non-start builds, so pending or failed starts are covered too. - Warn when a template version cannot be fetched instead of silently dropping its agent entries. - Split the lookup from building the names so the fallback is unit tested, and cover a stopped workspace in TestConfigSSH_NoWildcard. - Rename workspaceNames to hostNames, since it holds agent names too.
bded5be to
f6c4af3
Compare
There was an error while loading. Please reload this page.
f6c4af30
Deployed
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.