diff --git a/components/ide/jetbrains/backend-plugin/build.gradle.kts b/components/ide/jetbrains/backend-plugin/build.gradle.kts index bc1866b9c828ce..ed00d831d67beb 100644 --- a/components/ide/jetbrains/backend-plugin/build.gradle.kts +++ b/components/ide/jetbrains/backend-plugin/build.gradle.kts @@ -67,7 +67,11 @@ dependencies { // Read more: https://github.com/JetBrains/gradle-intellij-plugin intellij { pluginName.set(properties("pluginName")) - version.set(properties("platformVersion")) + if (File(properties("localPath")).let { it.exists() && it.isDirectory }) { + localPath.set(properties("localPath")) + } else { + version.set(properties("platformVersion")) + } type.set(properties("platformType")) instrumentCode.set(false) downloadSources.set(properties("platformDownloadSources").toBoolean()) @@ -115,6 +119,7 @@ tasks { } runPluginVerifier { + enabled = false // TODO: Re-enable it when there's a 2022.3 ide version released. ideVersions.set(properties("pluginVerifierIdeVersions").split(',').map(String::trim).filter(String::isNotEmpty)) } } diff --git a/components/ide/jetbrains/backend-plugin/gradle-latest.properties b/components/ide/jetbrains/backend-plugin/gradle-latest.properties index 432be7d91738de..d42b10a9e355a8 100644 --- a/components/ide/jetbrains/backend-plugin/gradle-latest.properties +++ b/components/ide/jetbrains/backend-plugin/gradle-latest.properties @@ -1,9 +1,12 @@ # See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html # for insight into build numbers and IntelliJ Platform versions. -pluginSinceBuild=222 -pluginUntilBuild=222.* +pluginSinceBuild=223 +pluginUntilBuild=223.* # Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl # See https://jb.gg/intellij-platform-builds-list for available build versions. -pluginVerifierIdeVersions=2022.2 +pluginVerifierIdeVersions=2022.3 # Version from "com.jetbrains.intellij.idea" which can be found at https://www.jetbrains.com/intellij-repository/snapshots -platformVersion=222.4167-EAP-CANDIDATE-SNAPSHOT +platformVersion=223.1192-EAP-CANDIDATE-SNAPSHOT +# If you want to try, during development, a snapshot that you need to download because it's not available at https://www.jetbrains.com/intellij-repository/snapshots, run the following command: +# (cd /workspace && rm -rf ide-backend && wget https://download-cdn.jetbrains.com/idea/gateway/idea_tmp/ideaIU-223.2931.tar.gz && tar -xvf ideaIU-223.2931.tar.gz && rm ideaIU-223.2931.tar.gz && mv idea-IU-223.2931 ide-backend) +localPath=/workspace/ide-backend diff --git a/components/ide/jetbrains/backend-plugin/launch-dev-server.sh b/components/ide/jetbrains/backend-plugin/launch-dev-server.sh index c6e7b17b8f5a70..4c2e7db619dc00 100755 --- a/components/ide/jetbrains/backend-plugin/launch-dev-server.sh +++ b/components/ide/jetbrains/backend-plugin/launch-dev-server.sh @@ -6,10 +6,11 @@ set -e set -o pipefail -TEST_BACKEND_DIR=/workspace/ide-backend +TEST_BACKEND_DIR=$(cat gradle-latest.properties | grep localPath= | sed 's/localPath=//') if [ ! -d "$TEST_BACKEND_DIR" ]; then mkdir -p $TEST_BACKEND_DIR - cp -r /ide-desktop/backend/* $TEST_BACKEND_DIR + SNAPSHOT_VERSION=$(cat gradle-latest.properties | grep platformVersion= | sed 's/platformVersion=//') + (cd $TEST_BACKEND_DIR && wget https://www.jetbrains.com/intellij-repository/snapshots/com/jetbrains/intellij/idea/ideaIU/${SNAPSHOT_VERSION}/ideaIU-${SNAPSHOT_VERSION}.zip && unzip ideaIU-${SNAPSHOT_VERSION}.zip && rm ideaIU-${SNAPSHOT_VERSION}.zip) fi TEST_PLUGINS_DIR="$TEST_BACKEND_DIR/plugins" @@ -40,7 +41,7 @@ export IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains export CWM_HOST_STATUS_OVER_HTTP_TOKEN=gitpod # Build and move idea-cli, then overwrite environment variables initially defined by `components/ide/jetbrains/image/leeway.Dockerfile` -IDEA_CLI_DEV_PATH=/ide-desktop/bin/idea-cli-dev +IDEA_CLI_DEV_PATH=$TEST_BACKEND_DIR/bin/idea-cli-dev (cd ../cli && go build -o $IDEA_CLI_DEV_PATH) export EDITOR="$IDEA_CLI_DEV_PATH open" export VISUAL="$EDITOR" diff --git a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodCLIService.kt b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodCLIService.kt index 63b6f39892212f..29060c622d25e2 100644 --- a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodCLIService.kt +++ b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodCLIService.kt @@ -25,13 +25,17 @@ import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.http.FullHttpRequest import io.netty.handler.codec.http.QueryStringDecoder import io.prometheus.client.exporter.common.TextFormat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.jetbrains.ide.RestService import org.jetbrains.io.response import java.io.OutputStreamWriter import java.nio.file.InvalidPathException import java.nio.file.Path -@Suppress("UnstableApiUsage") +@Suppress("UnstableApiUsage", "OPT_IN_USAGE") class GitpodCLIService : RestService() { private val manager = service() @@ -65,7 +69,11 @@ class GitpodCLIService : RestService() { val file = parseFilePath(fileStr) ?: return "invalid file" val shouldWait = getBooleanParameter("wait", urlDecoder) return withClient(request, context) { - CommandLineProcessor.doOpenFileOrProject(file, shouldWait).future.get() + GlobalScope.launch { + withContext(Dispatchers.IO) { + CommandLineProcessor.doOpenFileOrProject(file, shouldWait).future.get() + } + } } } if (operation == "preview") { diff --git a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodClientProjectSessionTracker.kt b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodClientProjectSessionTracker.kt index d00efb4b83584c..205cf0dfac2cab 100644 --- a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodClientProjectSessionTracker.kt +++ b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/GitpodClientProjectSessionTracker.kt @@ -6,7 +6,7 @@ package io.gitpod.jetbrains.remote import com.intellij.codeWithMe.ClientId import com.intellij.ide.BrowserUtil -import com.intellij.idea.StartupUtil +import com.intellij.idea.getServerFutureAsync import com.intellij.notification.NotificationAction import com.intellij.notification.NotificationType import com.intellij.openapi.Disposable @@ -120,7 +120,7 @@ class GitpodClientProjectSessionTracker( // Ignore ports that aren't actually used by the user (e.g. ports used internally by JetBrains IDEs) val backendPort = BuiltInServerManager.getInstance().waitForStart().port - val serverPort = StartupUtil.getServerFuture().await().port + val serverPort = getServerFutureAsync().await()?.port val ignorePorts = listOf(backendPort, serverPort, 5990) val portsStatus = hashMapOf() diff --git a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt index 669c3da12d9226..f3d4a3783703ad 100644 --- a/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt +++ b/components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/latest/GitpodPortForwardingService.kt @@ -9,12 +9,11 @@ import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.project.Project import com.intellij.remoteDev.util.onTerminationOrNow import com.intellij.util.application -import com.jetbrains.codeWithMe.model.RdPortType +import com.jetbrains.rd.platform.codeWithMe.portForwarding.PortType import com.jetbrains.rd.platform.util.lifetime import com.jetbrains.rd.util.lifetime.LifetimeStatus -import com.jetbrains.rdserver.portForwarding.ForwardedPortInfo -import com.jetbrains.rdserver.portForwarding.PortForwardingManager -import com.jetbrains.rdserver.portForwarding.remoteDev.PortEventsProcessor +import com.jetbrains.rdserver.portForwarding.* +import com.jetbrains.rdserver.portForwarding.remoteDev.ControllerPortsInformationProvider import io.gitpod.jetbrains.remote.GitpodManager import io.gitpod.jetbrains.remote.GitpodPortsService import io.gitpod.supervisor.api.Status @@ -32,6 +31,7 @@ class GitpodPortForwardingService(private val project: Project) { } private val portsService = service() + private val controllerPortsInformationProvider = service() init { start() } @@ -85,44 +85,51 @@ class GitpodPortForwardingService(private val project: Project) { } private fun updateForwardedPortsList(response: Status.PortsStatusResponse) { - val portForwardingManager = PortForwardingManager.getInstance(project) - val forwardedPortsList = portForwardingManager.getForwardedPortsWithLabel(FORWARDED_PORT_LABEL) + val portForwardingManager = PortForwardingManager.getInstance() + val forwardedPorts = portForwardingManager.getPortsWithLabel(FORWARDED_PORT_LABEL) for (port in response.portsList) { val hostPort = port.localPort val isServed = port.served + val existingForwardedPort = forwardedPorts.find { it.hostPortNumber == hostPort } - if (isServed && !forwardedPortsList.containsKey(hostPort)) { - val portEventsProcessor = object : PortEventsProcessor { - override fun onPortForwarded(hostPort: Int, clientPort: Int) { - portsService.setForwardedPort(hostPort, clientPort) - thisLogger().info("gitpod: Forwarded port $hostPort to client's port $clientPort.") - } + if (isServed && existingForwardedPort == null) { + portForwardingManager.addPort(Port.ExposedPort( + hostPort, + PortIdentity.MutableNameAndDescription(port.name, port.description), + setOf(FORWARDED_PORT_LABEL), + Property(port.exposed.url), + Property(PortVisibility.PrivatePort()) + )) - override fun onPortForwardingEnded(hostPort: Int) { - thisLogger().info("gitpod: Finished forwarding port $hostPort.") + portForwardingManager.addPort(Port.ForwardedPort( + hostPort, + PortType.HTTP, + PortIdentity.MutableNameAndDescription(port.name, port.description), + setOf(FORWARDED_PORT_LABEL) + )) + + // Note: The code below won't work because the addittion of a port takes some time in background, so it's + // to early to try caching them at this moment. + when (val clientPortState = controllerPortsInformationProvider.getForwardedClientPortState(hostPort)) { + is ClientPortState.Assigned -> { + thisLogger().warn("gitpod: Started forwarding host port $hostPort to client port ${clientPortState.clientPort}.") + portsService.setForwardedPort(hostPort, clientPortState.clientPort) } - - override fun onPortForwardingFailed(hostPort: Int, reason: String) { - thisLogger().error("gitpod: Failed to forward port $hostPort: $reason") + is ClientPortState.FailedToAssign -> { + thisLogger().warn("gitpod: Detected that host port $hostPort failed to be assigned to a client port.") + } + else -> { + thisLogger().warn("gitpod: Detected that host port $hostPort is not assigned to any client port.") } } - - val portInfo = ForwardedPortInfo( - hostPort, - RdPortType.HTTP, - FORWARDED_PORT_LABEL, - emptyList(), - portEventsProcessor - ) - - portForwardingManager.forwardPort(portInfo) } - if (!isServed && forwardedPortsList.containsKey(hostPort)) { - portForwardingManager.removePort(hostPort) + if (!isServed && existingForwardedPort != null) { + thisLogger().warn("hostPort $hostPort stopped being") + portForwardingManager.removePort(existingForwardedPort) portsService.removeForwardedPort(hostPort) - thisLogger().info("gitpod: Stopped forwarding port $hostPort.") + thisLogger().warn("gitpod: Stopped forwarding port $hostPort.") } } } diff --git a/components/ide/jetbrains/image/BUILD.yaml b/components/ide/jetbrains/image/BUILD.yaml index cc21682b5d03d3..ea75eb1df5bb1e 100644 --- a/components/ide/jetbrains/image/BUILD.yaml +++ b/components/ide/jetbrains/image/BUILD.yaml @@ -51,7 +51,7 @@ packages: metadata: helm-component: workspace.desktopIdeImages.intellijLatest buildArgs: - JETBRAINS_DOWNLOAD_QUALIFIER: intellij-latest + JETBRAINS_BACKEND_URL: "https://download-cdn.jetbrains.com/idea/gateway/idea_tmp/ideaIU-223.2931.tar.gz" SUPERVISOR_IDE_CONFIG: supervisor-ide-config_intellij.json JETBRAINS_BACKEND_QUALIFIER: latest image: