const { exec } = require('child_process')
const fs = require('fs')
const { nanoid } = require('nanoid')
const { logInfo, logError } = require('../log')
/**
* @class
*/
class DockerService {
static createDockerNetworkForContainerManagerServer(platformConfig) {
logInfo({ message: '[DockerService] Creating docker network for comunication between containers' })
exec(`sudo docker network create ${platformConfig.ciDockerNetworkName}`)
}
static stopContainer(deploymentRequest) {
const name = deploymentRequest.image.replaceAll('/', '_')
logInfo({ message: `Running docker stop for image with the name of ${name}` })
return `sudo docker stop ${name} ||`
}
static startContainer(platformConfig, { image, containerPort, hostPort, registry, env }) {
const name = image.replaceAll('/', '_')
const imageUrl = !!registry ? `${registry}/${image}` : image
const envsAsString = Object.entries(env || {}).reduce((envs, [name, value]) => `${envs} --env ${name}=${value}`, '')
logInfo({ message: `Running docker start for image with the name of ${name} with port mapping ${hostPort}:${containerPort} and source ${imageUrl}` })
return `sudo docker run -d -p ${hostPort}:${containerPort} --name=${name} --network=${platformConfig.ciDockerNetworkName} --network-alias=${name} --rm ${envsAsString} ${imageUrl}`
}
static resolveCredentials({ registry, username, authentication }) {
const shouldAuthenticate = username || authentication
if (!shouldAuthenticate) {
logInfo({ message: 'No docker credentials provided, assuming image is publicly hosted' })
return ''
}
logInfo({ message: `Resolving docker credentials for ${registry}` })
return `sudo docker login ${registry} -u ${username} -p ${authentication}`
}
static deploy(platformConfig, deploymentRequest) {
return new Promise(resolve => {
logInfo({ message: 'Starting docker deployment sequence' })
const dockerCommandScript = `'#!/bin/bash'
${DockerService.stopContainer(deploymentRequest)}
${DockerService.resolveCredentials(deploymentRequest)}
${DockerService.startContainer(platformConfig, deploymentRequest)}`
const deploymentId = nanoid()
const FilePaths = {
DeploymentScript: `${__dirname}/${deploymentId}.sh`
}
fs.writeFileSync(FilePaths.DeploymentScript, dockerCommandScript)
const command = exec(`bash ${FilePaths.DeploymentScript}`)
command.stdout.on('data', data => {
logInfo({ message: `[DockerService]: ${data}` })
})
command.stderr.on('data', (data) => {
logError({ message: `[DockerService]: ${data}` })
})
command.on('close', code => {
logInfo({ message: `[DockerService] command exited with code ${code}` })
fs.unlinkSync(FilePaths.DeploymentScript)
resolve()
})
})
}
}
module.exports = {
DockerService
}