Last active
August 29, 2015 14:23
-
-
Save tkawachi/7c2d2a81a84dec763723 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.charset.Charset | |
import java.text.SimpleDateFormat | |
import java.util.Date | |
import com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalkClient | |
import com.amazonaws.services.elasticbeanstalk.model.{UpdateEnvironmentRequest, S3Location, CreateApplicationVersionRequest} | |
import com.amazonaws.services.s3.AmazonS3Client | |
import com.amazonaws.services.s3.model.Region | |
import com.typesafe.sbt.packager.docker.DockerPlugin | |
import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport.{Docker, dockerExposedPorts} | |
import com.typesafe.sbt.packager.universal.UniversalPlugin | |
import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.{stage, stagingDirectory} | |
import play.sbt.Play | |
import play.sbt.PlayImport.PlayKeys | |
import sbt._, Keys._ | |
object EbDockerPlugin extends AutoPlugin { | |
object autoImport { | |
val EbDocker = config("ebdocker") extend Docker | |
val ebDockerContainerPort = settingKey[Int]("Container port for Elastic beanstalk with Docker") | |
val ebDockerrunVersion = settingKey[Int]("AWSEBDockerrunVersion in Dockerrun.aws.json") | |
val ebDockerOutputFile = settingKey[File]("Output file of Elastic beanstalk with Docker") | |
val ebDockerVersionLabel = taskKey[String]("Create a version label") | |
val ebDockerApplicationName = settingKey[String]("Elastic beanstalk with Docker application name") | |
val ebDockerS3Bucket = settingKey[String]("S3 bucket name to store Elastic beanstalk application files") | |
val ebDockerEnvironmentId = settingKey[Option[String]]("Elastic beanstalk Environment Id to deploy") | |
val ebDockerRegion = settingKey[Region]("Elastic beanstalk region") | |
} | |
import autoImport._ | |
override def requires = Play && DockerPlugin && UniversalPlugin | |
override def trigger = allRequirements | |
final val ChangeMe: String = "ChangeMe" | |
val ebDockerDefaultSettings = Seq( | |
ebDockerContainerPort := PlayKeys.playDefaultPort.value, | |
dockerExposedPorts := (dockerExposedPorts.value :+ ebDockerContainerPort.value).distinct, | |
ebDockerOutputFile := target.value / (name.value + "-" + version.value + ".zip"), | |
ebDockerApplicationName := ChangeMe, | |
ebDockerS3Bucket := ChangeMe, | |
ebDockerEnvironmentId := None, | |
ebDockerRegion := Region.US_Standard, | |
packageBin in EbDocker := { | |
// run docker:stage | |
(stage in Docker).value | |
val stageDir = (stagingDirectory in Docker).value | |
// Write Dockerrun.aws.json | |
writeDockerrunAwsJson(ebDockerrunVersion.value, ebDockerContainerPort.value, stageDir) | |
// Create a zip file | |
// Using an external zip command. | |
val zipFile: File = ebDockerOutputFile.value | |
val zipContents: Array[String] = stageDir.listFiles().flatMap(_.relativeTo(stageDir)).map(_.toString) | |
Process(Seq("zip", "-q", "-r", zipFile.absolutePath) ++ zipContents, stageDir) ! streams.value.log | |
val printPath = zipFile.relativeTo(baseDirectory.value).getOrElse(zipFile.absolutePath) | |
streams.value.log.info(s"Upload $printPath to Elastic beanstalk") | |
zipFile | |
}, | |
Keys.`package` in EbDocker := (packageBin in EbDocker).value, | |
ebDockerVersionLabel := { | |
val fmt = new SimpleDateFormat("yyyyMMddHHmmss") | |
val now = new Date() | |
val nowString = fmt.format(now) | |
val gitTag = | |
(Process(Seq("git", "describe", "--always"), baseDirectory.value) !! streams.value.log) | |
.stripLineEnd | |
Seq(gitTag, nowString).mkString("_") | |
}, | |
publish in EbDocker := { | |
val zipFile: File = (packageBin in EbDocker).value | |
val versionLabel: String = ebDockerVersionLabel.value | |
val s3Key = s"$versionLabel/${zipFile.name}" | |
val s3Client = new AmazonS3Client() | |
s3Client.putObject(ebDockerS3Bucket.value, s3Key, zipFile) | |
val ebClient = new AWSElasticBeanstalkClient() | |
ebClient.withRegion(ebDockerRegion.value.toAWSRegion) | |
val createRequest = new CreateApplicationVersionRequest() | |
.withApplicationName(ebDockerApplicationName.value) | |
.withVersionLabel(versionLabel) | |
.withSourceBundle(new S3Location(ebDockerS3Bucket.value, s3Key)) | |
ebClient.createApplicationVersion(createRequest) | |
streams.value.log.info(s"Published as version $versionLabel") | |
ebDockerEnvironmentId.value.foreach { envId => | |
val updateRequest = new UpdateEnvironmentRequest() | |
.withEnvironmentId(envId) | |
.withVersionLabel(versionLabel) | |
ebClient.updateEnvironment(updateRequest) | |
streams.value.log.info(s"Environment $envId has been updated to $versionLabel") | |
} | |
}, | |
ebDockerrunVersion := 1 | |
) | |
override lazy val projectSettings = ebDockerDefaultSettings | |
private def writeDockerrunAwsJson(ebDockerrunVersion: Int, ebContainerPort: Int, stagingDir: File): Unit = { | |
val json = | |
s"""{ | |
| "AWSEBDockerrunVersion": "$ebDockerrunVersion", | |
| "Ports": [{ | |
| "ContainerPort": "$ebContainerPort" | |
| }] | |
|} | |
|""".stripMargin | |
val dockerrun: File = new File(stagingDir, "Dockerrun.aws.json") | |
IO.write(dockerrun, json, Charset.forName("UTF-8")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment