When deploying keys to a machine, upload ALL private keys from ALL
other machines (not just sync pair peers). Also populate known_hosts
with all other machine hosts. Creates a full mesh where any machine
can SSH to any other.
- sshmanager/deploy.go: change knownHostsHost string parameter to
knownHostsHosts []string for multi-host ssh-keyscan
- handlers_machines.go: replace sync-pair-based key detection with
loop over all machines, deduplicating by local key path
- sshmanager/deploy.go: StdinPipe() must be called BEFORE Start(),
not after. Reordered the calls to fix "ssh: StdinPipe after
process started" error.
- Return DeployResult instead of nil error on SSH dial failure
so the frontend always gets a parseable response.
- Add slog.Debug for key upload, slog.Warn for ssh-keyscan and
authorized_keys failures, slog.Info for final result summary.
- sshmanager/deploy.go: initialize DeployResult with empty slices
instead of nil to prevent null serialization in JSON
- Machines.tsx: use ?? [] fallback for messages and errors arrays
in deploy keys modal to handle null/undefined gracefully
- sshmanager/deploy.go: new DeployKeysToMachine function that uploads
private keys, populates known_hosts via ssh-keyscan, and adds server
pub key to authorized_keys on remote machines
- handlers_machines.go: new DeployKeys handler with auto-detection of
keys needed per sync pair (source->dest uploads dest key, dest->source
uploads source key)
- router.go: POST /machines/{id}/deploy-keys route
- client.ts: deployKeys() API method
- Machines.tsx: Deploy Keys button + modal with result display