From bd7083167c1a0899f722971fb90ce41c96de252f Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Mon, 6 Mar 2017 01:47:50 -0800 Subject: scalafmt --- .../src/main/scala/io/crashbox/ci/Builders.scala | 124 ++++++++++++--------- .../src/main/scala/io/crashbox/ci/Core.scala | 5 +- .../src/main/scala/io/crashbox/ci/Main.scala | 6 +- .../src/main/scala/io/crashbox/ci/Parsers.scala | 16 ++- .../src/main/scala/io/crashbox/ci/Schedulers.scala | 68 ++++++----- .../src/main/scala/io/crashbox/ci/Source.scala | 11 +- .../src/main/scala/io/crashbox/ci/StateStore.scala | 6 +- .../main/scala/io/crashbox/ci/StreamStore.scala | 15 ++- .../src/test/scala/io/crashbox/ci/SourceSpec.scala | 5 +- .../src/test/scala/io/crashbox/ci/TestUtil.scala | 5 +- 10 files changed, 153 insertions(+), 108 deletions(-) diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Builders.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Builders.scala index 7e55640..6bd4816 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Builders.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Builders.scala @@ -1,11 +1,18 @@ package io.crashbox.ci -import com.spotify.docker.client.DockerClient.{ AttachParameter, ListContainersParam } +import com.spotify.docker.client.DockerClient.{ + AttachParameter, + ListContainersParam +} import com.spotify.docker.client.LogStream import com.spotify.docker.client.exceptions.ContainerNotFoundException -import com.spotify.docker.client.messages.{ ContainerConfig, HostConfig, LogConfig } +import com.spotify.docker.client.messages.{ + ContainerConfig, + HostConfig, + LogConfig +} import com.spotify.docker.client.messages.HostConfig.Bind -import java.io.{ File, OutputStream } +import java.io.{File, OutputStream} import scala.concurrent.Future import scala.concurrent.duration._ import scala.collection.JavaConverters._ @@ -13,9 +20,10 @@ import com.spotify.docker.client.DefaultDockerClient trait Builders { core: Core => - val dockerClient = DefaultDockerClient.builder().uri("unix:///run/docker.sock").build() + val dockerClient = + DefaultDockerClient.builder().uri("unix:///run/docker.sock").build() - core.system.registerOnTermination{ + core.system.registerOnTermination { dockerClient.close() } @@ -27,60 +35,66 @@ trait Builders { core: Core => override def toString = id } - def startBuild( - image: String, - script: String, - dir: File, - out: OutputStream - ): Future[ContainerId] = Future { - val volume = Bind.builder().from(dir.getAbsolutePath).to(containerWorkDirectory).build() - val hostConfig = HostConfig.builder().binds(volume).build() - val containerConfig = ContainerConfig.builder() - .labels(Map("crashbox" -> "build").asJava) - .hostConfig(hostConfig) - .tty(true) // combine stdout and stderr into stdout - .image(image) - .user(containerUser) - .workingDir(containerWorkDirectory) - .entrypoint("/bin/sh", "-c") - .cmd(script) - .build() - val container = dockerClient.createContainer(containerConfig).id + def startBuild(image: String, + script: String, + dir: File, + out: OutputStream): Future[ContainerId] = + Future { + val volume = Bind + .builder() + .from(dir.getAbsolutePath) + .to(containerWorkDirectory) + .build() + val hostConfig = HostConfig.builder().binds(volume).build() + val containerConfig = ContainerConfig + .builder() + .labels(Map("crashbox" -> "build").asJava) + .hostConfig(hostConfig) + .tty(true) // combine stdout and stderr into stdout + .image(image) + .user(containerUser) + .workingDir(containerWorkDirectory) + .entrypoint("/bin/sh", "-c") + .cmd(script) + .build() + val container = dockerClient.createContainer(containerConfig).id - log.debug(s"Starting container $container") - dockerClient.startContainer(container) + log.debug(s"Starting container $container") + dockerClient.startContainer(container) - log.debug(s"Attaching log stream of container $container") - blockingDispatcher execute new Runnable { - override def run() = { - var stream: LogStream = null - try { - stream = dockerClient.attachContainer( - container, - AttachParameter.LOGS, - AttachParameter.STDOUT, - AttachParameter.STREAM - ) - stream.attach(out, null, true) - } finally { - if (stream != null) stream.close() + log.debug(s"Attaching log stream of container $container") + blockingDispatcher execute new Runnable { + override def run() = { + var stream: LogStream = null + try { + stream = dockerClient.attachContainer( + container, + AttachParameter.LOGS, + AttachParameter.STDOUT, + AttachParameter.STREAM + ) + stream.attach(out, null, true) + } finally { + if (stream != null) stream.close() + } } } - } - ContainerId(container) - }(blockingDispatcher) + ContainerId(container) + }(blockingDispatcher) - def waitBuild(id: ContainerId): Future[Int] = Future { - log.debug(s"Waiting for container $id to exit") - val res: Int = dockerClient.waitContainer(id.id).statusCode() - cancelBuild(id) - res - }(blockingDispatcher) + def waitBuild(id: ContainerId): Future[Int] = + Future { + log.debug(s"Waiting for container $id to exit") + val res: Int = dockerClient.waitContainer(id.id).statusCode() + cancelBuild(id) + res + }(blockingDispatcher) def cancelBuild(id: ContainerId): Unit = { log.debug(s"Stopping container $id") try { - dockerClient.stopContainer(id.id, containerKillTimeout.toUnit(SECONDS).toInt) + dockerClient.stopContainer(id.id, + containerKillTimeout.toUnit(SECONDS).toInt) dockerClient.removeContainer(id.id) } catch { case _: ContainerNotFoundException => // build already cancelled @@ -88,10 +102,12 @@ trait Builders { core: Core => } def reapDeadBuilds(): Unit = { - val stale = dockerClient.listContainers( - ListContainersParam.withLabel("crashbox"), - ListContainersParam.withStatusExited() - ).asScala + val stale = dockerClient + .listContainers( + ListContainersParam.withLabel("crashbox"), + ListContainersParam.withStatusExited() + ) + .asScala stale.foreach { container => dockerClient.removeContainer(container.id()) } diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Core.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Core.scala index 8342293..5a30df0 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Core.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Core.scala @@ -2,13 +2,14 @@ package io.crashbox.ci import akka.actor.ActorSystem import scala.concurrent.duration.Duration -import scala.concurrent.{ Await, ExecutionContext } +import scala.concurrent.{Await, ExecutionContext} trait Core { implicit val system: ActorSystem = ActorSystem("crashbox") implicit val executionContext: ExecutionContext = system.dispatcher - val blockingDispatcher: ExecutionContext = system.dispatchers.lookup("crashbox.blocking-dispatcher") + val blockingDispatcher: ExecutionContext = + system.dispatchers.lookup("crashbox.blocking-dispatcher") def log = system.log def config = system.settings.config diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Main.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Main.scala index 5b58875..0187751 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Main.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Main.scala @@ -2,8 +2,8 @@ package io.crashbox.ci import java.net.URL - -object Main extends Core +object Main + extends Core with Schedulers with Builders with Parsers @@ -21,6 +21,6 @@ object Main extends Core ) Thread.sleep(15000) System.exit(0) - } + } } diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Parsers.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Parsers.scala index 6f43380..20221cb 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Parsers.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Parsers.scala @@ -9,8 +9,8 @@ trait Parsers { def defaultImage = "crashbox/default" case class BuildDef( - image: String, - script: String + image: String, + script: String ) case class ParseError(message: String) @@ -18,19 +18,23 @@ trait Parsers { def parseBuild(workdir: File): Either[BuildDef, ParseError] = { val file = new File(workdir, ".crashbox.txt") if (!file.exists()) { - return Right(ParseError("No build configuration file .crashbox.txt found.")) + return Right( + ParseError("No build configuration file .crashbox.txt found.")) } val lines = Files.readAllLines(file.toPath).asScala.map(_.trim) val Pattern = """(\w+)\s*:\s*(.+)""".r - val image = lines.collectFirst{case Pattern("image", s) => s}.getOrElse(defaultImage) - val script = lines.collectFirst{case Pattern("script", s) => s} + val image = lines + .collectFirst { case Pattern("image", s) => s } + .getOrElse(defaultImage) + val script = lines.collectFirst { case Pattern("script", s) => s } script match { case Some(s) => Left(BuildDef(image, s)) - case None => Right(ParseError("No build script defined in configuration.")) + case None => + Right(ParseError("No build script defined in configuration.")) } } } diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Schedulers.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Schedulers.scala index c860932..e9f2a82 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Schedulers.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Schedulers.scala @@ -1,24 +1,31 @@ package io.crashbox.ci -import akka.actor.{ Actor, ActorLogging, ActorRef, OneForOneStrategy, Props, Terminated } +import akka.actor.{ + Actor, + ActorLogging, + ActorRef, + OneForOneStrategy, + Props, + Terminated +} import akka.stream.stage.GraphStageLogic -import akka.stream.{ Attributes, Outlet, SourceShape } +import akka.stream.{Attributes, Outlet, SourceShape} import akka.stream.stage.GraphStage -import java.io.{ File, OutputStream } +import java.io.{File, OutputStream} import java.net.URL import java.nio.file.Files import java.util.Base64 import scala.collection.mutable.HashMap -import scala.concurrent.{ Await, Future } +import scala.concurrent.{Await, Future} import scala.concurrent.duration._ import scala.util.control.NonFatal import akka.actor.SupervisorStrategy._ -import scala.util.{ Failure, Success } - +import scala.util.{Failure, Success} trait Schedulers extends { self: Core with Source with Builders with Parsers => - private def newTempDir: File = Files.createTempDirectory("crashbox-run").toFile() + private def newTempDir: File = + Files.createTempDirectory("crashbox-run").toFile() sealed trait BuildState case class Cloning(url: URL) extends BuildState @@ -31,10 +38,11 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => case class Failed(message: String) extends EndBuildState class BuildManager( - url: URL, - openOut: () => OutputStream, - update: BuildState => Unit - ) extends Actor with ActorLogging { + url: URL, + openOut: () => OutputStream, + update: BuildState => Unit + ) extends Actor + with ActorLogging { var buildDir: Option[File] = None var out: Option[OutputStream] = None @@ -53,7 +61,7 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => override def receive: Receive = { - case state@Cloning(url) => + case state @ Cloning(url) => log.debug("Update build state: cloning") update(state) fetchSource(url, newTempDir) onComplete { @@ -63,7 +71,7 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => self ! Failed(s"Error fetching source from $url") } - case state@Parsing(src) => + case state @ Parsing(src) => log.debug("Update build state: parsing") update(state) buildDir = Some(src) @@ -74,7 +82,7 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => self ! Failed(s"Failed to parse build $err") } - case state@Starting(src, bd) => + case state @ Starting(src, bd) => log.debug("Update build state: starting") update(state) val so = openOut() @@ -86,7 +94,7 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => self ! Failed(s"Failed to start build $err") } - case state@Running(id) => + case state @ Running(id) => log.debug("Update build state: running") update(state) containerId = Some(id) @@ -97,25 +105,31 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => self ! Failed(s"Error waiting for build to complete") } - case state@Finished(status) => + case state @ Finished(status) => log.debug("Update build state: finished") update(state) context stop self - case state@Failed(message) => + case state @ Failed(message) => log.debug("Update build state: failed") update(state) context stop self } } object BuildManager { - def apply(buildId: String, url: URL, out: () => OutputStream, update: BuildState => Unit) = + def apply(buildId: String, + url: URL, + out: () => OutputStream, + update: BuildState => Unit) = Props(new BuildManager(url, out, update)) } private sealed trait SchedulerCommand private case class ScheduleBuild( - buildId: String, url: URL, out: () => OutputStream, update: BuildState => Unit + buildId: String, + url: URL, + out: () => OutputStream, + update: BuildState => Unit ) extends SchedulerCommand class Scheduler extends Actor { @@ -128,8 +142,9 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => runningBuilds.get(sb.buildId) match { case Some(_) => //already running case None => - val buildManager = context.actorOf(BuildManager( - sb.buildId, sb.url, sb.out, sb.update), s"build-${sb.buildId}") + val buildManager = context.actorOf( + BuildManager(sb.buildId, sb.url, sb.out, sb.update), + s"build-${sb.buildId}") context watch buildManager runningBuilds += sb.buildId -> buildManager } @@ -142,13 +157,14 @@ trait Schedulers extends { self: Core with Source with Builders with Parsers => } } - private val scheduler = system.actorOf(Props(new Scheduler()), "crashbox-scheduler") + private val scheduler = + system.actorOf(Props(new Scheduler()), "crashbox-scheduler") def start( - buildId: String, - url: URL, - out: () => OutputStream, - update: BuildState => Unit + buildId: String, + url: URL, + out: () => OutputStream, + update: BuildState => Unit ): Unit = { scheduler ! ScheduleBuild(buildId, url, out, update) } diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/Source.scala b/crashbox-server/src/main/scala/io/crashbox/ci/Source.scala index 720b809..335e59c 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/Source.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/Source.scala @@ -7,10 +7,11 @@ import scala.concurrent.Future trait Source { self: Core => - def fetchSource(from: URL, to: File): Future[File] = Future { - log.debug(s"Cloning git repo from $from to $to") - Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).call() - to - }(blockingDispatcher) + def fetchSource(from: URL, to: File): Future[File] = + Future { + log.debug(s"Cloning git repo from $from to $to") + Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).call() + to + }(blockingDispatcher) } diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/StateStore.scala b/crashbox-server/src/main/scala/io/crashbox/ci/StateStore.scala index 94f51d0..3474407 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/StateStore.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/StateStore.scala @@ -1,7 +1,3 @@ package io.crashbox.ci -trait StateStore { - -} - - +trait StateStore {} diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/StreamStore.scala b/crashbox-server/src/main/scala/io/crashbox/ci/StreamStore.scala index 5fd3769..bba3cdf 100644 --- a/crashbox-server/src/main/scala/io/crashbox/ci/StreamStore.scala +++ b/crashbox-server/src/main/scala/io/crashbox/ci/StreamStore.scala @@ -1,15 +1,24 @@ package io.crashbox.ci -import java.io.{ File, FileInputStream, FileOutputStream, InputStream, OutputStream } +import java.io.{ + File, + FileInputStream, + FileOutputStream, + InputStream, + OutputStream +} import java.security.MessageDigest trait StreamStore { self: Core => - val streamsDirectory: File = new File(config.getString("crashbox.streams.directory")) + val streamsDirectory: File = new File( + config.getString("crashbox.streams.directory")) private def logFile(id: String): File = { val bytes = MessageDigest.getInstance("SHA-256").digest(id.getBytes) - val str = bytes.map{byte => Integer.toString((byte & 0xff) + 0x100, 16)}.mkString + val str = bytes.map { byte => + Integer.toString((byte & 0xff) + 0x100, 16) + }.mkString val (head, tail) = str.splitAt(2) new File(streamsDirectory, s"$head/$tail") } diff --git a/crashbox-server/src/test/scala/io/crashbox/ci/SourceSpec.scala b/crashbox-server/src/test/scala/io/crashbox/ci/SourceSpec.scala index 9bef01d..a03e476 100644 --- a/crashbox-server/src/test/scala/io/crashbox/ci/SourceSpec.scala +++ b/crashbox-server/src/test/scala/io/crashbox/ci/SourceSpec.scala @@ -23,10 +23,11 @@ class SourceSpec extends FlatSpec with Matchers with Source with Core { } "GitFetchers" should "be able to clone a local repository" in { - TestUtil.withTempDir{ remote => + TestUtil.withTempDir { remote => makeRepo(remote) TestUtil.withTempDir { local => - val cloned = Await.result(fetchSource(remote.toURI().toURL(), local), Timeout) + val cloned = + Await.result(fetchSource(remote.toURI().toURL(), local), Timeout) assert(cloned.listFiles().length == 3) } } diff --git a/crashbox-server/src/test/scala/io/crashbox/ci/TestUtil.scala b/crashbox-server/src/test/scala/io/crashbox/ci/TestUtil.scala index eb177f8..a7e7ae6 100644 --- a/crashbox-server/src/test/scala/io/crashbox/ci/TestUtil.scala +++ b/crashbox-server/src/test/scala/io/crashbox/ci/TestUtil.scala @@ -1,13 +1,14 @@ package io.crashbox.ci -import java.io.{ File, OutputStream } +import java.io.{File, OutputStream} import java.nio.file.Files object TestUtil { def withTempDir[A](f: File => A): A = { val dir = Files.createTempDirectory("crashbox-test").toFile - try f(dir) finally dir.delete() + try f(dir) + finally dir.delete() } } -- cgit v1.2.3