Skip to content

Tune JB backend dev loop #12390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ tasks:
if [ -z "$RUN_GRADLE_TASK" ]; then
read -r -p "Press enter to continue Java gradle task"
fi
leeway exec --package components/supervisor-api/java:lib --package components/gitpod-protocol/java:lib -- ./gradlew --build-cache build
leeway exec --package components/ide/jetbrains/backend-plugin:plugin-latest --package components/ide/jetbrains/gateway-plugin:publish --parallel -- ./gradlew --build-cache buildPlugin
leeway exec --package components/supervisor-api/java:lib --package components/gitpod-protocol/java:lib -- ./gradlew build
leeway exec --package components/ide/jetbrains/backend-plugin:plugin-latest --package components/ide/jetbrains/gateway-plugin:publish --parallel -- ./gradlew buildPlugin
- name: TypeScript
before: scripts/branch-namespace.sh
init: yarn --network-timeout 100000 && yarn build
Expand Down
1 change: 1 addition & 0 deletions WORKSPACE.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defaultArgs:
localAppVersion: unknown
codeCommit: ca48b16256fad72bc239a27bde3dc78a369aafa6
codeQuality: stable
noVerifyJBPlugin: false
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2022.2.1.tar.gz"
golandDownloadUrl: "https://download.jetbrains.com/go/goland-2022.2.2.tar.gz"
pycharmDownloadUrl: "https://download.jetbrains.com/python/pycharm-professional-2022.2.1.tar.gz"
Expand Down
2 changes: 2 additions & 0 deletions components/BUILD.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ packages:
- components/ide/code-desktop:docker
- components/ide/code-desktop:docker-insiders
- components/ide/code:docker
- components/ide/jetbrains/backend-plugin:stable
- components/ide/jetbrains/backend-plugin:latest
- components/ide/jetbrains/image:goland
- components/ide/jetbrains/image:goland-latest
- components/ide/jetbrains/image:intellij
Expand Down
4 changes: 3 additions & 1 deletion components/gitpod-protocol/java/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# See https://stackoverflow.com/a/47607857/961588
systemProp.org.gradle.internal.http.socketTimeout=100000
systemProp.org.gradle.internal.http.connectionTimeout=100000
systemProp.org.gradle.internal.http.connectionTimeout=100000
# See https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_enable
org.gradle.caching=true
58 changes: 52 additions & 6 deletions components/ide/jetbrains/backend-plugin/BUILD.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
packages:
- name: docker
type: generic
argdeps:
- version
deps:
- :stable
- :latest
- name: stable
type: docker
deps:
- :plugin-stable
argdeps:
- imageRepoBase
- version
config:
dockerfile: leeway.Dockerfile
metadata:
helm-component: workspace.desktopIdeImages.jbBackendPlugin
buildArgs:
JETBRAINS_BACKEND_QUALIFIER: stable
image:
- ${imageRepoBase}/ide/jb-backend-plugin:commit-${__git_commit}
- name: latest
type: docker
deps:
- :plugin-latest
argdeps:
- imageRepoBase
- version
config:
dockerfile: leeway.Dockerfile
metadata:
helm-component: workspace.desktopIdeImages.jbBackendPluginLatest
buildArgs:
JETBRAINS_BACKEND_QUALIFIER: latest
image:
- ${imageRepoBase}/ide/jb-backend-plugin:${version}
- ${imageRepoBase}/ide/jb-backend-plugin:commit-${__git_commit}-latest
- name: plugin-stable
type: generic
argdeps:
- noVerifyJBPlugin
deps:
- components/supervisor-api/java:lib
- components/gitpod-protocol/java:lib
Expand All @@ -14,13 +54,17 @@ packages:
- "settings.gradle.kts"
- "src/main/resources/*"
- "src/main/resources-stable/*"
- "build.sh"
env:
- JB_QUALIFIER=stable
- NO_VERIFY_JB_PLUGIN=${noVerifyJBPlugin}
config:
commands:
- ["./gradlew", "-PsupervisorApiProjectPath=components-supervisor-api-java--lib/", "-PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/", "-PenvironmentName=stable", "runPluginVerifier"]
- ["./gradlew", "-PsupervisorApiProjectPath=components-supervisor-api-java--lib/", "-PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/", "-PenvironmentName=stable", "buildPlugin"]
- ["unzip", "./build/distributions/gitpod-remote-0.0.1.zip", "-d", "./build"]
- ["./build.sh"]
- name: plugin-latest
type: generic
argdeps:
- noVerifyJBPlugin
deps:
- components/supervisor-api/java:lib
- components/gitpod-protocol/java:lib
Expand All @@ -34,8 +78,10 @@ packages:
- "settings.gradle.kts"
- "src/main/resources/*"
- "src/main/resources-latest/*"
- "build.sh"
env:
- JB_QUALIFIER=latest
- NO_VERIFY_JB_PLUGIN=${noVerifyJBPlugin}
config:
commands:
- ["./gradlew", "-PsupervisorApiProjectPath=components-supervisor-api-java--lib/", "-PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/", "-PenvironmentName=latest", "runPluginVerifier"]
- ["./gradlew", "-PsupervisorApiProjectPath=components-supervisor-api-java--lib/", "-PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/", "-PenvironmentName=latest", "buildPlugin"]
- ["unzip", "./build/distributions/gitpod-remote-0.0.1.zip", "-d", "./build"]
- ["./build.sh"]
32 changes: 28 additions & 4 deletions components/ide/jetbrains/backend-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ Provides integrations within a Gitpod workspace.
## Development

Please make sure to enable IntelliJ in gitpod.io preferences: https://gitpod.io/preferences
IntelliJ delivers better experience for development of JetBrains plugins. We should as well use it for dogfooding. If
you experience any issues with JetBrains remote dev make sure to report
IntelliJ delivers better experience for development of JetBrains plugins. We should as well use it for dogfooding. If you experience any issues with JetBrains remote dev make sure to report
issues [here](https://youtrack.jetbrains.com/issues?q=project:%20CWM)
under remote development subsystem.

Usually you will need to create a preview environments to try your changes, but if your changes don't touch any other
components beside the backend plugin then you can test against the running workspace:
<img src="https://user-images.githubusercontent.com/3082655/187091748-c58ce156-90b6-4522-83a7-b4312e36d949.png"/>

### Local

Usually you will need to create a preview environments to try your changes, but if your changes don't touch any other components beside the backend plugin then you can test against the running workspace:

- Launch `./launch-dev-server.sh` from `components/ide/jetbrains/backend-plugin`. It builds the backend plugin, and
start another JB backend in the remote debug mode with it against sprint-petclinic project and services of a running
Expand Down Expand Up @@ -43,3 +45,25 @@ Listening for transport dt_socket at address: 54963
for now each thin client is accompanied by another window (main) which directly renders UI from backend. Sometimes
there are bugs when a file will be opened in this window instead of the thin client. It also can be that
the main window is not visible then try to find it in the left top corner and resize. It looks almost like a line.

### Hot deployment

Run `./hot-deploy.sh (latest|stable)` to build and publish the backend plugin image from your dev workspace and
update the IDE config map in a preview environment. After that start a new workspace in preview environment
with corresponding version to try your changes.

### Hot swapping

Run `./hot-swap.sh <workspaceURL>` to build a new backend plugin version corresponding to a workspace running in preview environment,
install a new version in such workspace and restart the JB backend. Reconnect to the restarted JB backend to try new changes.

If you need to change the startup endpoint then run to hot swap it too:
```bash
leeway build components/ide/jetbrains/image/status:hot-swap -DworkspaceUrl=<workspaceURL>
```

### Remote debugging

Run `./remote-debug.sh <workspaceURL> (<localPort>)?` to configure remote debugging in a workpace running in preview environment.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion(minor): spotted this one in the Loom you shared 😄

Suggested change
Run `./remote-debug.sh <workspaceURL> (<localPort>)?` to configure remote debugging in a workpace running in preview environment.
Run `./remote-debug.sh <workspaceURL> (<localPort>)?` to configure remote debugging in a workspace running in preview environment.

It will configure remote debug port, restart the backend and start port forwarding in your dev workspace.
Create a new `Remote JVM Debug` launch configuration with the forwarded port and launch it.
9 changes: 8 additions & 1 deletion components/ide/jetbrains/backend-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ plugins {
}

group = properties("pluginGroup")
version = properties("version")
var pluginVersion = properties("pluginVersion")

val environmentName = properties("environmentName")
if (!environmentName.isNullOrBlank()) {
pluginVersion += "-" + environmentName
}

project(":") {
kotlin {
Expand Down Expand Up @@ -117,4 +120,8 @@ tasks {
runPluginVerifier {
ideVersions.set(properties("pluginVerifierIdeVersions").split(',').map(String::trim).filter(String::isNotEmpty))
}

patchPluginXml {
version.set(pluginVersion)
}
}
12 changes: 12 additions & 0 deletions components/ide/jetbrains/backend-plugin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

if [ "${NO_VERIFY_JB_PLUGIN}" == "true" ]; then
echo "build.sh: skip verify plugin step"
else
./gradlew -PsupervisorApiProjectPath=components-supervisor-api-java--lib/ -PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/ -PenvironmentName="$JB_QUALIFIER" runPluginVerifier
fi
./gradlew -PsupervisorApiProjectPath=components-supervisor-api-java--lib/ -PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/ -PenvironmentName="$JB_QUALIFIER" buildPlugin
unzip ./build/distributions/gitpod-remote.zip -d ./build
4 changes: 3 additions & 1 deletion components/ide/jetbrains/backend-plugin/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=0.0.1
pluginVersion=0.0.1
# Supported environments: stable, latest (via https://github.com/stevesaliman/gradle-properties-plugin)
environmentName=latest
# IntelliJ Platform Artifacts Repositories
Expand All @@ -19,3 +19,5 @@ gitpodProtocolProjectPath=../../../gitpod-protocol/java
# See https://stackoverflow.com/a/47607857/961588
systemProp.org.gradle.internal.http.socketTimeout=100000
systemProp.org.gradle.internal.http.connectionTimeout=100000
# See https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_enable
org.gradle.caching=true
38 changes: 38 additions & 0 deletions components/ide/jetbrains/backend-plugin/hot-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

set -Eeuo pipefail

# This script builds the backend plugin and updates the IDE config map.

qualifier=${1:-latest}
echo "Plugin Qualifier: $qualifier"

# TODO(AK) optimize to produce a new version only if plugin was rebuilt
version="dev-jb-backend-plugin-$(date +%F_T"%H-%M-%S")"
echo "Image Version: $version"

bldfn="/tmp/build-$version.tar.gz"

docker ps &> /dev/null || (echo "You need a working Docker daemon. Maybe set DOCKER_HOST?"; exit 1)
leeway build -DnoVerifyJBPlugin=true -Dversion="$version" -DimageRepoBase=eu.gcr.io/gitpod-core-dev/build .:"$qualifier" --save "$bldfn"
dev_image="$(tar xfO "$bldfn" ./imgnames.txt | head -n1)"
echo "Dev Image: $dev_image"

if [ "$qualifier" == "stable" ]; then
prop="pluginImage"
else
prop="pluginLatestImage"
fi

cf_patch=$(kubectl get cm server-ide-config -o=json | jq '.data."config.json"' |jq -r)
cf_patch=$(echo "$cf_patch" |jq ".ideOptions.options.intellij.$prop = \"$dev_image\"")
cf_patch=$(echo "$cf_patch" |jq ".ideOptions.options.goland.$prop = \"$dev_image\"")
cf_patch=$(echo "$cf_patch" |jq ".ideOptions.options.pycharm.$prop = \"$dev_image\"")
cf_patch=$(echo "$cf_patch" |jq ".ideOptions.options.phpstorm.$prop = \"$dev_image\"")
cf_patch=$(echo "$cf_patch" |jq tostring)
cf_patch="{\"data\": {\"config.json\": $cf_patch}}"

kubectl patch cm server-ide-config --type=merge -p "$cf_patch"
62 changes: 62 additions & 0 deletions components/ide/jetbrains/backend-plugin/hot-swap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

set -Eeuo pipefail

# This script builds the backend plugin, replaces the backend plugin on a running workspace and restarts the JB backend.

workspaceUrl=${1-}
[ -z "$workspaceUrl" ] && echo "Please provide a workspace URL as first argument." && exit 1
workspaceUrl=$(echo "$workspaceUrl" |sed -e "s/\/$//")
echo "URL: $workspaceUrl"

workspaceDesc=$(gpctl workspaces describe "$workspaceUrl" -o=json)

podName=$(echo "$workspaceDesc" | jq .runtime.pod_name -r)
echo "Pod: $podName"

workspaceId=$(echo "$workspaceDesc" | jq .metadata.meta_id -r)
echo "ID: $workspaceId"

clusterHost=$(kubectl exec -it "$podName" -- printenv GITPOD_WORKSPACE_CLUSTER_HOST |sed -e "s/\s//g")
echo "Cluster Host: $clusterHost"

qualifier=$(kubectl exec -it "$podName" -- printenv JETBRAINS_BACKEND_QUALIFIER |sed -e "s/\s//g")
echo "Version Qualifier: $qualifier"

# prepare build
component="gitpod-remote-$qualifier-$(date +%F_T"%H-%M-%S")"
tarDir="/tmp/hot-swap/$component"
mkdir -p "$tarDir"
echo "Build Dir: $tarDir"

# prepare ssh
ownerToken=$(kubectl get pod "$podName" -o=json | jq ".metadata.annotations.\"gitpod\/ownerToken\"" -r)
sshConfig="$tarDir/ssh-config"
echo "Host $workspaceId" > "$sshConfig"
echo " Hostname \"$workspaceId.ssh.$clusterHost\"" >> "$sshConfig"
echo " User \"$workspaceId#$ownerToken\"" >> "$sshConfig"

# build
tarFile="$tarDir/build.tar.gz"
leeway build -DnoVerifyJBPlugin=true .:"plugin-$qualifier" --save "$tarFile"
tar -xf "$tarFile" -C "$tarDir"

# upload
uploadDest="/ide-desktop-plugins/$component"
echo "Upload Dest: $uploadDest"
scp -F "$sshConfig" -r "$tarDir/build/gitpod-remote" "$workspaceId":"$uploadDest"

# link
link="/ide-desktop/backend/plugins/gitpod-remote"
ssh -F "$sshConfig" "$workspaceId" ln -sfn "$uploadDest" "$link"
echo "Link: $link -> $uploadDest"

# restart
ssh -F "$sshConfig" "$workspaceId" curl http://localhost:24000/restart
echo "Restarted: please reconenct to JB backend to try new changes."

# clean up
rm -rf "$tarDir"
14 changes: 14 additions & 0 deletions components/ide/jetbrains/backend-plugin/leeway.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2021 Gitpod GmbH. All rights reserved.
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

FROM alpine:3.16 as base_builder
RUN mkdir /ide-desktop-plugins

# for debugging
# FROM alpine:3.16
FROM scratch
ARG JETBRAINS_BACKEND_QUALIFIER
# ensures right permissions for /ide-desktop-plugins
COPY --from=base_builder --chown=33333:33333 /ide-desktop-plugins/ /ide-desktop-plugins/
COPY --chown=33333:33333 components-ide-jetbrains-backend-plugin--plugin-${JETBRAINS_BACKEND_QUALIFIER}/build/gitpod-remote /ide-desktop-plugins/gitpod-remote/
48 changes: 48 additions & 0 deletions components/ide/jetbrains/backend-plugin/remote-debug.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

# This script configure remote debugging in a workspace running in a preview environment.
# It updates VM options with remote debug agent, restart the JB backend to apply them,
# and start port forwarding of the remote debug port. You can configure `Remote JVM Debug`
# run configuration using the forwarded port.
#
# ./remote-debug.sh <workspaceUrl> (<localPort>)?

workspaceUrl=${1-}
[ -z "$workspaceUrl" ] && echo "Please provide a workspace URL as first argument." && exit 1
workspaceUrl=$(echo "$workspaceUrl" |sed -e "s/\/$//")
echo "URL: $workspaceUrl"

workspaceDesc=$(gpctl workspaces describe "$workspaceUrl" -o=json)

podName=$(echo "$workspaceDesc" | jq .runtime.pod_name -r)
echo "Pod: $podName"

workspaceId=$(echo "$workspaceDesc" | jq .metadata.meta_id -r)
echo "ID: $workspaceId"

clusterHost=$(kubectl exec -it "$podName" -- printenv GITPOD_WORKSPACE_CLUSTER_HOST |sed -e "s/\s//g")
echo "Cluster Host: $clusterHost"

# prepare ssh
ownerToken=$(kubectl get pod "$podName" -o=json | jq ".metadata.annotations.\"gitpod\/ownerToken\"" -r)
sshConfig="/tmp/$workspaceId-ssh-config"
echo "Host $workspaceId" > "$sshConfig"
echo " Hostname \"$workspaceId.ssh.$clusterHost\"" >> "$sshConfig"
echo " User \"$workspaceId#$ownerToken\"" >> "$sshConfig"

while true
do
# configure remote debugging
remotePort=$(ssh -F "$sshConfig" "$workspaceId" curl http://localhost:24000/debug)
if [ -n "$remotePort" ]; then
localPort=${2-$remotePort}
# forward
echo "Forwarding Debug Port: $localPort -> $remotePort"
ssh -F "$sshConfig" -L "$remotePort:localhost:$localPort" "$workspaceId" -N
fi

sleep 1
done
Loading