From 931eed4dd109518d0714677d2430e17189ab4798 Mon Sep 17 00:00:00 2001 From: Manuel Alejandro de Brito Fontes Date: Tue, 20 Sep 2022 17:18:56 -0300 Subject: [PATCH] Enable configuration of core dumps in .gitpod.yml files --- .../gitpod-protocol/data/gitpod-schema.json | 19 ++++++++++++++++ components/gitpod-protocol/src/protocol.ts | 7 ++++++ .../server/src/workspace/workspace-starter.ts | 13 +++++++++++ components/workspacekit/cmd/rings.go | 22 ++++++++++++++----- components/ws-manager/pkg/manager/create.go | 3 ++- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/components/gitpod-protocol/data/gitpod-schema.json b/components/gitpod-protocol/data/gitpod-schema.json index 911828bf0c5e3b..d3f2054bb8502e 100644 --- a/components/gitpod-protocol/data/gitpod-schema.json +++ b/components/gitpod-protocol/data/gitpod-schema.json @@ -282,6 +282,25 @@ "type": "boolean", "deprecationMessage": "The 'experimentalNetwork' property is deprecated.", "description": "Experimental network configuration in workspaces (deprecated). Enabled by default" + }, + "coreDump": { + "type": "object", + "description": "Configure the default action of certain signals is to cause a process to terminate and produce a core dump file, a file containing an image of the process's memory at the time of termination. Disabled by default.", + "deprecationMessage": "The 'coreDump' property is experimental.", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "softLimit": { + "type": "number", + "description": "upper limit on the size of the core dump file that will be produced if it receives a core dump signal" + }, + "hardLimit": { + "type": "number", + "description": "the hard limit acts as a ceiling for the soft limit. For more details please check https://man7.org/linux/man-pages/man2/getrlimit.2.html" + } + } } }, "additionalProperties": false, diff --git a/components/gitpod-protocol/src/protocol.ts b/components/gitpod-protocol/src/protocol.ts index 087f03e68e7fea..4f0226fedc49f0 100644 --- a/components/gitpod-protocol/src/protocol.ts +++ b/components/gitpod-protocol/src/protocol.ts @@ -804,6 +804,12 @@ export interface RepositoryCloneInformation { checkoutLocation?: string; } +export interface CoreDumpConfig { + enabled?: boolean; + softLimit?: number; + hardLimit?: number; +} + export interface WorkspaceConfig { mainConfiguration?: string; additionalRepositories?: RepositoryCloneInformation[]; @@ -816,6 +822,7 @@ export interface WorkspaceConfig { github?: GithubAppConfig; vscode?: VSCodeConfig; jetbrains?: JetBrainsConfig; + coreDump?: CoreDumpConfig; /** deprecated. Enabled by default **/ experimentalNetwork?: boolean; diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts index d5c9f35da84f50..287e4275f128a0 100644 --- a/components/server/src/workspace/workspace-starter.ts +++ b/components/server/src/workspace/workspace-starter.ts @@ -1417,6 +1417,19 @@ export class WorkspaceStarter { dotfileEnv.setValue(user.additionalData?.dotfileRepo || ""); envvars.push(dotfileEnv); + if (workspace.config.coreDump?.enabled) { + // default core dump size is 1GB + const defaultLimit:number=10240000; + + const rLimitCore = new EnvironmentVariable(); + rLimitCore.setName("GITPOD_RLIMIT_CORE"); + rLimitCore.setValue(JSON.stringify({ + softLimit: workspace.config.coreDump?.softLimit || defaultLimit, + hardLimit: workspace.config.coreDump?.hardLimit || defaultLimit, + })); + envvars.push(rLimitCore); + } + const createGitpodTokenPromise = (async () => { const scopes = this.createDefaultGitpodAPITokenScopes(workspace, instance); const token = crypto.randomBytes(30).toString("hex"); diff --git a/components/workspacekit/cmd/rings.go b/components/workspacekit/cmd/rings.go index b3b85d93f26dbe..4365822ae41553 100644 --- a/components/workspacekit/cmd/rings.go +++ b/components/workspacekit/cmd/rings.go @@ -829,12 +829,24 @@ var ring2Cmd = &cobra.Command{ return } - rlimit := syscall.Rlimit{ - Cur: 0, - Max: 0, + type fakeRlimit struct { + Cur uint64 `json:"softLimit"` + Max uint64 `json:"hardLimit"` } - if err := syscall.Setrlimit(syscall.RLIMIT_CORE, &rlimit); err != nil { - log.WithError(err).Error("cannot disable core dumps") + + rLimitValue := os.Getenv("GITPOD_RLIMIT_CORE") + var rLimitCore fakeRlimit + err = json.Unmarshal([]byte(rLimitValue), &rLimitCore) + if err != nil { + log.WithError(err).WithField("data", rLimitValue).Error("cannot deserialize GITPOD_RLIMIT_CORE") + } + + err = unix.Setrlimit(unix.RLIMIT_CORE, &unix.Rlimit{ + Cur: rLimitCore.Cur, + Max: rLimitCore.Max, + }) + if err != nil { + log.WithError(err).WithField("rlimit", rLimitCore).Error("cannot configure core dumps") } // Now that we're in our new root filesystem, including proc and all, we can load diff --git a/components/ws-manager/pkg/manager/create.go b/components/ws-manager/pkg/manager/create.go index 0c1445833fdc18..7b63c517f5232b 100644 --- a/components/ws-manager/pkg/manager/create.go +++ b/components/ws-manager/pkg/manager/create.go @@ -802,7 +802,8 @@ func (m *Manager) createWorkspaceEnvironment(startContext *startWorkspaceContext "GITPOD_RESOLVED_EXTENSIONS", "GITPOD_EXTERNAL_EXTENSIONS", "GITPOD_WORKSPACE_CLASS_INFO", - "GITPOD_IDE_ALIAS": + "GITPOD_IDE_ALIAS", + "GITPOD_RLIMIT_CORE": // these variables are allowed - don't skip them default: if strings.HasPrefix(e.Name, "GITPOD_") {