Skip to content

fix(cli): use local ssh client for vm access#2442

Merged
LopatinDmitr merged 2 commits into
mainfrom
fix/cli/remove-native-ssh-client
Jun 15, 2026
Merged

fix(cli): use local ssh client for vm access#2442
LopatinDmitr merged 2 commits into
mainfrom
fix/cli/remove-native-ssh-client

Conversation

@LopatinDmitr

@LopatinDmitr LopatinDmitr commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Description

Drop the embedded Go SSH/SCP implementation and run the local ssh/scp
binaries directly through a ProxyCommand (the d8 port-forward subcommand).
Provide a uniform way to pass extra options to the local client and to run
a command on the VM.

Highlights of the user-facing surface:

  • Single --ssh-args flag for the local ssh/scp client. Can be repeated
    or given as a single value with space-separated options:
    d8 ssh user@myvm --ssh-args='-o StrictHostKeyChecking=no -o LogLevel=ERROR'
    d8 ssh user@myvm --ssh-args='-o X' --ssh-args='-o Y'
  • -- separator for the command to execute on the VM (mirrors plain ssh):
    d8 ssh user@myvm -- 'ls -la /'
    d8 ssh user@myvm -- bash -lc 'echo $HOSTNAME'
  • -c/--command remains supported as an equivalent to --.
  • --known-hosts is mapped to OpenSSH UserKnownHostsFile; --identity-file
    to -i.
  • --local-ssh and --local-ssh-opts are kept as deprecated compatibility
    flags (--local-ssh-opts is the old name for --ssh-args).
  • templates.MinimumArgs was added so commands can consume everything
    after --.

Why do we need it, and what problem does it solve?

The previous virtctl-style command shipped its own native Go SSH/SCP
client, including terminal handling, knownhosts parsing and stdio
tunnel plumbing. Maintaining that implementation:

  • duplicated what OpenSSH already does well (proxy commands, keep-alives,
    host key verification, compression, control master, etc.);
  • made it impossible to use features the local client already supports
    (-L, -R, -D, jump hosts, custom config in ~/.ssh/config,
    ProxyJump, etc.) without growing the wrapper with more flags;
  • meant every fix for an edge case (e.g. non-ASCII terminals on Windows)
    had to be ported to the embedded code.

Switching to the local ssh/scp client makes the CLI delegate to the
tooling users (and CI) already have, with a much smaller surface in Go
code. The new --ssh-args design replaces the previous --ssh-opts /
positional-tail approach, which was both verbose (each -o had to be
wrapped in its own flag) and inconsistent with the standard ssh CLI.

What is the expected result?

  1. d8 ssh user@myvm opens an interactive SSH session through
    d8 v port-forward --stdio=true (ProxyCommand).
  2. d8 ssh user@myvm -- 'cmd' runs cmd on the VM and exits with its
    status code; d8 ssh user@myvm -c 'cmd' does the same.
  3. d8 ssh user@myvm --ssh-args='-o X -o Y' passes -o X -o Y to the
    local ssh (split into separate argv entries by whitespace).
  4. d8 scp local user@myvm:remote copies a file via local scp; scp
    flags can be supplied via the same --ssh-args flag.
  5. The deprecated --local-ssh-opts flag still works and emits a
    warning pointing to --ssh-args.

Manual smoke test (13 cases covering --ssh-args single/repeat/mixed
forms, -- vs -c, deprecation warning, scp up- and download) was run
against vm-alpine in the test namespace.

Checklist

  • The code is covered by unit tests.
  • e2e tests passed.
  • Documentation updated according to the changes.
  • Changes were tested in the Kubernetes cluster manually.

Changelog entries

section: cli
type: fix
summary: "d8 ssh / d8 scp now use the local OpenSSH/SCP clients via ProxyCommand; pass extra client options through a single --ssh-args flag and the command via --."
impact_level: low

@LopatinDmitr LopatinDmitr added this to the v1.9.0 milestone Jun 3, 2026
@LopatinDmitr LopatinDmitr marked this pull request as draft June 3, 2026 13:59
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch from ab8e42b to 5969f19 Compare June 3, 2026 14:11
@LopatinDmitr LopatinDmitr marked this pull request as ready for review June 5, 2026 07:49
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch 4 times, most recently from 57f6d8d to 6dd0b06 Compare June 9, 2026 12:58
Comment thread src/cli/internal/cmd/ssh/ssh.go
@universal-itengineer universal-itengineer modified the milestones: v1.9.0, v1.10.0 Jun 10, 2026
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch 2 times, most recently from 9483c25 to 4aa6af8 Compare June 14, 2026 17:14
@LopatinDmitr LopatinDmitr requested a review from diafour June 14, 2026 17:15
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch from d065a23 to 4b60517 Compare June 14, 2026 17:41
Use the local OpenSSH/SCP clients for VM access by default and remove the embedded native SSH/SCP implementation.

Keep --local-ssh and --local-ssh-opts as deprecated compatibility flags, add --ssh-opts for extra client options, and map --known-hosts to OpenSSH UserKnownHostsFile.

Signed-off-by: Dmitry Lopatin <dmitry.lopatin@flant.com>
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch from 4b60517 to e1e059a Compare June 15, 2026 07:06
Signed-off-by: Dmitry Lopatin <dmitry.lopatin@flant.com>
@LopatinDmitr LopatinDmitr force-pushed the fix/cli/remove-native-ssh-client branch from bad1f20 to 14ed0ab Compare June 15, 2026 08:09
@LopatinDmitr LopatinDmitr merged commit dbc1fa6 into main Jun 15, 2026
31 of 32 checks passed
@LopatinDmitr LopatinDmitr deleted the fix/cli/remove-native-ssh-client branch June 15, 2026 09:31
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.

5 participants