From e266df1bc80b7f887cadb294f402ed6eec37a07b Mon Sep 17 00:00:00 2001 From: hwen Date: Wed, 9 Oct 2024 19:32:21 +0800 Subject: [PATCH 1/3] Add client side vmoptions for PyCharm --- components/ide/jetbrains/launcher/main.go | 40 +++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/components/ide/jetbrains/launcher/main.go b/components/ide/jetbrains/launcher/main.go index cd6074558badc5..afbd6f0228203e 100644 --- a/components/ide/jetbrains/launcher/main.go +++ b/components/ide/jetbrains/launcher/main.go @@ -66,6 +66,7 @@ type LaunchContext struct { wsInfo *supervisor.WorkspaceInfoResponse vmOptionsFile string + clientVMOptionsFile string platformPropertiesFile string projectDir string configDir string @@ -542,6 +543,11 @@ func launch(launchCtx *LaunchContext) { if err != nil { log.WithError(err).Error("failed to parse .gitpod.yml") } + userHomeDir, err := os.UserHomeDir() + if err != nil { + log.WithError(err).Error("failed to get user home dir") + userHomeDir = "~" + } // configure vmoptions idePrefix := launchCtx.alias @@ -550,10 +556,16 @@ func launch(launchCtx *LaunchContext) { } // [idea64|goland64|pycharm64|phpstorm64].vmoptions launchCtx.vmOptionsFile = fmt.Sprintf(launchCtx.backendDir+"/bin/%s64.vmoptions", idePrefix) + // ~/.config/JetBrains//[idea64|goland64|pycharm64|phpstorm64].vmoptions + launchCtx.clientVMOptionsFile = fmt.Sprintf("%s/.config/JetBrains/%s/%s64.vmoptions", userHomeDir, launchCtx.info.DataDirectoryName, idePrefix) + err = configureVMOptions(gitpodConfig, launchCtx.alias, launchCtx.vmOptionsFile) if err != nil { log.WithError(err).Error("failed to configure vmoptions") } + if err := configureClientSideVMOptions(launchCtx); err != nil { + log.WithError(err).Error("failed to configure client side vmoptions") + } var riderSolutionFile string if launchCtx.alias == "rider" { @@ -792,6 +804,27 @@ func configureVMOptions(config *gitpod.GitpodConfig, alias string, vmOptionsPath return writeVMOptions(vmOptionsPath, newOptions) } +func configureClientSideVMOptions(launchCtx *LaunchContext) error { + if launchCtx.alias != "pycharm" { + return nil + } + // ENT-849 + // Add -Dide.browser.jcef.enabled=false for PyCharm + vmOptionsPath := launchCtx.clientVMOptionsFile + options, err := readVMOptions(vmOptionsPath) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + options = []string{} + } else { + return err + } + } + newOptions := deduplicateVMOption(options, []string{"-Dide.browser.jcef.enabled=false"}, func(l, r string) bool { + return l == r + }) + return writeVMOptions(vmOptionsPath, newOptions) +} + func readVMOptions(vmOptionsPath string) ([]string, error) { content, err := os.ReadFile(vmOptionsPath) if err != nil { @@ -902,9 +935,10 @@ func updateVMOptions( } */ type ProductInfo struct { - BuildNumber string `json:"buildNumber"` - Version string `json:"version"` - ProductCode string `json:"productCode"` + BuildNumber string `json:"buildNumber"` + Version string `json:"version"` + ProductCode string `json:"productCode"` + DataDirectoryName string `json:"dataDirectoryName"` } func resolveProductInfo(backendDir string) (*ProductInfo, error) { From 359934c65742b641d8582dac0d92613e04462d06 Mon Sep 17 00:00:00 2001 From: Huiwen Date: Wed, 9 Oct 2024 11:55:42 +0000 Subject: [PATCH 2/3] Mkdir -p --- components/ide/jetbrains/launcher/main.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/ide/jetbrains/launcher/main.go b/components/ide/jetbrains/launcher/main.go index afbd6f0228203e..add507e59fe123 100644 --- a/components/ide/jetbrains/launcher/main.go +++ b/components/ide/jetbrains/launcher/main.go @@ -808,9 +808,10 @@ func configureClientSideVMOptions(launchCtx *LaunchContext) error { if launchCtx.alias != "pycharm" { return nil } - // ENT-849 - // Add -Dide.browser.jcef.enabled=false for PyCharm vmOptionsPath := launchCtx.clientVMOptionsFile + if err := os.MkdirAll(filepath.Dir(vmOptionsPath), 0755); err != nil { + return err + } options, err := readVMOptions(vmOptionsPath) if err != nil { if errors.Is(err, fs.ErrNotExist) { @@ -819,6 +820,8 @@ func configureClientSideVMOptions(launchCtx *LaunchContext) error { return err } } + // ENT-849 + // Add -Dide.browser.jcef.enabled=false for PyCharm newOptions := deduplicateVMOption(options, []string{"-Dide.browser.jcef.enabled=false"}, func(l, r string) bool { return l == r }) From fea7d78cf34b73101251db8f550a4f66d23c6171 Mon Sep 17 00:00:00 2001 From: Huiwen Date: Wed, 9 Oct 2024 14:12:00 +0000 Subject: [PATCH 3/3] Correct file perm --- components/ide/jetbrains/launcher/main.go | 12 ++++++------ components/ide/jetbrains/launcher/main_test.go | 9 +++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/components/ide/jetbrains/launcher/main.go b/components/ide/jetbrains/launcher/main.go index add507e59fe123..569f57838c2b2e 100644 --- a/components/ide/jetbrains/launcher/main.go +++ b/components/ide/jetbrains/launcher/main.go @@ -246,7 +246,7 @@ func serve(launchCtx *LaunchContext) { options = deduplicateVMOption(options, debugOptions, func(l, r string) bool { return strings.HasPrefix(l, debugAgentPrefix) && strings.HasPrefix(r, debugAgentPrefix) }) - err = writeVMOptions(launchCtx.vmOptionsFile, options) + err = writeVMOptions(launchCtx.vmOptionsFile, options, 0) if err != nil { log.WithError(err).Error("failed to configure debug agent") http.Error(w, err.Error(), http.StatusInternalServerError) @@ -801,7 +801,7 @@ func configureVMOptions(config *gitpod.GitpodConfig, alias string, vmOptionsPath return err } newOptions := updateVMOptions(config, alias, options) - return writeVMOptions(vmOptionsPath, newOptions) + return writeVMOptions(vmOptionsPath, newOptions, 0) } func configureClientSideVMOptions(launchCtx *LaunchContext) error { @@ -809,7 +809,7 @@ func configureClientSideVMOptions(launchCtx *LaunchContext) error { return nil } vmOptionsPath := launchCtx.clientVMOptionsFile - if err := os.MkdirAll(filepath.Dir(vmOptionsPath), 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(vmOptionsPath), os.ModePerm); err != nil { return err } options, err := readVMOptions(vmOptionsPath) @@ -825,7 +825,7 @@ func configureClientSideVMOptions(launchCtx *LaunchContext) error { newOptions := deduplicateVMOption(options, []string{"-Dide.browser.jcef.enabled=false"}, func(l, r string) bool { return l == r }) - return writeVMOptions(vmOptionsPath, newOptions) + return writeVMOptions(vmOptionsPath, newOptions, 0o644) } func readVMOptions(vmOptionsPath string) ([]string, error) { @@ -836,10 +836,10 @@ func readVMOptions(vmOptionsPath string) ([]string, error) { return strings.Fields(string(content)), nil } -func writeVMOptions(vmOptionsPath string, vmoptions []string) error { +func writeVMOptions(vmOptionsPath string, vmoptions []string, perm os.FileMode) error { // vmoptions file should end with a newline content := strings.Join(vmoptions, "\n") + "\n" - return os.WriteFile(vmOptionsPath, []byte(content), 0) + return os.WriteFile(vmOptionsPath, []byte(content), perm) } // deduplicateVMOption append new VMOptions onto old VMOptions and remove any duplicated leftmost options diff --git a/components/ide/jetbrains/launcher/main_test.go b/components/ide/jetbrains/launcher/main_test.go index 12c9710898c8ff..89515053d85044 100644 --- a/components/ide/jetbrains/launcher/main_test.go +++ b/components/ide/jetbrains/launcher/main_test.go @@ -50,11 +50,12 @@ func TestUpdateVMOptions(t *testing.T) { {"idea64.vmoptions (GITPOD_CPU_COUNT 2)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx4096m", "GITPOD_CPU_COUNT": "12"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-XX:ActiveProcessorCount=12\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, {"goland64.vmoptions", "goland", nil, "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true"}, {"idea64.vmoptions", "intellij", nil, "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, - {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx2048m"}, "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2048m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, - {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx4096m"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, - {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"INTELLIJ_VMOPTIONS": "-Xmx4096m -XX:MaxRAMPercentage=75"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-XX:MaxRAMPercentage=75\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, - {"goland64.vmoptions (GOLAND_VMOPTIONS env set with conflicting options)", "goland", map[string]string{"GOLAND_VMOPTIONS": "-ea -XX:+IgnoreUnrecognizedVMOptions -XX:MaxRAMPercentage=75 -XX:MaxRAMPercentage=50"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-ea\n-XX:+IgnoreUnrecognizedVMOptions\n-XX:+UseContainerSupport\n-XX:MaxRAMPercentage=50"}, + {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"GITPOD_CPU_COUNT": "", "INTELLIJ_VMOPTIONS": "-Xmx2048m"}, "-Xms128m\n-Xmx750m\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2048m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, + {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"GITPOD_CPU_COUNT": "", "INTELLIJ_VMOPTIONS": "-Xmx4096m"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, + {"idea64.vmoptions (INTELLIJ_VMOPTIONS env set)", "intellij", map[string]string{"GITPOD_CPU_COUNT": "", "INTELLIJ_VMOPTIONS": "-Xmx4096m -XX:MaxRAMPercentage=75"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx4096m\n-XX:MaxRAMPercentage=75\n-Dsun.tools.attach.tmp.only=true\n-XX:+UseContainerSupport\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-Djdk.configure.existing=true"}, + {"goland64.vmoptions (GOLAND_VMOPTIONS env set with conflicting options)", "goland", map[string]string{"GITPOD_CPU_COUNT": "", "GOLAND_VMOPTIONS": "-ea -XX:+IgnoreUnrecognizedVMOptions -XX:MaxRAMPercentage=75 -XX:MaxRAMPercentage=50"}, "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true", "-Xms128m\n-Xmx2g\n-Dsun.tools.attach.tmp.only=true\n-Dfreeze.reporter.profiling=false\n-Dgtw.disable.exit.dialog=true\n-ea\n-XX:+IgnoreUnrecognizedVMOptions\n-XX:+UseContainerSupport\n-XX:MaxRAMPercentage=50"}, } + os.Unsetenv("GITPOD_CPU_COUNT") for _, test := range tests { // compare vmoptions string content equality (i.e. split into slices and compare ignore order) lessFunc := func(a, b string) bool { return a < b }