#!/usr/bin/env bash set -euo pipefail require_ssh_key() { local key_path="$1" if [[ -z "$key_path" ]]; then echo "SSH key path is required" >&2 return 1 fi if [[ ! -f "$key_path" ]]; then echo "SSH key not found: $key_path" >&2 return 1 fi } ssh_common_opts() { local ssh_user="$1" local ssh_host="$2" # Keepalive to reduce flakiness through ProxyJump # (observed: "Connection reset by peer" during scp/ssh). # # Notes: # - Avoid SSH multiplexing here: ControlPath/ControlMaster can be flaky on Windows OpenSSH + MSYS paths. # - Increased timeouts and keepalive settings to handle network instability # - Compression disabled to reduce overhead and potential connection issues echo \ -o BatchMode=yes \ -o StrictHostKeyChecking=accept-new \ -o ConnectTimeout=30 \ -o ServerAliveInterval=10 \ -o ServerAliveCountMax=6 \ -o TCPKeepAlive=yes \ -o Compression=no } ssh_run() { local ssh_key="$1" local ssh_user="$2" local ssh_host="$3" shift 3 require_ssh_key "$ssh_key" local proxy_host="${DEPLOY_SSH_PROXY_HOST:-}" local proxy_user="${DEPLOY_SSH_PROXY_USER:-$ssh_user}" local proxy_args=() if [[ -n "$proxy_host" ]]; then proxy_args=(-J "$proxy_user@$proxy_host") fi # shellcheck disable=SC2207 local common_opts=($(ssh_common_opts "$ssh_user" "$ssh_host")) ssh -i "$ssh_key" \ "${common_opts[@]}" \ "${proxy_args[@]}" \ "$ssh_user@$ssh_host" "$@" } scp_copy() { local ssh_key="$1" local src="$2" local ssh_user="$3" local ssh_host="$4" local dst="$5" local recursive="${6:-false}" require_ssh_key "$ssh_key" local proxy_host="${DEPLOY_SSH_PROXY_HOST:-}" local proxy_user="${DEPLOY_SSH_PROXY_USER:-$ssh_user}" local proxy_args=() if [[ -n "$proxy_host" ]]; then proxy_args=(-o "ProxyJump=$proxy_user@$proxy_host") fi # shellcheck disable=SC2207 local common_opts=($(ssh_common_opts "$ssh_user" "$ssh_host")) local scp_opts=() # Add -r for recursive copy if requested or if source is a directory if [[ "$recursive" == "true" ]] || [[ -d "$src" ]]; then scp_opts=(-r) fi scp -i "$ssh_key" \ "${scp_opts[@]}" \ "${common_opts[@]}" \ "${proxy_args[@]}" \ "$src" "$ssh_user@$ssh_host:$dst" }