import { createSshConnection , SshConnection } from "ssh-remote-port-forward" ; import { log } from "./logger" ; import { GenericContainer } from "./generic-container/generic-container" ; import { Port } from "./port" ; import { StartedTestContainer } from "./test-container" ; import { RandomUuid } from "./uuid" ; import { sessionId } from "./docker/session-id" ; import { dockerClient } from "./docker/docker-client" ; import { SSHD_IMAGE } from "./images" ; export class PortForwarder { constructor ( private readonly sshConnection , private readonly container ) { } public async exposeHostPort ( port ) { log . info ( `Exposing host port ${ port }` ) ; await this . sshConnection . remoteForward ( "localhost" , port ) ; } public getNetworkId ( ) { return this . container . getNetworkId ( this . getNetworkName ( ) ) ; } public getIpAddress ( ) { return this . container . getIpAddress ( this . getNetworkName ( ) ) ; } private getNetworkName ( ) { return this . container . getNetworkNames ( ) [ 0 ] ; } } export class PortForwarderInstance { private static instance : Promise < PortForwarder > ; public static isRunning ( ) { return this . instance !== undefined ; } public static async getInstance ( ) { if ( ! this . instance ) { this . instance = this . createInstance ( ) ; } return this . instance ; } private static async createInstance ( ) { log . debug ( `Creating new Port Forwarder` ) ; const username = "root" ; const password = new RandomUuid ( ) . nextUuid ( ) ; const container = await new GenericContainer ( SSHD_IMAGE ) . withName ( `testcontainers-port-forwarder-${ sessionId }` ) . withExposedPorts ( 22 ) . withEnv ( "PASSWORD" , password ) . withCmd ( [ "sh" , "-c" , `echo "${ username }:$PASSWORD" | chpasswd && /usr/sbin/sshd -D -o PermitRootLogin=yes -o AddressFamily=inet -o GatewayPorts=yes` , ] ) . start ( ) ; const host = ( await dockerClient ) . host ; const port = container . getMappedPort ( 22 ) ; log . debug ( `Connecting to Port Forwarder on ${ host }:${ port }` ) ; const connection = await createSshConnection ( { host , port , username , password } ) ; connection . unref ( ) ; return new PortForwarder ( connection , container ) ; } }