Repository navigation
fix(no-ticket): quote the standalone binary path in helper launchers - #492
Conversation
The CLI kept a table of Cloudsmith hostnames. That table pinned the CLI
to the production hosts. The CLI now gets the domains of a Workspace
from GET /v2/workspaces/{workspace}/domains/ on the configured API host.
The answer includes the Cloudsmith-owned hosts, in preference order.
- Remove the built-in hostname table and the [domains] section in
config.ini.
- Keep version 1 of the domains list JSON document. Set primary and
created_at to null, because the API does not give them.
- Without a Workspace, domains list uses the cached domains. If no
domains are cached, it gets the domains of a Workspace that the
credential is a member of.
- Name the domain cache after the full API base URL, so two deployments
on one hostname do not share a cache.
- Put the org in the Terraform token for every host that the API lists
as Cloudsmith-owned, not only for *.cloudsmith.io hosts.
- Make the credential helper installers configure the Cloudsmith-owned
hosts that the API lists. They use their default host only when they
cannot get the domains.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The docker, pnpm, cargo and terraform installers each had a copy of the code that builds the launcher command for a standalone binary. The copies put the path in plain double quotes, so a path with `$` or a backtick broke the POSIX launcher. `helper_command()` in `launchers.py` replaces the copies and quotes the path with `shlex.quote`. Windows output does not change. The helpers also had five copies of the "Unable to retrieve credentials" message. It is now one `REFUSAL_MESSAGE` in `common.py`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The focused quoting fix and behavior-preserving refactoring have no unresolved findings, and reported execution checks confirm literal paths and argument forwarding.
No open issues 🎉
What changed in this PR
Fixes standalone credential-helper launchers on POSIX systems by safely quoting executable paths and sharing command construction.
Changes:
- Centralizes launcher commands for Docker, pnpm, Cargo, and Terraform; preserves Windows output.
- Consolidates credential-refusal messages without changing their text.
- Strengthens the path-quoting regression test and documents the fix.
| File | Description |
|---|---|
| cloudsmith_cli/credential_helpers/terraform/runtime.py | Uses shared refusal message. |
| cloudsmith_cli/credential_helpers/terraform/installer.py | Uses shared launcher command. |
| cloudsmith_cli/credential_helpers/pnpm/runtime.py | Uses shared refusal message. |
| cloudsmith_cli/credential_helpers/pnpm/installer.py | Uses shared launcher command. |
| cloudsmith_cli/credential_helpers/launchers.py | Centralizes commands and safe POSIX quoting. |
| cloudsmith_cli/credential_helpers/generic.py | Uses shared refusal message. |
| cloudsmith_cli/credential_helpers/docker/runtime.py | Uses shared refusal message. |
| cloudsmith_cli/credential_helpers/docker/installer.py | Uses shared launcher command. |
| cloudsmith_cli/credential_helpers/common.py | Defines shared refusal message. |
| cloudsmith_cli/credential_helpers/cargo/runtime.py | Uses shared refusal message. |
| cloudsmith_cli/credential_helpers/cargo/installer.py | Uses shared launcher command. |
| cloudsmith_cli/cli/tests/test_credential_helper_terraform.py | Updates refusal-message assertions. |
| cloudsmith_cli/cli/tests/test_credential_helper_pnpm.py | Updates refusal-message assertions. |
| cloudsmith_cli/cli/tests/test_credential_helper_cargo.py | Updates refusal-message assertions. |
| cloudsmith_cli/cli/tests/commands/test_credential_helper.py | Updates refusal-message assertions. |
| cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py | Checks quoting for paths containing $ and spaces. |
| cloudsmith_cli/cli/tests/commands/test_credential_helper_generic.py | Updates refusal-message references. |
| CHANGELOG.md | Documents the POSIX launcher fix. |
Review effort: Balanced
The CLI kept a table of Cloudsmith hostnames. That table pinned the CLI
to the production hosts. The CLI now gets the domains of a Workspace
from GET /v2/workspaces/{workspace}/domains/ on the configured API host.
The answer includes the Cloudsmith-owned hosts, in preference order.
- Remove the built-in hostname table and the [domains] section in
config.ini.
- Keep version 1 of the domains list JSON document. Set primary and
created_at to null, because the API does not give them.
- Without a Workspace, domains list uses the cached domains. If no
domains are cached, it gets the domains of a Workspace that the
credential is a member of.
- Name the domain cache after the full API base URL, so two deployments
on one hostname do not share a cache.
- Put the org in the Terraform token for every host that the API lists
as Cloudsmith-owned, not only for *.cloudsmith.io hosts.
- Make the credential helper installers configure the Cloudsmith-owned
hosts that the API lists. They use their default host only when they
cannot get the domains.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@copilot rebase and resolve conflicts. |
Co-authored-by: cloudsmith-iduffy <178375997+cloudsmith-iduffy@users.noreply.github.com>
Merged the latest |
|
@copilot fix the conflict. |
Co-authored-by: cloudsmith-iduffy <178375997+cloudsmith-iduffy@users.noreply.github.com>
Resolved against the PR’s current base, |
Description
The standalone binary writes launchers that run the binary by its absolute path. The docker, pnpm, cargo and terraform installers each had their own copy of that code, and each copy put the path in plain double quotes. In a POSIX shell,
$and backticks still expand inside double quotes, so a binary under a path such as/opt/price$USD/cloudsmithgave a launcher that ran the wrong command.helper_command()incredential_helpers/launchers.pynow builds the launcher command for every helper. It quotes the path withshlex.quoteon Linux and macOS. The Windows.cmdoutput is the same as before.REFUSAL_MESSAGEincredential_helpers/common.py. The text does not change.Type of Change
Additional Notes
test_frozen_install_launcher_targets_executablenow installs the docker launcher from a path with$in it and checks the exactexecline. It fails on the old code.🤖 Generated with Claude Code