From 343e1630e8d9fa85481fb795c77d3e4c1bb0d13b Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Tue, 29 Nov 2022 19:27:23 +0200 Subject: [PATCH] Impl: clean-up outdated binaries - older versions of Coder CLI are now removed from the cache folder. - refactored some of the code around managing the coder cli - resolves #92 --- CHANGELOG.md | 3 ++ .../coder/gateway/sdk/CoderCLIDownloader.kt | 27 ----------- .../com/coder/gateway/sdk/CoderCLIManager.kt | 45 +++++++++++++++---- .../views/steps/CoderWorkspacesStepView.kt | 14 ++++-- 4 files changed, 49 insertions(+), 40 deletions(-) delete mode 100644 src/main/kotlin/com/coder/gateway/sdk/CoderCLIDownloader.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index ca6f3920..e30392bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ## Unreleased +### Fixed +- outdated Coder CLI binaries are cleaned up + ## 2.1.2 - 2022-11-23 ### Added diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderCLIDownloader.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderCLIDownloader.kt deleted file mode 100644 index daf77f32..00000000 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderCLIDownloader.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.coder.gateway.sdk - -import com.intellij.openapi.diagnostic.Logger -import java.io.InputStream -import java.net.URL -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.StandardCopyOption - -class CoderCLIDownloader { - - fun downloadCLI(url: URL, cliPath: Path): Boolean { - if (Files.exists(cliPath)) { - logger.info("${cliPath.toAbsolutePath()} already exists, skipping download") - return false - } - logger.info("Starting Coder CLI download to ${cliPath.toAbsolutePath()}") - url.openStream().use { - Files.copy(it as InputStream, cliPath, StandardCopyOption.REPLACE_EXISTING) - } - return true - } - - companion object { - val logger = Logger.getInstance(CoderCLIDownloader::class.java.simpleName) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt index d60d22b6..0c2ae625 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt @@ -1,28 +1,36 @@ package com.coder.gateway.sdk import com.intellij.openapi.diagnostic.Logger +import java.io.InputStream import java.net.URL +import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import java.nio.file.StandardCopyOption class CoderCLIManager(url: URL, buildVersion: String) { - var remoteCliPath: URL - var localCliPath: Path + var remoteCli: URL + var localCli: Path + private var cliNamePrefix: String + private var tmpDir: String + private var cliFileName: String init { val os = getOS() - val cliName = getCoderCLIForOS(os, getArch()) - val cliNameWithExt = if (os == OS.WINDOWS) "$cliName.exe" else cliName - val filename = if (os == OS.WINDOWS) "${cliName}-${buildVersion}.exe" else "${cliName}-${buildVersion}" + cliNamePrefix = getCoderCLIForOS(os, getArch()) + val cliNameWithExt = if (os == OS.WINDOWS) "$cliNamePrefix.exe" else cliNamePrefix + cliFileName = if (os == OS.WINDOWS) "${cliNamePrefix}-${buildVersion}.exe" else "${cliNamePrefix}-${buildVersion}" - remoteCliPath = URL(url.protocol, url.host, url.port, "/bin/$cliNameWithExt") - localCliPath = Paths.get(System.getProperty("java.io.tmpdir"), filename) + remoteCli = URL(url.protocol, url.host, url.port, "/bin/$cliNameWithExt") + tmpDir = System.getProperty("java.io.tmpdir") + localCli = Paths.get(tmpDir, cliFileName) } - private fun getCoderCLIForOS(os: OS?, arch: Arch?): String? { + private fun getCoderCLIForOS(os: OS?, arch: Arch?): String { logger.info("Resolving coder cli for $os $arch") if (os == null) { - return null + logger.error("Could not resolve client OS and architecture, defaulting to WINDOWS AMD64") + return "coder-windows-amd64" } return when (os) { OS.WINDOWS -> when (arch) { @@ -46,6 +54,25 @@ class CoderCLIManager(url: URL, buildVersion: String) { } } + fun downloadCLI(): Boolean { + if (Files.exists(localCli)) { + logger.info("${localCli.toAbsolutePath()} already exists, skipping download") + return false + } + logger.info("Starting Coder CLI download to ${localCli.toAbsolutePath()}") + remoteCli.openStream().use { + Files.copy(it as InputStream, localCli, StandardCopyOption.REPLACE_EXISTING) + } + return true + } + + fun removeOldCli() { + Files.walk(Path.of(tmpDir)).sorted().map { it.toFile() }.filter { it.name.contains(cliNamePrefix) && !it.name.contains(cliFileName) }.forEach { + logger.info("Removing $it because it is an old coder cli") + it.delete() + } + } + companion object { val logger = Logger.getInstance(CoderCLIManager::class.java.simpleName) } diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index 4682152c..b61e1cd2 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -13,7 +13,6 @@ import com.coder.gateway.models.WorkspaceAgentStatus.STOPPED import com.coder.gateway.models.WorkspaceAgentStatus.STOPPING import com.coder.gateway.models.WorkspaceVersionStatus import com.coder.gateway.sdk.Arch -import com.coder.gateway.sdk.CoderCLIDownloader import com.coder.gateway.sdk.CoderCLIManager import com.coder.gateway.sdk.CoderRestClientService import com.coder.gateway.sdk.OS @@ -317,7 +316,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : localWizardModel.apply { this.token = token buildVersion = coderClient.buildVersion - localCliPath = cliManager.localCliPath.toAbsolutePath().toString() + localCliPath = cliManager.localCli.toAbsolutePath().toString() } val authTask = object : Task.Modal(null, CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.cli.downloader.dialog.title"), false) { @@ -329,11 +328,11 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : fraction = 0.1 } - CoderCLIDownloader().downloadCLI(cliManager.remoteCliPath, cliManager.localCliPath) + cliManager.downloadCLI() if (getOS() != OS.WINDOWS) { pi.fraction = 0.4 val chmodOutput = ProcessExecutor().command("chmod", "+x", localWizardModel.localCliPath).readOutput(true).execute().outputUTF8() - logger.info("chmod +x ${cliManager.localCliPath.toAbsolutePath()} $chmodOutput") + logger.info("chmod +x ${cliManager.localCli.toAbsolutePath()} $chmodOutput") } pi.apply { text = "Configuring coder cli..." @@ -345,6 +344,13 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : pi.fraction = 0.8 val sshConfigOutput = ProcessExecutor().command(localWizardModel.localCliPath, "config-ssh", "--yes", "--use-previous-options").readOutput(true).execute().outputUTF8() logger.info("Result of `${localWizardModel.localCliPath} config-ssh --yes --use-previous-options`: $sshConfigOutput") + + pi.apply { + text = "Remove old coder cli versions..." + fraction = 0.9 + } + cliManager.removeOldCli() + pi.fraction = 1.0 } }