parent
5345da6232
commit
992a5a922d
@ -1,46 +0,0 @@
|
|||||||
package alfred.web.core
|
|
||||||
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Service
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
@Service
|
|
||||||
class ScriptRunner(
|
|
||||||
val builds: Builds,
|
|
||||||
val handles: Handles,
|
|
||||||
val processes: Processes
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun run(buildId: BuildId, rev: String): ProcessInfo {
|
|
||||||
val config = builds.buildConfig(buildId)
|
|
||||||
val logFile = builds.createLogFile(buildId)
|
|
||||||
|
|
||||||
logger.info("preparing process for build $buildId with config $config")
|
|
||||||
logger.info("log file: $logFile")
|
|
||||||
|
|
||||||
logFile.header(buildId, rev, Paths.get(config.gitWorkspace))
|
|
||||||
|
|
||||||
val process = processes.builder(config, logFile, rev)
|
|
||||||
.command(config.script)
|
|
||||||
.start()
|
|
||||||
handles.add(Handle(process.toHandle(), buildId))
|
|
||||||
process.onExit().whenComplete { _, _ -> logFile.footer() }
|
|
||||||
|
|
||||||
val pid = process.pid()
|
|
||||||
|
|
||||||
logger.info("pid for build $buildId is: $pid")
|
|
||||||
|
|
||||||
return ProcessInfo(pid = pid, logFile = logFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ProcessInfo(
|
|
||||||
val pid: Long,
|
|
||||||
val logFile: LogFile
|
|
||||||
)
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
package alfred.web.core.build
|
||||||
|
|
||||||
|
data class BuildContext(
|
||||||
|
val config: BuildConfig,
|
||||||
|
val logFile: LogFile,
|
||||||
|
val rev: String,
|
||||||
|
val buildId: BuildId
|
||||||
|
)
|
@ -1,18 +1,22 @@
|
|||||||
package alfred.web.core
|
package alfred.web.core.build
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
|
import kotlin.collections.joinToString
|
||||||
import kotlin.io.appendText
|
import kotlin.io.appendText
|
||||||
|
import kotlin.text.isEmpty
|
||||||
|
import kotlin.text.lines
|
||||||
|
import kotlin.text.trim
|
||||||
|
|
||||||
class LogFile(
|
class LogFile(
|
||||||
val backingFile: File
|
val backingFile: File
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun header(buildId: BuildId, rev: String, workspace: Path) {
|
fun header(buildId: BuildId, rev: String?, workspace: Path) {
|
||||||
append("At your service.")
|
append("At your service.")
|
||||||
append("Build $buildId, rev [$rev] started at ${ZonedDateTime.now()}")
|
append("Build $buildId, rev [${rev ?: "-none-"}] started at ${ZonedDateTime.now()}")
|
||||||
append("Workspace directory is: $workspace\n")
|
append("Workspace directory is: ${workspace.toFile().absolutePath}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun footer() {
|
fun footer() {
|
@ -0,0 +1,6 @@
|
|||||||
|
package alfred.web.core.build
|
||||||
|
|
||||||
|
data class ProcessInfo(
|
||||||
|
val pid: Long,
|
||||||
|
val logFile: LogFile
|
||||||
|
)
|
@ -0,0 +1,61 @@
|
|||||||
|
package alfred.web.core.runner
|
||||||
|
|
||||||
|
import alfred.web.core.Handle
|
||||||
|
import alfred.web.core.Handles
|
||||||
|
import alfred.web.core.Processes
|
||||||
|
import alfred.web.core.build.BuildContext
|
||||||
|
import alfred.web.core.build.BuildId
|
||||||
|
import alfred.web.core.build.Builds
|
||||||
|
import alfred.web.core.build.ProcessInfo
|
||||||
|
import alfred.web.core.build.Workspaces
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import kotlin.jvm.java
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class ScriptRunner(
|
||||||
|
val builds: Builds,
|
||||||
|
val handles: Handles,
|
||||||
|
val processes: Processes,
|
||||||
|
val workspaces: Workspaces
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun run(buildId: BuildId, rev: String?): ProcessInfo {
|
||||||
|
val config = builds.buildConfig(buildId)
|
||||||
|
val logFile = builds.createLogFile(buildId)
|
||||||
|
|
||||||
|
logger.info("preparing process for build $buildId with config $config")
|
||||||
|
logger.info("log file: ${logFile.backingFile.absolutePath}")
|
||||||
|
|
||||||
|
val ctx = BuildContext(
|
||||||
|
config = config,
|
||||||
|
logFile = logFile,
|
||||||
|
rev = rev ?: "",
|
||||||
|
buildId = buildId
|
||||||
|
)
|
||||||
|
|
||||||
|
val wsDir = workspaces.prepare(ctx)
|
||||||
|
logFile.header(buildId, rev, wsDir)
|
||||||
|
|
||||||
|
val process = processes.builder(config, logFile, rev)
|
||||||
|
.command(config.script)
|
||||||
|
.directory(wsDir.toFile())
|
||||||
|
.start()
|
||||||
|
handles.add(Handle(process.toHandle(), buildId))
|
||||||
|
|
||||||
|
process.onExit().whenComplete { _, _ ->
|
||||||
|
logFile.footer()
|
||||||
|
workspaces.cleanUp(wsDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val pid = process.pid()
|
||||||
|
|
||||||
|
logger.info("pid for build $buildId is: $pid")
|
||||||
|
|
||||||
|
return ProcessInfo(pid = pid, logFile = logFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package alfred.web.cron
|
||||||
|
|
||||||
|
import alfred.web.core.build.Builds
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class CronTrigger(
|
||||||
|
private val builds: Builds
|
||||||
|
) {
|
||||||
|
|
||||||
|
@Scheduled(fixedDelay = 1L, timeUnit= TimeUnit.MINUTES)
|
||||||
|
fun checkTrigger() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package alfred.web.http
|
||||||
|
|
||||||
|
import alfred.web.core.Handles
|
||||||
|
import alfred.web.core.build.BuildId
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("build")
|
||||||
|
class BuildsInfo(
|
||||||
|
val security: Security,
|
||||||
|
val handles: Handles
|
||||||
|
) {
|
||||||
|
|
||||||
|
@GetMapping(
|
||||||
|
"{build}/info",
|
||||||
|
produces = [MediaType.APPLICATION_JSON_VALUE]
|
||||||
|
)
|
||||||
|
fun info(
|
||||||
|
@PathVariable("build")
|
||||||
|
build: BuildId,
|
||||||
|
@RequestParam("key")
|
||||||
|
key: String?
|
||||||
|
) = security.requireKey(build, key) {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(
|
||||||
|
"{build}/handles",
|
||||||
|
produces = [MediaType.APPLICATION_JSON_VALUE]
|
||||||
|
)
|
||||||
|
fun handles(
|
||||||
|
@PathVariable("build")
|
||||||
|
build: BuildId,
|
||||||
|
@RequestParam("key")
|
||||||
|
key: String?
|
||||||
|
) = security.requireKey(build, key) {
|
||||||
|
handles.active(build)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue