* Connect to a single SSH host.
(
hostInfo: { host: string; port: number; username: string },
password: string | undefined,
privateKey: Buffer | undefined,
passphrase: string | undefined,
sock: Duplex | undefined,
label: string | undefined,
keepaliveInterval?: number,
keepaliveCountMax?: number
)
| 169 | * Connect to a single SSH host. |
| 170 | */ |
| 171 | private connectToHost( |
| 172 | hostInfo: { host: string; port: number; username: string }, |
| 173 | password: string | undefined, |
| 174 | privateKey: Buffer | undefined, |
| 175 | passphrase: string | undefined, |
| 176 | sock: Duplex | undefined, |
| 177 | label: string | undefined, |
| 178 | keepaliveInterval?: number, |
| 179 | keepaliveCountMax?: number |
| 180 | ): Promise<Client> { |
| 181 | return new Promise((resolve, reject) => { |
| 182 | const client = new Client(); |
| 183 | |
| 184 | const sshConfig: ConnectConfig = { |
| 185 | host: hostInfo.host, |
| 186 | port: hostInfo.port, |
| 187 | username: hostInfo.username, |
| 188 | }; |
| 189 | |
| 190 | if (password) { |
| 191 | sshConfig.password = password; |
| 192 | } |
| 193 | if (privateKey) { |
| 194 | sshConfig.privateKey = privateKey; |
| 195 | if (passphrase) { |
| 196 | sshConfig.passphrase = passphrase; |
| 197 | } |
| 198 | } |
| 199 | if (sock) { |
| 200 | sshConfig.sock = sock; |
| 201 | } |
| 202 | if (keepaliveInterval !== undefined) { |
| 203 | if (Number.isNaN(keepaliveInterval) || keepaliveInterval < 0) { |
| 204 | const desc = label || `${hostInfo.host}:${hostInfo.port}`; |
| 205 | console.warn( |
| 206 | `Invalid SSH keepaliveInterval (${keepaliveInterval}) for ${desc}; ` + |
| 207 | 'keepalive configuration will be ignored.' |
| 208 | ); |
| 209 | } else if (keepaliveInterval > 0) { |
| 210 | sshConfig.keepaliveInterval = keepaliveInterval * 1000; // Convert seconds to milliseconds |
| 211 | sshConfig.keepaliveCountMax = keepaliveCountMax ?? 3; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | const onError = (err: Error) => { |
| 216 | client.removeListener('ready', onReady); |
| 217 | client.destroy(); |
| 218 | reject(new Error(`SSH connection error${label ? ` (${label})` : ''}: ${err.message}`)); |
| 219 | }; |
| 220 | |
| 221 | const onReady = () => { |
| 222 | client.removeListener('error', onError); |
| 223 | const desc = label || `${hostInfo.host}:${hostInfo.port}`; |
| 224 | console.error(`SSH connection established: ${desc}`); |
| 225 | resolve(client); |
| 226 | }; |
| 227 | |
| 228 | client.on('error', onError); |