From 8da6c6d93f4054d1fd381a4ea1f2f2e97ff38669 Mon Sep 17 00:00:00 2001 From: infiniteregrets Date: Sat, 11 Nov 2023 23:38:14 -0500 Subject: [PATCH] Fix broken wsl support --- .../com/metalbear/mirrord/MirrordApi.kt | 14 ++--- .../metalbear/mirrord/MirrordBinaryManager.kt | 33 +++++++----- .../metalbear/mirrord/MirrordExecManager.kt | 51 +++++++++---------- .../metalbear/mirrord/MirrordPluginTest.kt | 3 ++ 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt index 4e934766..b0f3702d 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt @@ -102,7 +102,7 @@ class MirrordApi(private val service: MirrordProjectService) { if (pods.isEmpty()) { project.service().notifier.notifySimple( "No mirrord target available in the configured namespace. " + - "You can run targetless, or set a different target namespace or kubeconfig in the mirrord configuration file.", + "You can run targetless, or set a different target namespace or kubeconfig in the mirrord configuration file.", NotificationType.INFORMATION ) } @@ -193,10 +193,7 @@ class MirrordApi(private val service: MirrordProjectService) { throw MirrordError.fromStdErr(processStdError) } - val parser = SafeParser() val bufferedReader = process.inputStream.reader().buffered() - - val warningHandler = MirrordWarningHandler(project.service()) return bufferedReader.readText() } } @@ -208,9 +205,13 @@ class MirrordApi(private val service: MirrordProjectService) { */ fun verifyConfig( cli: String, - configFilePath: String + configFilePath: String, + wslDistribution: WSLDistribution? ): String { - return MirrordVerifyConfigTask(cli, configFilePath).run(service.project) + val verifyConfigTask = MirrordVerifyConfigTask(cli, configFilePath).apply { + this.wslDistribution = wslDistribution + } + return verifyConfigTask.run(service.project) } /** @@ -303,6 +304,7 @@ private abstract class MirrordCliTask(private val cli: String, private val co wslDistribution?.let { val wslOptions = WSLCommandLineOptions().apply { isLaunchWithWslExe = true + isExecuteCommandInShell = false } it.patchCommandLine(this, project, wslOptions) } diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordBinaryManager.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordBinaryManager.kt index fa9423e7..068ba73c 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordBinaryManager.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordBinaryManager.kt @@ -104,7 +104,7 @@ class MirrordBinaryManager { val local = if (checkInPath) { manager.getLocalBinary(version, wslDistribution) } else { - manager.findBinaryInStorage(version) + manager.findBinaryInStorage(version, wslDistribution) } if (local != null) { @@ -112,7 +112,7 @@ class MirrordBinaryManager { } manager.latestSupportedVersion = version - // auto update -> false -> mirrordVersion is empty -> no cli found locally -> fetch latest version + // auto update -> false -> mirrordVersion is empty -> no cli found locally -> fetch latest version ?: manager.fetchLatestSupportedVersion(product, indicator) if (downloadInProgress.compareAndExchange(false, true)) { @@ -241,19 +241,24 @@ class MirrordBinaryManager { Files.move(tmpDestination, destination, StandardCopyOption.REPLACE_EXISTING) } - private class MirrordBinary(val command: String) { + private class MirrordBinary(val command: String, wslDistribution: WSLDistribution?) { val version: String init { - val child = Runtime.getRuntime().exec(arrayOf(command, "--version")) + version = if (wslDistribution != null) { + val command = wslDistribution.getWslPath(command) + val output = wslDistribution.executeOnWsl(1000, command, "--version") + output.stdout.split(' ')[1].trim() + } else { + val child = Runtime.getRuntime().exec(arrayOf(command, "--version")) + val result = child.waitFor() + if (result != 0) { + MirrordLogger.logger.debug("`mirrord --version` failed with code $result") + throw RuntimeException("failed to get mirrord version") + } - val result = child.waitFor() - if (result != 0) { - MirrordLogger.logger.debug("`mirrord --version` failed with code $result") - throw RuntimeException("failed to get mirrord version") + child.inputReader().readLine().split(' ')[1].trim() } - - version = child.inputReader().readLine().split(' ')[1].trim() } } @@ -277,7 +282,7 @@ class MirrordBinaryManager { output.stdoutLines.first().trim() } - val binary = MirrordBinary(output) + val binary = MirrordBinary(output, wslDistribution) if (requiredVersion == null || requiredVersion == binary.version) { return binary } @@ -291,10 +296,10 @@ class MirrordBinaryManager { /** * @return executable found in plugin storage */ - private fun findBinaryInStorage(requiredVersion: String?): MirrordBinary? { + private fun findBinaryInStorage(requiredVersion: String?, wslDistribution: WSLDistribution?): MirrordBinary? { try { MirrordPathManager.getBinary(CLI_BINARY, true)?.let { - val binary = MirrordBinary(it) + val binary = MirrordBinary(it, wslDistribution) if (requiredVersion == null || requiredVersion == binary.version) { return binary } @@ -310,7 +315,7 @@ class MirrordBinaryManager { * @return the local installation of mirrord, either in `PATH` or in plugin storage */ private fun getLocalBinary(requiredVersion: String?, wslDistribution: WSLDistribution?): MirrordBinary? { - return findBinaryInPath(requiredVersion, wslDistribution) ?: findBinaryInStorage(requiredVersion) + return findBinaryInPath(requiredVersion, wslDistribution) ?: findBinaryInStorage(requiredVersion, wslDistribution) } /** diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt index c487fb51..dd728e56 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt @@ -53,7 +53,7 @@ class MirrordExecManager(private val service: MirrordProjectService) { .notifier .notification( "mirrord plugin was unable to display the target selection dialog. " + - "You can set it manually in the configuration file $config.", + "You can set it manually in the configuration file $config.", NotificationType.WARNING ) .apply { @@ -109,45 +109,42 @@ class MirrordExecManager(private val service: MirrordProjectService) { service.versionCheck.checkVersion() // TODO makes an HTTP request, move to background val cli = cliPath(wslDistribution, product) - val config = service.configApi.getConfigPath(mirrordConfigFromEnv) - // Find the mirrord config path, then call `mirrord verify-config {path}` so we can display warnings/errors // from the config without relying on mirrord-layer. val configPath = service.configApi.getConfigPath(mirrordConfigFromEnv) - var verifiedConfig: MirrordVerifiedConfig? = null - if (configPath != null) { - val verifiedConfigOutput = service.mirrordApi.verifyConfig(cli, configPath) - val verified = MirrordVerifiedConfig(verifiedConfigOutput, service.notifier).also { verifiedConfig = it } - if (verified.isError()) { - throw InvalidConfigException(configPath, "validation failed for config") + + val verifiedConfig = configPath?.let { + val verifiedConfigOutput = + service.mirrordApi.verifyConfig(cli, wslDistribution?.getWslPath(it) ?: it, wslDistribution) + MirrordVerifiedConfig(verifiedConfigOutput, service.notifier).apply { + if (isError()) { + throw InvalidConfigException(it, "Validation failed for config") + } } } - MirrordLogger.logger.debug("target selection") + MirrordLogger.logger.debug("Verified Config: $verifiedConfig, Target selection.") - var target: String? = null - val isTargetSet = (config != null && isTargetSet(verifiedConfig?.config)) - MirrordLogger.logger.debug("$verifiedConfig") - - if (!isTargetSet) { + val target = if (configPath != null && !isTargetSet(verifiedConfig?.config)) { MirrordLogger.logger.debug("target not selected, showing dialog") - target = chooseTarget(cli, wslDistribution, config) - if (target == MirrordExecDialog.targetlessTargetName) { - MirrordLogger.logger.info("No target specified - running targetless") - service.notifier.notification( - "No target specified, mirrord running targetless.", - NotificationType.INFORMATION - ) - .withDontShowAgain(MirrordSettingsState.NotificationId.RUNNING_TARGETLESS) - .fire() - target = null + chooseTarget(cli, wslDistribution, configPath).also { + if (it == MirrordExecDialog.targetlessTargetName) { + MirrordLogger.logger.info("No target specified - running targetless") + service.notifier.notification( + "No target specified, mirrord running targetless.", + NotificationType.INFORMATION + ) + .withDontShowAgain(MirrordSettingsState.NotificationId.RUNNING_TARGETLESS) + .fire() + } } - } + } else null + val executionInfo = service.mirrordApi.exec( cli, target, - config, + configPath, executable, wslDistribution ) diff --git a/src/test/kotlin/com/metalbear/mirrord/MirrordPluginTest.kt b/src/test/kotlin/com/metalbear/mirrord/MirrordPluginTest.kt index dbcd2c3e..60ebab28 100644 --- a/src/test/kotlin/com/metalbear/mirrord/MirrordPluginTest.kt +++ b/src/test/kotlin/com/metalbear/mirrord/MirrordPluginTest.kt @@ -26,6 +26,7 @@ import java.nio.file.Path import java.nio.file.Paths import java.time.Duration.ofMinutes import java.time.Duration.ofSeconds +import java.util.* import java.util.concurrent.TimeUnit import javax.imageio.ImageIO @@ -41,10 +42,12 @@ internal class MirrordPluginTest { private var tmpDir: Path = Files.createTempDirectory("launcher") private lateinit var remoteRobot: RemoteRobot private var steps: CommonSteps? = null + private var isWsl = false @BeforeAll @JvmStatic fun startIdea() { + isWsl = System.getProperty("os.version").lowercase(Locale.getDefault()).contains("windows") val client = OkHttpClient() remoteRobot = RemoteRobot("http://localhost:8082", client) steps = CommonSteps(remoteRobot)