Skip to content

Instantly share code, notes, and snippets.

@outofcoffee
Created August 26, 2017 20:34
Show Gist options
  • Save outofcoffee/8487806a8d2f0b888590a6ff557492d0 to your computer and use it in GitHub Desktop.
Save outofcoffee/8487806a8d2f0b888590a6ff557492d0 to your computer and use it in GitHub Desktop.
Build, tag and push containers (with AWS ECR support)
#!/usr/bin/env groovy
import groovy.json.JsonSlurper
class Constants {
final static def REPOSITORY_PREFIX = ""
final static def REGISTRY_PREFIX = "your-docker-hub-id/"
final static def ECR_REGION = "eu-west-1"
}
final imageConfig = new JsonSlurper().parseText(new File("./containers.json").text)
def parseArguments() {
def cli = new CliBuilder(usage: 'containers.groovy [options]')
cli.h(required: false, longOpt: 'help', 'help/usage')
cli.el(required: false, longOpt: 'ecr-login', 'whether to login to ECR')
cli.le(required: false, longOpt: 'login-email', 'whether to login to ECR with email flag (docker < 17.06)')
cli.i(required: false, longOpt: 'image', args: 1, 'only build this image. excludes -g')
cli.g(required: false, longOpt: 'group', args: 1, 'only build this group of images')
cli.t(required: false, longOpt: 'tag', args: 1, 'the Docker image tag')
cli.stopAtNonOption = false
def options = cli.parse(args)
if (!options) {
System.exit(1)
} else if (options.h) {
cli.usage()
System.exit(0)
}
options
}
class ImageBuilder {
String imageTag
String loginArgs
String exec(String command, boolean followOutput = false) {
def commandElements = command.replaceAll("[\\r\\n]*", "").split("\\s+")
def procBuilder = new ProcessBuilder(commandElements).redirectErrorStream(true)
if (followOutput) procBuilder.inheritIO()
def proc = procBuilder.start()
if (0 != proc.waitFor()) throw new RuntimeException(proc.text) else proc.text
}
void login() {
println "\nLogging in to ECR"
def loginCommand = exec("aws ecr get-login ${loginArgs} --region ${Constants.ECR_REGION}")
exec(loginCommand, true)
}
void buildTagPush(imageName, buildPath, dockerFile, buildArgs) {
println "\nBuilding ${imageName} image"
def dockerBuildPath = dockerFile ? "--file ${buildPath}/${dockerFile}" : ""
def args = buildArgs?.collect { "--build-arg ${it.key}=${it.value}" }?.join(" ") ?: ""
exec("docker build ${args} --tag ${Constants.REPOSITORY_PREFIX}${imageName}:${imageTag} ${dockerBuildPath} ${buildPath}", true)
println "\nTagging and pushing ${imageName}"
exec("""docker tag
${Constants.REPOSITORY_PREFIX}${imageName}:${imageTag}
${Constants.REGISTRY_PREFIX}${Constants.REPOSITORY_PREFIX}${imageName}:${imageTag}""", true)
exec("""docker push
${Constants.REGISTRY_PREFIX}${Constants.REPOSITORY_PREFIX}${imageName}:${imageTag}""", true)
}
}
def options = parseArguments()
def imageBuilder = new ImageBuilder(
imageTag: options.t ?: "latest",
loginArgs: options.le ? "" : "--no-include-email"
)
List<Map> filtered
if (options.i) {
filtered = [imageConfig.find { it.imageName == options.i }]
} else {
filtered = imageConfig.findAll { options.g && it.groups ? it.groups.contains(options.g) : !options.g }
}
println "Building ${filtered.size()} image(s)"
if (!filtered.isEmpty()) {
if (options.el) imageBuilder.login()
filtered.each { imageBuilder.buildTagPush(it.imageName, it.buildPath, it.dockerFile, it.buildArgs) }
}
[
{
"imageName": "service1",
"buildPath": "service1"
},
{
"imageName": "service2",
"buildPath": "service2",
"buildArgs": {
"foo": "bar"
},
"dockerFile": "Dockerfile.dev"
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment