ssh
Recipe card from the charly-core plugin (Commands — runtime CLI verbs).
MUST be invoked before any work involving: charly --host <alias|target>
remote execution, charly ssh tunnel port forwarding for external SPICE/VNC
viewers, or managing host aliases via charly settings set hosts.<alias>.
Two orthogonal surfaces
Section titled “Two orthogonal surfaces”1. charly --host <alias> — re-exec any charly command on a remote machine
Section titled “1. charly --host <alias> — re-exec any charly command on a remote machine”Set --host (or CHARLY_HOST) at the top level of any charly invocation.
charly shells out to the system ssh binary, runs charly <rest of argv> on
the remote host, and streams stdin/stdout/stderr through. Exit code
propagates.
# Alias setup (once per workstation):charly settings set hosts.o o.example.org
# Any charly verb works:charly --host o statuscharly --host o start openclawcharly --host o vm listcharly --host o deploy add host fedora-codercharly --host o test libvirt info archcharly --host o test libvirt screenshot arch - > /tmp/local.png # stdout pipes backLocalOnly commands are NOT re-execed, even when --host is set:
charly settings …, charly version, charly ssh tunnel …. These manage the local
workstation (settings file, CLI version, local tunnel listener) and
would be meaningless on the remote host.
Transport: system ssh binary via os/exec, so ~/.ssh/config,
agent forwarding, and ControlMaster all work transparently. If your
target needs a specific key, set it in ~/.ssh/config — charly stays out
of SSH authentication.
Client-only flags stripped before re-exec: --host, --dir / -C,
--repo. These are workstation-local concerns and must not be
forwarded to the remote side.
2. charly ssh tunnel — expose a remote VM’s display for external GUI apps
Section titled “2. charly ssh tunnel — expose a remote VM’s display for external GUI apps”For apps that aren’t charly (virt-viewer, remote-viewer with a bare URL,
TigerVNC, Spicy), open an SSH-forwarded local endpoint:
charly ssh tunnel spice <vm> [--uri qemu+ssh://user@host/session] [--tcp]charly ssh tunnel vnc <vm> [--uri qemu+ssh://user@host/session] [--tcp]Default mode preserves the wire format: UNIX socket in, UNIX socket out
(local path under /tmp/charly-tunnel-<id>.sock). --tcp forces a
127.0.0.1:spice+unix:// / vnc+unix://.
$ charly ssh tunnel spice arch --uri qemu+ssh://o.example.org/sessionspice tunnel: spice+unix:///tmp/charly-tunnel-8e4c.sockConnect with: remote-viewer spice+unix:///tmp/charly-tunnel-8e4c.sockPress Ctrl-C to close the tunnel.Blocks until SIGINT/SIGTERM; closes listener + SSH client cleanly on exit.
Not needed for virt-manager or remote-viewer --connect qemu+ssh://
— those auto-forward UNIX-socket listeners through libvirt’s RPC
fd-passing, with zero charly involvement. See /charly-vm:arch-cloud-vm.
Alias management
Section titled “Alias management”| Command | Effect |
|---|---|
charly settings set hosts.<alias> <ssh-target> |
create/update alias |
charly settings get hosts.<alias> |
print resolved target |
charly settings reset hosts.<alias> |
delete alias |
charly settings list |
show all settings including host_aliases map |
<ssh-target> forms: host, user@host, user@host:port. When
resolving, plain words that look like aliases (no @, no .) are
looked up in hosts.*; anything else is treated as a raw ssh target
and passed through.
When NOT to use --host
Section titled “When NOT to use --host”- When you want artifacts (screenshots, recordings) to land in the local
filesystem → use the declarative
libvirt:/vnc:/spice:check verbs against the vm target withCHARLY_LIBVIRT_URI=qemu+ssh://…set instead; it runs charly locally and forwards the display channel over SSH. - When
charlyisn’t installed on the remote machine → setCHARLY_LIBVIRT_URIor usecharly ssh tunnel.
Cross-References
Section titled “Cross-References”/charly-vm:arch-cloud-vm— “Connecting from a remote workstation” — the canonical worked example across all three paths./charly-build:settings—hosts.<alias>key schema./charly-check:spice— the declarativespice:check verb; the host resolves the VM’s SPICE endpoint (honoringCHARLY_LIBVIRT_URIfor a remote hypervisor)./charly-check:libvirt— the declarativelibvirt:check verb served out-of-process by candy/plugin-vm; honorsCHARLY_LIBVIRT_URIfor a remote hypervisor./charly-check:vnc— the declarativevnc:check verb (served out-of-process by candy/plugin-vnc); the host pre-resolves the RFB endpoint for pod AND vm targets (a VM’s libvirt VNC via bridge/tunnel).