import Docker from 'dockerode' ; import { containerExec , imageExists , pullImageAsync } from 'dockerode-utils' ; import path from 'path' ; const CONTAINER_IMAGE = 'postgres:11.5-alpine' ; const CONTAINER_TEMP_DIR = '/tmp' ; const CONTAINER_NAME = 'cardano-test' ; export const removePostgresContainer = async ( ) : Promise < void > => { const docker = new Docker ( ) ; const container = await docker . getContainer ( CONTAINER_NAME ) ; await container . stop ( ) ; await container . remove ( { v : true } ) ; } ; interface DatabaseConfig { database : string ; snapshot : boolean ; fixture : boolean ; } const setupDBData = async ( databaseConfig , user , container ) => { const database = databaseConfig . database ; await containerExec ( container , [ 'bash' , '-c' , `psql -U ${ user } -c "CREATE DATABASE ${ database }"` ] ) ; if ( databaseConfig . snapshot ) { await container . putArchive ( path . join ( __dirname , `${ database }-db-snapshot.tar` ) , { path : CONTAINER_TEMP_DIR , User : 'root' } ) ; await containerExec ( container , [ 'bash' , '-c' , `cat ${ CONTAINER_TEMP_DIR }/${ database }.bak | psql -U ${ user } ${ database }` ] ) ; } if ( databaseConfig . fixture ) { await container . putArchive ( path . join ( __dirname , `${ database }-fixture-data.tar` ) , { path : CONTAINER_TEMP_DIR , User : 'root' } ) ; await containerExec ( container , [ 'bash' , '-c' , `cat ${ CONTAINER_TEMP_DIR }/${ database }-fixture-data.sql | psql -U ${ user } ${ database }` ] ) ; } } ; export const setupPostgresContainer = async ( user , password , port ) : Promise < void > => { const docker = new Docker ( ) ; const needsToPull = ! ( await imageExists ( docker , CONTAINER_IMAGE ) ) ; if ( needsToPull ) await pullImageAsync ( docker , CONTAINER_IMAGE ) ; const container = await docker . createContainer ( { Image : CONTAINER_IMAGE , Env : [ `POSTGRES_PASSWORD=${ password }` , `POSTGRES_USER=${ user }` ] , HostConfig : { PortBindings : { '5432/tcp' : [ { HostPort : port } ] } } , name : CONTAINER_NAME } ) ; await container . start ( ) ; await containerExec ( container , [ 'bash' , '-c' , `until psql -U ${ user } -c "select 1" > /dev/null 2>&1 ; do sleep 1; done` ] ) ; const databaseConfigs = [ { snapshot : true , fixture : true , database : 'mainnet' } ] ; for ( const databaseConfig of databaseConfigs ) { await setupDBData ( databaseConfig , user , container ) ; } } ;