Runnodes now exposes default ports for nodes automatically (#480)

Cordformation now automatically assigns a debug port
This commit is contained in:
Clinton 2017-04-04 11:58:56 +01:00 committed by GitHub
parent 09e7d89e4e
commit e8316dedd0
2 changed files with 34 additions and 16 deletions

View File

@ -1,3 +1,3 @@
gradlePluginsVersion=0.10.3 gradlePluginsVersion=0.10.4
kotlinVersion=1.1.1 kotlinVersion=1.1.1
guavaVersion=21.0 guavaVersion=21.0

View File

@ -20,25 +20,26 @@ private val os: OS by lazy {
private enum class OS { MACOS, WINDOWS, LINUX } private enum class OS { MACOS, WINDOWS, LINUX }
data class IncrementalPortAllocator(var basePort: Int = 5005) {
fun next(): Int = basePort++
}
val debugPortAlloc: IncrementalPortAllocator = IncrementalPortAllocator()
fun main(args: Array<String>) { fun main(args: Array<String>) {
val startedProcesses = mutableListOf<Process>() val startedProcesses = mutableListOf<Process>()
val headless = (GraphicsEnvironment.isHeadless() || (!args.isEmpty() && (args[0] == HEADLESS_FLAG))) val headless = (GraphicsEnvironment.isHeadless() || (!args.isEmpty() && (args[0] == HEADLESS_FLAG)))
val runJar = getJarRunner(headless)
val workingDir = Paths.get(System.getProperty("user.dir")).toFile() val workingDir = Paths.get(System.getProperty("user.dir")).toFile()
val javaArgs = args.filter { it != HEADLESS_FLAG } val javaArgs = args.filter { it != HEADLESS_FLAG }
println("Starting nodes in $workingDir") println("Starting nodes in $workingDir")
workingDir.list().map { File(workingDir, it) }.forEach { workingDir.list().map { File(workingDir, it) }.forEach {
if (isNode(it)) { if (isNode(it)) {
println("Starting node in $it") startedProcesses += startJarProcess(headless, it, nodeJarName, javaArgs)
startedProcesses.add(runJar(nodeJarName, it, javaArgs))
if (os == OS.MACOS) Thread.sleep(1000)
} }
if (isWebserver(it)) { if (isWebserver(it)) {
println("Starting webserver in $it") startedProcesses += startJarProcess(headless, it, webJarName, javaArgs)
startedProcesses.add(runJar(webJarName, it, javaArgs))
if (os == OS.MACOS) Thread.sleep(1000)
} }
} }
@ -46,32 +47,49 @@ fun main(args: Array<String>) {
println("Finished starting nodes") println("Finished starting nodes")
} }
private fun startJarProcess(headless: Boolean, dir: File, jarName: String, javaArgs: List<String>) : Process {
val runJar = getJarRunner(headless)
val debugPort = debugPortAlloc.next()
println("Starting $jarName in $dir on debug port $debugPort")
val proc = runJar(jarName, dir, javaArgs, debugPort)
if (os == OS.MACOS) Thread.sleep(1000)
return proc
}
private fun isNode(maybeNodeDir: File) = maybeNodeDir.isDirectory private fun isNode(maybeNodeDir: File) = maybeNodeDir.isDirectory
&& File(maybeNodeDir, nodeJarName).exists() && File(maybeNodeDir, nodeJarName).exists()
&& File(maybeNodeDir, webJarName).exists()
&& File(maybeNodeDir, nodeConfName).exists() && File(maybeNodeDir, nodeConfName).exists()
private fun isWebserver(maybeWebserverDir: File) = isNode(maybeWebserverDir) && hasWebserverPort(maybeWebserverDir) private fun isWebserver(maybeWebserverDir: File) = maybeWebserverDir.isDirectory
&& File(maybeWebserverDir, webJarName).exists()
&& File(maybeWebserverDir, nodeConfName).exists()
&& hasWebserverPort(maybeWebserverDir)
// TODO: Add a webserver.conf, or use TypeSafe config instead of this hack // TODO: Add a webserver.conf, or use TypeSafe config instead of this hack
private fun hasWebserverPort(nodeConfDir: File) = Files.readAllLines(File(nodeConfDir, nodeConfName).toPath()).joinToString { it }.contains("webAddress") private fun hasWebserverPort(nodeConfDir: File) = Files.readAllLines(File(nodeConfDir, nodeConfName).toPath()).joinToString { it }.contains("webAddress")
private fun getJarRunner(headless: Boolean): (String, File, List<String>) -> Process = if (headless) ::execJar else ::execJarInTerminalWindow private fun getDebugPortArg(debugPort: Int?) = if (debugPort != null) {
listOf("""-Dcapsule.jvm.args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$debugPort"""")
} else {
emptyList()
}
private fun execJar(jarName: String, dir: File, args: List<String> = listOf()): Process { private fun getJarRunner(headless: Boolean): (String, File, List<String>, Int?) -> Process = if (headless) ::execJar else ::execJarInTerminalWindow
private fun execJar(jarName: String, dir: File, args: List<String> = listOf(), debugPort: Int?): Process {
val nodeName = dir.toPath().fileName val nodeName = dir.toPath().fileName
val separator = System.getProperty("file.separator") val separator = System.getProperty("file.separator")
val path = System.getProperty("java.home") + separator + "bin" + separator + "java" val path = System.getProperty("java.home") + separator + "bin" + separator + "java"
val builder = ProcessBuilder(listOf(path, "-Dname=$nodeName", "-jar", jarName) + args) val builder = ProcessBuilder(listOf(path, "-Dname=$nodeName") + getDebugPortArg(debugPort) + listOf("-jar", jarName) + args)
builder.redirectError(Paths.get("error.${dir.toPath().fileName}.log").toFile()) builder.redirectError(Paths.get("error.${dir.toPath().fileName}.log").toFile())
builder.inheritIO() builder.inheritIO()
builder.directory(dir) builder.directory(dir)
return builder.start() return builder.start()
} }
private fun execJarInTerminalWindow(jarName: String, dir: File, args: List<String> = listOf()): Process { private fun execJarInTerminalWindow(jarName: String, dir: File, args: List<String> = listOf(), debugPort: Int?): Process {
val javaCmd = "java -jar $jarName " + args.joinToString(" ") { it } val nodeName = "${dir.toPath().fileName}-$jarName"
val nodeName = "${dir.toPath().fileName} $jarName" val javaCmd = (listOf("java", "-Dname=$nodeName") + getDebugPortArg(debugPort) + listOf("-jar", jarName) + args).joinToString(" ") { it }
val builder = when (os) { val builder = when (os) {
OS.MACOS -> ProcessBuilder( OS.MACOS -> ProcessBuilder(
"osascript", "-e", "osascript", "-e",