Skip to content

Commit b704c9c

Browse files
jeanp413roboquat
andauthored
[JB] Properly overide jb config and cache folder locations (#19394)
* Revert "Revert jb stable images to 2023.3.2 (#19389)" This reverts commit 49269b9. * Update platform properties file * Fix * Update Platform Version of JetBrains Gateway Plugin (Stable) to 233.14015-EAP-CANDIDATE-SNAPSHOT * [JetBrains] Update IDE images to new build version * 💄 * Fix plugin installation and config sync * Check before updating platform properties file * Fix * 💄 * Update jb integration test * Fix test * Add unit test --------- Co-authored-by: Robo Quat <[email protected]>
1 parent 85274ef commit b704c9c

File tree

6 files changed

+149
-49
lines changed

6 files changed

+149
-49
lines changed

WORKSPACE.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ defaultArgs:
1111
codeVersion: 1.86.0
1212
codeQuality: stable
1313
noVerifyJBPlugin: false
14-
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2023.3.2.tar.gz"
15-
golandDownloadUrl: "https://download.jetbrains.com/go/goland-2023.3.2.tar.gz"
16-
pycharmDownloadUrl: "https://download.jetbrains.com/python/pycharm-professional-2023.3.2.tar.gz"
17-
phpstormDownloadUrl: "https://download.jetbrains.com/webide/PhpStorm-2023.3.2.tar.gz"
18-
rubymineDownloadUrl: "https://download.jetbrains.com/ruby/RubyMine-2023.3.2.tar.gz"
19-
webstormDownloadUrl: "https://download.jetbrains.com/webstorm/WebStorm-2023.3.2.tar.gz"
20-
riderDownloadUrl: "https://download.jetbrains.com/rider/JetBrains.Rider-2023.3.2.tar.gz"
21-
clionDownloadUrl: "https://download.jetbrains.com/cpp/CLion-2023.3.2.tar.gz"
14+
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2023.3.3.tar.gz"
15+
golandDownloadUrl: "https://download.jetbrains.com/go/goland-2023.3.3.tar.gz"
16+
pycharmDownloadUrl: "https://download.jetbrains.com/python/pycharm-professional-2023.3.3.tar.gz"
17+
phpstormDownloadUrl: "https://download.jetbrains.com/webide/PhpStorm-2023.3.3.tar.gz"
18+
rubymineDownloadUrl: "https://download.jetbrains.com/ruby/RubyMine-2023.3.3.tar.gz"
19+
webstormDownloadUrl: "https://download.jetbrains.com/webstorm/WebStorm-2023.3.3.tar.gz"
20+
riderDownloadUrl: "https://download.jetbrains.com/rider/JetBrains.Rider-2023.3.3.tar.gz"
21+
clionDownloadUrl: "https://download.jetbrains.com/cpp/CLion-2023.3.3.tar.gz"
2222
jbBackendVersion: "latest"
2323
dockerVersion: "20.10.24"
2424
dockerComposeVersion: "2.23.3-gitpod.1"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# this file is auto generated by components/ide/jetbrains/image/gha-update-image/index.js
22
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
33
# for insight into build numbers and IntelliJ Platform versions.
4-
pluginSinceBuild=233.13135
4+
pluginSinceBuild=233.14015
55
pluginUntilBuild=233.*
66
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
77
# See https://jb.gg/intellij-platform-builds-list for available build versions.
88
pluginVerifierIdeVersions=2023.3
99
# Version from "com.jetbrains.intellij.idea" which can be found at https://www.jetbrains.com/intellij-repository/snapshots
10-
platformVersion=233.13135-EAP-CANDIDATE-SNAPSHOT
10+
platformVersion=233.14015-EAP-CANDIDATE-SNAPSHOT
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
22
# for insight into build numbers and IntelliJ Platform versions.
3-
pluginSinceBuild=233.13135
3+
pluginSinceBuild=233.14015
44
pluginUntilBuild=233.*
55
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
66
# See https://jb.gg/intellij-platform-builds-list for available build versions.
77
pluginVerifierIdeVersions=2023.3
88
# Version from "com.jetbrains.gateway" which can be found at https://www.jetbrains.com/intellij-repository/snapshots
9-
platformVersion=233.13135-EAP-CANDIDATE-SNAPSHOT
9+
platformVersion=233.14015-EAP-CANDIDATE-SNAPSHOT

components/ide/jetbrains/launcher/main.go

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ type LaunchContext struct {
6565
backendVersion *version.Version
6666
wsInfo *supervisor.WorkspaceInfoResponse
6767

68-
vmOptionsFile string
69-
projectDir string
70-
configDir string
71-
systemDir string
72-
projectConfigDir string
73-
projectContextDir string
74-
riderSolutionFile string
68+
vmOptionsFile string
69+
platformPropertiesFile string
70+
projectDir string
71+
configDir string
72+
systemDir string
73+
projectContextDir string
74+
riderSolutionFile string
7575

7676
env []string
7777
}
@@ -462,34 +462,36 @@ func launch(launchCtx *LaunchContext) {
462462
}
463463

464464
launchCtx.projectDir = projectDir
465-
launchCtx.configDir = fmt.Sprintf("/workspace/.config/JetBrains%s", launchCtx.qualifier)
466-
launchCtx.systemDir = fmt.Sprintf("/workspace/.cache/JetBrains%s", launchCtx.qualifier)
465+
launchCtx.configDir = fmt.Sprintf("/workspace/.config/JetBrains%s/RemoteDev-%s", launchCtx.qualifier, launchCtx.info.ProductCode)
466+
launchCtx.systemDir = fmt.Sprintf("/workspace/.cache/JetBrains%s/RemoteDev-%s", launchCtx.qualifier, launchCtx.info.ProductCode)
467467
launchCtx.riderSolutionFile = riderSolutionFile
468468
launchCtx.projectContextDir = resolveProjectContextDir(launchCtx)
469-
launchCtx.projectConfigDir = fmt.Sprintf("%s/RemoteDev-%s/%s", launchCtx.configDir, launchCtx.info.ProductCode, strings.ReplaceAll(launchCtx.projectContextDir, "/", "_"))
470469

471-
alreadySync, err := syncInitialContent(launchCtx, Options)
470+
launchCtx.platformPropertiesFile = launchCtx.backendDir + "/bin/idea.properties"
471+
_, err = configurePlatformProperties(launchCtx.platformPropertiesFile, launchCtx.configDir, launchCtx.systemDir)
472+
if err != nil {
473+
log.WithError(err).Error("failed to update platform properties file")
474+
}
475+
476+
_, err = syncInitialContent(launchCtx, Options)
472477
if err != nil {
473478
log.WithError(err).Error("failed to sync initial options")
474479
}
475480

476-
launchCtx.env = resolveLaunchContextEnv(launchCtx.configDir, launchCtx.systemDir, !alreadySync)
481+
launchCtx.env = resolveLaunchContextEnv()
477482

478483
_, err = syncInitialContent(launchCtx, Plugins)
479484
if err != nil {
480485
log.WithError(err).Error("failed to sync initial plugins")
481486
}
482487

483488
// install project plugins
484-
version_2022_1, _ := version.NewVersion("2022.1")
485-
if version_2022_1.LessThanOrEqual(launchCtx.backendVersion) {
486-
err = installPlugins(gitpodConfig, launchCtx)
487-
installPluginsCost := time.Now().Local().Sub(launchCtx.startTime).Milliseconds()
488-
if err != nil {
489-
log.WithError(err).WithField("cost", installPluginsCost).Error("installing repo plugins: done")
490-
} else {
491-
log.WithField("cost", installPluginsCost).Info("installing repo plugins: done")
492-
}
489+
err = installPlugins(gitpodConfig, launchCtx)
490+
installPluginsCost := time.Now().Local().Sub(launchCtx.startTime).Milliseconds()
491+
if err != nil {
492+
log.WithError(err).WithField("cost", installPluginsCost).Error("installing repo plugins: done")
493+
} else {
494+
log.WithField("cost", installPluginsCost).Info("installing repo plugins: done")
493495
}
494496

495497
// install gitpod plugin
@@ -586,7 +588,7 @@ func resolveUserEnvs() (userEnvs []string, err error) {
586588
return
587589
}
588590

589-
func resolveLaunchContextEnv(configDir string, systemDir string, enableNewUI bool) []string {
591+
func resolveLaunchContextEnv() []string {
590592
var launchCtxEnv []string
591593
userEnvs, err := resolveUserEnvs()
592594
if err == nil {
@@ -596,21 +598,14 @@ func resolveLaunchContextEnv(configDir string, systemDir string, enableNewUI boo
596598
launchCtxEnv = os.Environ()
597599
}
598600

599-
// Set default config and system directories under /workspace to preserve between restarts
600-
launchCtxEnv = append(launchCtxEnv,
601-
// Set default config and system directories under /workspace to preserve between restarts
602-
fmt.Sprintf("IJ_HOST_CONFIG_BASE_DIR=%s", configDir),
603-
fmt.Sprintf("IJ_HOST_SYSTEM_BASE_DIR=%s", systemDir),
604-
)
605-
606601
// instead put them into /ide-desktop/${alias}${qualifier}/backend/bin/idea64.vmoptions
607602
// otherwise JB will complain to a user on each startup
608603
// by default remote dev already set -Xmx2048m, see /ide-desktop/${alias}${qualifier}/backend/plugins/remote-dev-server/bin/launcher.sh
609604
launchCtxEnv = append(launchCtxEnv, "JAVA_TOOL_OPTIONS=")
610605

611-
if enableNewUI {
612-
launchCtxEnv = append(launchCtxEnv, "REMOTE_DEV_NEW_UI_ENABLED=1")
613-
}
606+
// Force it to be disabled as we update platform properties file already
607+
// TODO: Some ides have it enabled by default still, check pycharm and remove next release
608+
launchCtxEnv = append(launchCtxEnv, "REMOTE_DEV_LEGACY_PER_PROJECT_CONFIGS=0")
614609

615610
log.WithField("env", strings.Join(launchCtxEnv, "\n")).Info("resolved launch env")
616611

@@ -637,6 +632,52 @@ func handleSignal() {
637632
log.Info("asked IDE to terminate")
638633
}
639634

635+
func configurePlatformProperties(platformOptionsPath string, configDir string, systemDir string) (bool, error) {
636+
buffer, err := os.ReadFile(platformOptionsPath)
637+
if err != nil {
638+
return false, err
639+
}
640+
641+
content := string(buffer)
642+
643+
updated, content := updatePlatformProperties(content, configDir, systemDir)
644+
645+
if updated {
646+
return true, os.WriteFile(platformOptionsPath, []byte(content), 0)
647+
}
648+
649+
return false, nil
650+
}
651+
652+
func updatePlatformProperties(content string, configDir string, systemDir string) (bool, string) {
653+
lines := strings.Split(content, "\n")
654+
configMap := make(map[string]bool)
655+
for _, v := range lines {
656+
v = strings.TrimSpace(v)
657+
if v != "" && !strings.HasPrefix(v, "#") {
658+
key, _, found := strings.Cut(v, "=")
659+
if found {
660+
configMap[key] = true
661+
}
662+
}
663+
}
664+
665+
updated := false
666+
667+
if _, found := configMap["idea.config.path"]; !found {
668+
updated = true
669+
content = strings.Join([]string{
670+
content,
671+
fmt.Sprintf("idea.config.path=%s", configDir),
672+
fmt.Sprintf("idea.plugins.path=%s", configDir+"/plugins"),
673+
fmt.Sprintf("idea.system.path=%s", systemDir),
674+
fmt.Sprintf("idea.log.path=%s", systemDir+"/log"),
675+
}, "\n")
676+
}
677+
678+
return updated, content
679+
}
680+
640681
func configureVMOptions(config *gitpod.GitpodConfig, alias string, vmOptionsPath string) error {
641682
options, err := readVMOptions(vmOptionsPath)
642683
if err != nil {
@@ -647,7 +688,7 @@ func configureVMOptions(config *gitpod.GitpodConfig, alias string, vmOptionsPath
647688
}
648689

649690
func readVMOptions(vmOptionsPath string) ([]string, error) {
650-
content, err := ioutil.ReadFile(vmOptionsPath)
691+
content, err := os.ReadFile(vmOptionsPath)
651692
if err != nil {
652693
return nil, err
653694
}
@@ -657,7 +698,7 @@ func readVMOptions(vmOptionsPath string) ([]string, error) {
657698
func writeVMOptions(vmOptionsPath string, vmoptions []string) error {
658699
// vmoptions file should end with a newline
659700
content := strings.Join(vmoptions, "\n") + "\n"
660-
return ioutil.WriteFile(vmOptionsPath, []byte(content), 0)
701+
return os.WriteFile(vmOptionsPath, []byte(content), 0)
661702
}
662703

663704
// deduplicateVMOption append new VMOptions onto old VMOptions and remove any duplicated leftmost options
@@ -844,7 +885,7 @@ func syncPlugin(file fs.FileInfo, srcDir, destDir string) error {
844885
}
845886

846887
func ensureInitialSyncDest(launchCtx *LaunchContext, target SyncTarget) (string, error, bool) {
847-
targetDestDir := launchCtx.projectConfigDir
888+
targetDestDir := launchCtx.configDir
848889
if target == Plugins {
849890
targetDestDir = launchCtx.backendDir
850891
}
@@ -964,7 +1005,7 @@ func installPlugins(config *gitpod.GitpodConfig, launchCtx *LaunchContext) error
9641005
installErr := cmd.Run()
9651006

9661007
// delete alien_plugins.txt to suppress 3rd-party plugins consent on startup to workaround backend startup freeze
967-
err = os.Remove(launchCtx.projectConfigDir + "/alien_plugins.txt")
1008+
err = os.Remove(launchCtx.configDir + "/alien_plugins.txt")
9681009
if err != nil && !os.IsNotExist(err) && !strings.Contains(err.Error(), "no such file or directory") {
9691010
log.WithError(err).Error("failed to suppress 3rd-party plugins consent")
9701011
}

components/ide/jetbrains/launcher/main_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,28 @@ func TestUpdateVMOptions(t *testing.T) {
7575
})
7676
}
7777
}
78+
79+
func TestUpdatePlatformProperties(t *testing.T) {
80+
platformProperties := `#---------------------------------------------------------------------
81+
# Uncomment this option if you want to customize a path to the settings directory.
82+
#---------------------------------------------------------------------
83+
# idea.config.path=${user.home}/.IntelliJIdea/config
84+
85+
86+
shared.indexes.download.auto.consent=true
87+
`
88+
configDir := "/workspace/.config/JetBrains/RemoteDev-IU"
89+
systemDir := "/workspace/.cache/JetBrains/RemoteDev-IU"
90+
91+
t.Run("updatePlatformProperties multiple time should be stable", func(t *testing.T) {
92+
93+
updated, content := updatePlatformProperties(platformProperties, configDir, systemDir)
94+
assert.Equal(t, true, updated)
95+
assert.Equal(t, true, strings.Contains(content, "idea.config.path=/workspace/.config/JetBrains/RemoteDev-IU"))
96+
for i := 0; i < 5; i++ {
97+
updated, newContent := updatePlatformProperties(content, configDir, systemDir)
98+
assert.Equal(t, false, updated)
99+
assert.Equal(t, content, newContent)
100+
}
101+
})
102+
}

test/tests/ide/jetbrains/gateway_test.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
2323
supervisor "github.com/gitpod-io/gitpod/supervisor/api"
24+
agent "github.com/gitpod-io/gitpod/test/pkg/agent/workspace/api"
2425
"github.com/gitpod-io/gitpod/test/pkg/integration"
2526
wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"
2627
"github.com/google/go-github/v42/github"
@@ -150,6 +151,39 @@ func JetBrainsIDETest(ctx context.Context, t *testing.T, cfg *envconf.Config, id
150151
t.Fatal(err)
151152
}
152153

154+
if ide == "intellij" {
155+
t.Logf("Check idea.log file correct location")
156+
rsa, closer, err := integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(), integration.WithInstanceID(info.LatestInstance.ID), integration.WithWorkspacekitLift(true))
157+
if err != nil {
158+
t.Fatal(err)
159+
}
160+
defer rsa.Close()
161+
integration.DeferCloser(t, closer)
162+
163+
qualifier := ""
164+
if useLatest {
165+
qualifier = "-latest"
166+
}
167+
168+
var resp agent.ExecResponse
169+
err = rsa.Call("WorkspaceAgent.Exec", &agent.ExecRequest{
170+
Dir: "/",
171+
Command: "bash",
172+
Args: []string{
173+
"-c",
174+
fmt.Sprintf("test -f /workspace/.cache/JetBrains%s/RemoteDev-IU/log/idea.log", qualifier),
175+
},
176+
}, &resp)
177+
178+
if err != nil {
179+
t.Fatal(err)
180+
}
181+
182+
if resp.ExitCode != 0 {
183+
t.Fatal("idea.log file not found in the expected location")
184+
}
185+
}
186+
153187
ts := oauth2.StaticTokenSource(
154188
&oauth2.Token{AccessToken: roboquatToken},
155189
)
@@ -273,7 +307,7 @@ func TestIntellij(t *testing.T) {
273307
Assess("it can let JetBrains Gateway connect", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {
274308
ctx, cancel := context.WithTimeout(testCtx, 30*time.Minute)
275309
defer cancel()
276-
JetBrainsIDETest(ctx, t, cfg, "intellij", "https://github.com/gitpod-samples/spring-petclinic")
310+
JetBrainsIDETest(ctx, t, cfg, "intellij", "https://github.com/jeanp413/spring-petclinic")
277311
return testCtx
278312
}).
279313
Feature()

0 commit comments

Comments
 (0)