Docker.Container.js
JavaScript source for A Docker module for Node.js, 160 lines. Raw file
const Security = require('Security');
const Docker =
{
Daemon: require('./Docker.Daemon'),
Container:
{
Command: (containerName, command) => {
containerName = Security.String(containerName)
command = Security.String(command)
// const containerId = Docker.Container.ID(containerName)
const commandArray = ['exec', containerName, command]
return Docker.Daemon.Execute(commandArray)
},
/**
* Gets the ID of the container based on the container name
*
* @param string containerName
* @returns int
* @throws Error if the container is not found or there are multiple with the same name
*/
ID: ( containerName ) =>
{
containerName = Security.String(containerName)
const command = [`container`, `ls`, `-a`, `-q`, `-f`, `name=${containerName}`];
return Docker.Daemon.Execute(command, (input) => {
if (input.trim() === '') {
throw new Error("Container not found: '" + containerName + "'")
}
const lines = input.trim().split('\n')
const regExp = /^[a-f0-9A-F]+$/;
const linesAreHashes = lines.map(line => regExp.test(line.trim()))
const allLinesAreHashes = linesAreHashes.reduce((a, b) => a && b)
if (allLinesAreHashes) {
if (lines.length === 1) {
return lines[0].trim()
} else {
throw new Error("Multiple containers with the same name: '" + containerName + "'")
}
} else {
throw new Error("Unexpected output from docker container ls: '" + input + "'")
}
})
},
/**
* Starts a container
*
* @param imageName string
* @param containerName string
* @param extraArguments string
* @returns string
* @throws Error if the container could not be started
*/
Start: (imageName, containerName, extraArguments) =>
{
imageName = Security.String(imageName)
containerName = Security.String(containerName)
extraArguments = Security.Array(Security.String)(extraArguments)
const command = [`run`, `-itd`, ...extraArguments, `--name ${containerName}`, `${imageName}:latest`];
const containerId = Docker.Daemon.Execute( command, (input) => {
const [hashToCompare] = Docker.Daemon.SplitOutput( input )
const regExp = /\b([a-f0-9]{64})\b/
if (!regExp.test(hashToCompare.trim())) {
throw new Error("Invalid hash format: '"+input+"'")
}
return hashToCompare;
})
if (!containerId) {
throw new Error("Unable to start container")
}
return containerId;
},
Stop: (containerName) =>
{
containerName = Security.String(containerName)
if( Docker.Container.Exists( containerName ) ) {
const containerId = Docker.Container.ID( containerName )
const command = [`stop`, containerId];
const parsingCb = (input) => input.toLowerCase().trim() === containerId;
const hasStopped = Docker.Daemon.Execute( command, parsingCb )
if (!hasStopped) {
throw new Error("Unable to delete container")
}
}
},
Remove: (containerName) =>
{
containerName = Security.String(containerName)
if( Docker.Container.Exists(containerName) ) {
const containerId = Docker.Container.ID( containerName )
const command = [`rm`, containerId];
const parsingCb = (input) => {
if (input.toLowerCase().trim() !== containerId) {
throw new Error("Unable to delete container")
}
};
Docker.Daemon.Execute( command, parsingCb )
}
},
Exists: (containerName, isRunning=false) =>
{
containerName = Security.String(containerName)
const command = isRunning
? [`container`, `ls`, `-q`, `-f`, `name=${containerName}`]
: [`container`, `ls`, `-a`, `-q`, `-f`, `name=${containerName}`];
return Docker.Daemon.Execute(command, (input) => {
if( input.trim() === '' ) {
return false;
}
const lines = input.trim().split('\n')
const regExp = /^[a-f0-9A-F]+$/;
const linesAreHashes = lines.map( line => regExp.test(line.trim()) )
const allLinesAreHashes = linesAreHashes.reduce( (a,b) => a && b )
if( allLinesAreHashes ) {
return true;
}
else {
throw new Error("Unexpected output from docker images: '" + input + "'")
}
})
},
Logs: (containerName) => {
containerName = Security.String(containerName)
const command = [`logs`, '-f', containerName];
return Docker.Daemon.Execute(command)
}
}
}
module.exports = Docker.Container