2016-07-18 18:48:34 +00:00
import * as plugins from "./npmdocker.plugins" ;
import * as paths from "./npmdocker.paths" ;
2016-07-18 22:59:57 +00:00
import * as snippets from "./npmdocker.snippets" ;
2016-07-19 22:40:37 +00:00
import { npmdockerOra } from "./npmdocker.promisechain" ;
2016-07-18 22:59:57 +00:00
let config ;
2016-07-19 17:21:06 +00:00
let dockerData = {
imageTag : "npmdocker-temp-image:latest" ,
2016-07-19 22:40:37 +00:00
containerName : "npmdocker-temp-container"
2016-07-19 17:21:06 +00:00
} ;
2016-07-19 22:40:37 +00:00
2016-07-18 18:48:34 +00:00
/ * *
* check if docker is available
* /
2016-07-18 22:59:57 +00:00
let checkDocker = ( ) = > {
2016-07-18 18:48:34 +00:00
let done = plugins . q . defer ( ) ;
2016-07-19 22:40:37 +00:00
npmdockerOra . text ( "checking docker..." ) ;
2016-07-18 18:48:34 +00:00
if ( plugins . shelljs . which ( "docker" ) ) {
2016-07-19 17:21:06 +00:00
plugins . beautylog . ok ( "Docker found!" )
2016-07-18 22:59:57 +00:00
done . resolve ( ) ;
2016-07-18 18:48:34 +00:00
} else {
done . reject ( new Error ( "docker not found on this machine" ) ) ;
}
return done . promise ;
} ;
2016-07-18 22:37:13 +00:00
/ * *
* builds the Dockerfile according to the config in the project
* /
let buildDockerFile = ( ) = > {
let done = plugins . q . defer ( ) ;
2016-07-19 22:40:37 +00:00
npmdockerOra . text ( "building Dockerfile..." ) ;
2016-07-19 17:21:06 +00:00
let dockerfile :string = snippets . dockerfileSnippet ( {
2016-07-18 22:59:57 +00:00
baseImage :config.baseImage ,
command :config.command
} ) ;
2016-07-19 17:21:06 +00:00
plugins . beautylog . info ( ` Base image is: ${ config . baseImage } ` ) ;
plugins . beautylog . info ( ` Command is: ${ config . command } ` ) ;
plugins . smartfile . memory . toFsSync ( dockerfile , paths . dockerfile ) ;
plugins . beautylog . ok ( "Dockerfile created!" ) ;
done . resolve ( ) ;
2016-07-18 22:37:13 +00:00
return done . promise
} ;
/ * *
* builds the Dockerimage from the built Dockerfile
* /
let buildDockerImage = ( ) = > {
let done = plugins . q . defer ( ) ;
2016-07-19 22:40:37 +00:00
npmdockerOra . text ( "pulling latest base image from registry..." ) ;
2016-07-19 17:21:06 +00:00
plugins . shelljs . exec ( ` docker pull ${ config . baseImage } ` , {
silent :true
} , ( ) = > {
2016-07-19 22:40:37 +00:00
npmdockerOra . text ( "building Dockerimage..." ) ;
2016-07-28 22:52:30 +00:00
// are we creating a build context form project ?
if ( process . env . CI == "true" ) {
npmdockerOra . text ( "creating build context..." ) ;
plugins . smartfile . fs . copySync ( paths . cwd , paths . buildContextDir ) ;
}
2016-07-19 22:40:37 +00:00
plugins . shelljs . exec ( ` docker build -f ${ paths . dockerfile } -t ${ dockerData . imageTag } ${ paths . assets } ` , {
silent :true
} , ( ) = > {
plugins . beautylog . ok ( "Dockerimage built!" )
done . resolve ( ) ;
} ) ;
} ) ; // first pull latest version of baseImage
2016-07-18 22:37:13 +00:00
return done . promise
} ;
/ * *
* creates a container by running the built Dockerimage
* /
let runDockerImage = ( ) = > {
let done = plugins . q . defer ( ) ;
2016-07-19 22:40:37 +00:00
npmdockerOra . text ( "starting Container..." ) ;
npmdockerOra . end ( ) ;
2016-07-28 22:52:30 +00:00
// Are we mounting the project directory?
let dockerProjectMountString :string = "" ;
if ( process . env . CI != "true" ) {
dockerProjectMountString = ` -v ${ paths . cwd } :/workspace `
} ;
// Are we mounting docker.sock?
2016-07-28 16:01:02 +00:00
let dockerSockString :string = "" ;
if ( config . dockerSock ) {
dockerSockString = ` -v /var/run/docker.sock:/var/run/docker.sock `
} ;
2016-07-29 20:00:22 +00:00
plugins . beautylog . log ( "now running Dockerimage" ) ;
2016-07-28 22:52:30 +00:00
config . exitCode = plugins . shelljs . exec ( ` docker run ${ dockerProjectMountString } ${ dockerSockString } --name ${ dockerData . containerName } ${ dockerData . imageTag } ` ) . code ;
2016-07-19 17:21:06 +00:00
done . resolve ( ) ;
return done . promise ;
2016-07-18 22:37:13 +00:00
} ;
2016-07-29 20:00:22 +00:00
let deleteDockerContainer = ( ) = > {
2016-07-18 22:37:13 +00:00
let done = plugins . q . defer ( ) ;
2016-07-19 17:21:06 +00:00
plugins . shelljs . exec ( ` docker rm ${ dockerData . containerName } ` , {
silent :true
} ) ;
done . resolve ( ) ;
2016-07-18 22:37:13 +00:00
return done . promise
} ;
let deleteDockerImage = ( ) = > {
let done = plugins . q . defer ( ) ;
2016-07-19 17:21:06 +00:00
plugins . shelljs . exec ( ` docker rmi ${ dockerData . imageTag } ` , {
silent :true
} ) ;
2016-07-28 22:52:30 +00:00
done . resolve ( ) ;
2016-07-18 22:37:13 +00:00
return done . promise
} ;
2016-07-28 22:52:30 +00:00
let deleteBuildContext = ( ) = > {
let done = plugins . q . defer ( ) ;
2016-07-29 20:00:22 +00:00
plugins . smartfile . fs . remove ( paths . buildContextDir )
. then ( done . resolve ) ;
2016-07-28 22:52:30 +00:00
return done . promise ;
2016-07-29 20:00:22 +00:00
} ;
let preClean = ( ) = > {
let done = plugins . q . defer ( ) ;
deleteDockerImage ( )
. then ( deleteDockerContainer )
. then ( ( ) = > {
plugins . beautylog . ok ( "ensured clean Docker environment!" ) ;
done . resolve ( ) ;
} ) ;
} ;
let postClean = ( ) = > {
let done = plugins . q . defer ( ) ;
deleteDockerContainer ( )
. then ( deleteDockerImage )
. then ( deleteBuildContext )
. then ( ( ) = > {
plugins . beautylog . ok ( "cleaned up!" ) ;
done . resolve ( ) ;
} ) ;
2016-07-28 22:52:30 +00:00
}
2016-07-18 22:37:13 +00:00
export let run = ( configArg ) = > {
let done = plugins . q . defer ( ) ;
2016-07-18 22:59:57 +00:00
config = configArg ;
checkDocker ( )
2016-07-29 20:00:22 +00:00
. then ( preClean )
2016-07-18 22:37:13 +00:00
. then ( buildDockerFile )
. then ( buildDockerImage )
. then ( runDockerImage )
2016-07-29 20:00:22 +00:00
. then ( postClean )
2016-07-18 22:59:57 +00:00
. then ( ( ) = > {
2016-07-19 22:40:37 +00:00
done . resolve ( config ) ;
2016-07-18 22:59:57 +00:00
} )
2016-07-18 22:37:13 +00:00
return done . promise ;
}