Skip to content
Closed

WIP #20278

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
51 changes: 44 additions & 7 deletions components/ide/jetbrains/launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type LaunchContext struct {
wsInfo *supervisor.WorkspaceInfoResponse

vmOptionsFile string
clientVMOptionsFile string
platformPropertiesFile string
projectDir string
configDir string
Expand Down Expand Up @@ -245,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)
Expand Down Expand Up @@ -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
Expand All @@ -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/<name_version>/[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" {
Expand Down Expand Up @@ -789,7 +801,31 @@ 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 {
if launchCtx.alias != "pycharm" {
return nil
}
vmOptionsPath := launchCtx.clientVMOptionsFile
if err := os.MkdirAll(filepath.Dir(vmOptionsPath), os.ModePerm); err != nil {
return err
}
options, err := readVMOptions(vmOptionsPath)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
options = []string{}
} else {
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
})
return writeVMOptions(vmOptionsPath, newOptions, 0o644)
}

func readVMOptions(vmOptionsPath string) ([]string, error) {
Expand All @@ -800,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
Expand Down Expand Up @@ -902,9 +938,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) {
Expand Down
9 changes: 5 additions & 4 deletions components/ide/jetbrains/launcher/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
Loading