Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker registry credentials #89

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ libraryDependencies ++= Seq(

scalacOptions := Seq("-deprecation", "-unchecked", "-feature")

crossScalaVersions := Seq("2.10.6", "2.12.2")
crossSbtVersions := Seq("0.13.16", "1.0.0")

licenses := Seq("MIT License" -> url("https://github.com/marcuslonnberg/sbt-docker/blob/master/LICENSE"))
homepage := Some(url("https://github.com/marcuslonnberg/sbt-docker"))
scmInfo := Some(ScmInfo(url("https://github.com/marcuslonnberg/sbt-docker"), "scm:git:git://github.com:marcuslonnberg/sbt-docker.git"))
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/sbtdocker/DockerKeys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ object DockerKeys {
val imageNames = taskKey[Seq[ImageName]]("Names of the built image.")
val dockerPath = settingKey[String]("Path to the Docker binary.")
val buildOptions = settingKey[BuildOptions]("Options for the Docker build command.")

val dockerRegistryCredentials = settingKey[Option[DockerRegistryCredentials]]("Credentials to Docker Registry")
}
45 changes: 33 additions & 12 deletions src/main/scala/sbtdocker/DockerPush.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ import sbt._
import scala.sys.process.{Process, ProcessLogger}

object DockerPush {

val processLog: Logger => ProcessLogger = log => ProcessLogger({ line =>
log.info(line)
}, { line =>
log.info(line)
})

/**
* Push Docker images to a registry.
*
* @param dockerPath path to the docker binary
* @param imageNames names of the images to push
* @param log logger
*/
def apply(dockerPath: String, imageNames: Seq[ImageName], log: Logger): Unit = {
def apply(dockerPath: String, imageNames: Seq[ImageName], log: Logger, dockerRegistryCredentials: Option[DockerRegistryCredentials] = None): Unit = {
imageNames.foreach { imageName =>
apply(dockerPath, imageName, log)
apply(dockerPath, imageName, log, dockerRegistryCredentials)
}
}

Expand All @@ -25,20 +32,34 @@ object DockerPush {
* @param imageName name of the image to push
* @param log logger
*/
def apply(dockerPath: String, imageName: ImageName, log: Logger): Unit = {
def apply(dockerPath: String, imageName: ImageName, log: Logger, dockerRegistryCredentials: Option[DockerRegistryCredentials]): Unit = {
log.info(s"Pushing docker image with name: '$imageName'")
dockerRegistryCredentials.map(login).foreach(_(dockerPath, log))
val command = dockerPath :: "push" :: imageName.toString :: Nil
runCommand(command)("Failed to push", log)
dockerRegistryCredentials.map(logout).foreach(_(dockerPath, log))
}

val processLog = ProcessLogger({ line =>
log.info(line)
}, { line =>
log.info(line)
})
private def login(dockerRegistryCredentials: DockerRegistryCredentials): (String, Logger) => Unit = (dockerPath, log) => {
log.info(s"Login to docker registry")
val command = dockerPath :: "login" ::
"-u" :: dockerRegistryCredentials.username ::
"-p" :: dockerRegistryCredentials.password ::
dockerRegistryCredentials.url :: Nil
runCommand(command)("Failed to login", log)
}

val command = dockerPath :: "push" :: imageName.toString :: Nil
log.debug(s"Running command: '${command.mkString(" ")}'")
private def logout(dockerRegistryCredentials: DockerRegistryCredentials): (String, Logger) => Unit = (dockerPath, log) => {
log.info(s"Logout from docker registry")
val command = dockerPath :: "logout" ::
dockerRegistryCredentials.url :: Nil
runCommand(command)("Failed to logout", log)
}

private def runCommand(command: Seq[String]): (String, Logger) => Unit = (errorMsg, log) => {
log.debug(s"Running command: '${command.mkString(" ")}'")
val process = Process(command)
val exitValue = process ! processLog
if (exitValue != 0) sys.error("Failed to push")
val exitValue = process ! processLog(log)
if (exitValue != 0) sys.error(errorMsg)
}
}
7 changes: 4 additions & 3 deletions src/main/scala/sbtdocker/DockerSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ object DockerSettings {
val log = Keys.streams.value.log
val dockerPath = (DockerKeys.dockerPath in docker).value
val imageNames = (DockerKeys.imageNames in docker).value

DockerPush(dockerPath, imageNames, log)
val dockerRegistryCredentials = (DockerKeys.dockerRegistryCredentials in docker).value
DockerPush(dockerPath, imageNames, log, dockerRegistryCredentials)
},
dockerBuildAndPush := Def.taskDyn {
val id = docker.value
Expand Down Expand Up @@ -51,7 +51,8 @@ object DockerSettings {
Seq((imageName in docker).value)
},
dockerPath in docker := sys.env.get("DOCKER").filter(_.nonEmpty).getOrElse("docker"),
buildOptions in docker := BuildOptions()
buildOptions in docker := BuildOptions(),
dockerRegistryCredentials in docker := None
)

def autoPackageJavaApplicationSettings(
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/sbtdocker/models.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,5 @@ case class ImageName(
@deprecated("Use toString instead.", "0.4.0")
def name = toString
}

case class DockerRegistryCredentials(url: String, username: String, password: String)