Skip to content

Commit 1cb6fe1

Browse files
committed
fix: process working dir detection
1 parent f02f31c commit 1cb6fe1

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

serverhost-runtime/src/main/kotlin/app/simplecloud/droplet/serverhost/runtime/config/environment/EnvironmentConfig.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ data class EnvironmentConfig(
2828
}
2929
return start?.command?.get(0)
3030
}
31+
32+
fun getRealExecutable(): String? {
33+
return start?.command?.get(0)
34+
}
35+
3136
}

serverhost-runtime/src/main/kotlin/app/simplecloud/droplet/serverhost/runtime/process/ProcessFinder.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,32 @@ package app.simplecloud.droplet.serverhost.runtime.process
33
import app.simplecloud.droplet.serverhost.runtime.util.ProcessDirectory
44
import java.nio.file.Path
55
import java.util.*
6+
import kotlin.io.path.absolutePathString
67

78
object ProcessFinder {
89

9-
fun findHighestProcessParent(
10-
serverDir: Path,
10+
fun findHighestProcessWorkingDir(
11+
dir: Path,
1112
handle: ProcessHandle,
13+
executable: String,
1214
): Optional<ProcessHandle> {
13-
val path = ProcessDirectory.of(handle).orElse(serverDir)
14-
if (path == serverDir) {
15+
val path = ProcessDirectory.of(handle).orElse(dir)
16+
if (path.normalize().absolutePathString() == dir.normalize().absolutePathString() && ProcessInfo.of(handle)
17+
.getCommand().lowercase().startsWith(executable)
18+
) {
1519
return Optional.of(handle)
1620
}
1721
val parent = handle.parent().orElse(null) ?: return Optional.empty()
18-
return findHighestProcessParent(serverDir, parent)
22+
return findHighestProcessWorkingDir(dir, parent, executable)
1923
}
2024

2125
fun findHighestExecutableProcess(handle: ProcessHandle, executable: String): Optional<ProcessHandle> {
2226
var returned = Optional.empty<ProcessHandle>()
2327
handle.children().forEach { child ->
2428
if (!returned.isEmpty) return@forEach
25-
if (ProcessInfo.of(child).getCommand().startsWith(executable))
29+
if (ProcessInfo.of(child).getCommand().lowercase().startsWith(executable)) {
2630
returned = Optional.of(child)
31+
}
2732
}
2833
if (!returned.isEmpty) return returned
2934
handle.children().forEach { child ->

serverhost-runtime/src/main/kotlin/app/simplecloud/droplet/serverhost/runtime/runner/ServerRunner.kt

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,14 @@ class ServerRunner(
7979

8080
// Retrieving this before the ping makes it possible to stop servers way sooner (port is registered in system nearly instantly, it takes longer for the
8181
// server to respond to pings though)
82-
val executable = environmentsRepository.get(runtimeRepository.get(server.group))?.getExecutable()
82+
val executable = environmentsRepository.get(runtimeRepository.get(server.group))
8383
val handle = PortProcessHandle.of(server.port.toInt()).orElse(null)?.let {
84-
val realProcess = ProcessFinder.findHighestProcessParent(getServerDir(server).toPath(), it).orElse(null)
84+
val realProcess = executable?.getRealExecutable()?.let { exe ->
85+
ProcessFinder.findHighestProcessWorkingDir(
86+
getServerDir(server).toPath(), it,
87+
exe
88+
).orElse(null)
89+
}
8590
if (realProcess != null && serverToProcessHandle[server] != realProcess) {
8691
logger.info("Found updated process handle with PID ${realProcess.pid()} for ${server.group}-${server.numericalId}")
8792
serverToProcessHandle[server] = realProcess
@@ -110,7 +115,7 @@ class ServerRunner(
110115
this.playerCount = ping.players.online.toLong()
111116
this.cloudProperties["motd"] = ping.description.text
112117
})
113-
trackMetrics(copiedServer, handle, executable)
118+
trackMetrics(copiedServer, handle, executable?.getExecutable())
114119
return copiedServer
115120
} catch (e: Exception) {
116121
logger.warn("Failed to ping server ${server.group}-${server.numericalId} ${server.ip}:${server.port}: ${e.message}")
@@ -166,7 +171,7 @@ class ServerRunner(
166171
)
167172
}
168173

169-
fun startServer(server: Server): Boolean {
174+
suspend fun startServer(server: Server): Boolean {
170175
logger.info("Starting server ${server.uniqueId} of group ${server.group} (#${server.numericalId})")
171176

172177
if (containsServer(server)) {
@@ -183,19 +188,24 @@ class ServerRunner(
183188
logger.error("Server ${server.uniqueId} of group ${server.group} failed to start: Group has no assigned configurator.")
184189
return false
185190
}
191+
var ctx: YamlActionContext?
192+
copyTemplateMutex.withLock {
193+
ctx = executeTemplate(getServerDir(server).toPath(), server, YamlActionTriggerTypes.START)
194+
}
186195

187-
val ctx = executeTemplate(getServerDir(server).toPath(), server, YamlActionTriggerTypes.START)
188196
var serverDir: File? = null
189197
if (ctx != null) {
190-
serverDir = getServerDir(ctx)
198+
serverDir = getServerDir(ctx!!)
191199
}
192200
try {
193201
val builder = buildProcess(serverDir, server, runtimeConfig)
194202

195203
if (!builder.directory().exists()) {
196204
builder.directory().mkdirs()
197205
}
198-
val process = builder.start()
206+
val process = withContext(Dispatchers.IO) {
207+
builder.start()
208+
}
199209
val updatedServer = Server.fromDefinition(server.toDefinition().copy {
200210
cloudProperties["server-dir"] = serverDir?.absolutePath ?: getServerDir(server).absolutePath
201211
})
@@ -297,12 +307,16 @@ class ServerRunner(
297307
logger.error("Server ${server.uniqueId} of group ${server.group} is already running.")
298308
return true
299309
}
310+
val executable = environmentsRepository.get(runtimeRepository.get(server.group))?.getRealExecutable()
300311
val handle = PortProcessHandle.of(server.port.toInt()).orElse(null)
301312
?.let {
302-
ProcessFinder.findHighestProcessParent(
303-
getServerDir(server).toPath(),
304-
it
305-
).orElse(null)
313+
executable?.let { exe ->
314+
ProcessFinder.findHighestProcessWorkingDir(
315+
getServerDir(server).toPath(),
316+
it,
317+
exe
318+
).orElse(null)
319+
}
306320
}
307321

308322
if (handle == null) {
@@ -335,6 +349,7 @@ class ServerRunner(
335349

336350
private fun terminateScreenSession(pid: Long) {
337351
try {
352+
logger.info("Terminating screen $pid")
338353
val process = ProcessBuilder("screen", "-S", pid.toString(), "-X", "quit")
339354
.redirectErrorStream(true)
340355
.start()

0 commit comments

Comments
 (0)