diff --git a/components/image-builder-bob/BUILD.yaml b/components/image-builder-bob/BUILD.yaml index c55982451cf931..b2427b0bc8d0e3 100644 --- a/components/image-builder-bob/BUILD.yaml +++ b/components/image-builder-bob/BUILD.yaml @@ -20,7 +20,6 @@ packages: - ide-startup.sh deps: - :app - - components/image-builder-mk3/workspace-image-layer:pack config: argdeps: - imageRepoBase diff --git a/components/image-builder-bob/leeway.Dockerfile b/components/image-builder-bob/leeway.Dockerfile index 4a137b667a6055..297717a9b00e16 100644 --- a/components/image-builder-bob/leeway.Dockerfile +++ b/components/image-builder-bob/leeway.Dockerfile @@ -14,13 +14,6 @@ RUN apk --no-cache add sudo bash \ COPY components-image-builder-bob--app/bob /app/ RUN chmod 4755 /app/bob -COPY components-image-builder-mk3-workspace-image-layer--pack/pack.tar /app/workspace-image-layer.tar.gz -RUN mkdir /app/gplayer \ - && cd /app/gplayer \ - && tar xzf /app/workspace-image-layer.tar.gz \ - && rm -r /app/workspace-image-layer.tar.gz \ - && mv gitpod-layer/* . - RUN mkdir /ide COPY ide-startup.sh /ide/startup.sh COPY supervisor-ide-config.json /ide/ diff --git a/components/image-builder-bob/pkg/builder/builder.go b/components/image-builder-bob/pkg/builder/builder.go index 52df20b00f129e..fcf6ca1cdfb3d2 100644 --- a/components/image-builder-bob/pkg/builder/builder.go +++ b/components/image-builder-bob/pkg/builder/builder.go @@ -19,6 +19,7 @@ import ( "github.com/containerd/console" "github.com/moby/buildkit/client" + "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/session" "github.com/moby/buildkit/util/progress/progressui" "golang.org/x/sync/errgroup" @@ -28,7 +29,6 @@ const ( buildkitdSocketPath = "unix:///run/buildkit/buildkitd.sock" maxConnectionAttempts = 10 initialConnectionTimeout = 2 * time.Second - gplayerDir = "/app/gplayer" ) // Builder builds images using buildkit @@ -66,7 +66,7 @@ func (b *Builder) Build() error { if err != nil { return err } - err = b.buildGPLayer(ctx, cl) + err = b.buildWorkspaceImage(ctx, cl) if err != nil { return err } @@ -152,7 +152,7 @@ func (b *Builder) buildBaseLayer(ctx context.Context, cl *client.Client) error { }, }, } - if lauth := b.Config.GPLayerAuth; lauth != "" { + if lauth := b.Config.WorkspaceLayerAuth; lauth != "" { auth, err := newAuthProviderFromEnvvar(lauth) if err != nil { return fmt.Errorf("invalid gp layer authentication: %w", err) @@ -187,9 +187,9 @@ func (b *Builder) buildBaseLayer(ctx context.Context, cl *client.Client) error { return err } -func (b *Builder) buildGPLayer(ctx context.Context, cl *client.Client) (err error) { +func (b *Builder) buildWorkspaceImage(ctx context.Context, cl *client.Client) (err error) { var sess []session.Attachable - if gplayerAuth := b.Config.GPLayerAuth; gplayerAuth != "" { + if gplayerAuth := b.Config.WorkspaceLayerAuth; gplayerAuth != "" { auth, err := newAuthProviderFromEnvvar(gplayerAuth) if err != nil { return err @@ -197,15 +197,12 @@ func (b *Builder) buildGPLayer(ctx context.Context, cl *client.Client) (err erro sess = append(sess, auth) } + def, err := llb.Image(b.Config.BaseRef).Marshal(context.Background()) + if err != nil { + return err + } + solveOpt := client.SolveOpt{ - Frontend: "dockerfile.v0", - LocalDirs: map[string]string{ - "context": gplayerDir, - "dockerfile": gplayerDir, - }, - FrontendAttrs: map[string]string{ - "build-arg:baseref": b.Config.BaseRef, - }, Exports: []client.ExportEntry{ { Type: "image", @@ -222,7 +219,7 @@ func (b *Builder) buildGPLayer(ctx context.Context, cl *client.Client) (err erro eg, ctx := errgroup.WithContext(ctx) ch := make(chan *client.SolveStatus) eg.Go(func() error { - _, err := cl.Solve(ctx, nil, solveOpt, ch) + _, err := cl.Solve(ctx, def, solveOpt, ch) if err != nil { return fmt.Errorf("cannot build Gitpod layer: %w", err) } diff --git a/components/image-builder-bob/pkg/builder/config.go b/components/image-builder-bob/pkg/builder/config.go index 58fe42a1909cc3..ad6e67bbd855b1 100644 --- a/components/image-builder-bob/pkg/builder/config.go +++ b/components/image-builder-bob/pkg/builder/config.go @@ -18,31 +18,31 @@ import ( // Config configures a builder type Config struct { - TargetRef string - BaseRef string - BaseContext string - BuildBase bool - BaseLayerAuth string - GPLayerAuth string - Dockerfile string - ContextDir string - ExternalBuildkitd string - localCacheImport string + TargetRef string + BaseRef string + BaseContext string + BuildBase bool + BaseLayerAuth string + WorkspaceLayerAuth string + Dockerfile string + ContextDir string + ExternalBuildkitd string + localCacheImport string } // GetConfigFromEnv extracts configuration from environment variables func GetConfigFromEnv() (*Config, error) { cfg := &Config{ - TargetRef: os.Getenv("BOB_TARGET_REF"), - BaseRef: os.Getenv("BOB_BASE_REF"), - BaseContext: os.Getenv("THEIA_WORKSPACE_ROOT"), - BuildBase: os.Getenv("BOB_BUILD_BASE") == "true", - BaseLayerAuth: os.Getenv("BOB_BASELAYER_AUTH"), - GPLayerAuth: os.Getenv("BOB_GPLAYER_AUTH"), - Dockerfile: os.Getenv("BOB_DOCKERFILE_PATH"), - ContextDir: os.Getenv("BOB_CONTEXT_DIR"), - ExternalBuildkitd: os.Getenv("BOB_EXTERNAL_BUILDKITD"), - localCacheImport: os.Getenv("BOB_LOCAL_CACHE_IMPORT"), + TargetRef: os.Getenv("BOB_TARGET_REF"), + BaseRef: os.Getenv("BOB_BASE_REF"), + BaseContext: os.Getenv("THEIA_WORKSPACE_ROOT"), + BuildBase: os.Getenv("BOB_BUILD_BASE") == "true", + BaseLayerAuth: os.Getenv("BOB_BASELAYER_AUTH"), + WorkspaceLayerAuth: os.Getenv("BOB_WSLAYER_AUTH"), + Dockerfile: os.Getenv("BOB_DOCKERFILE_PATH"), + ContextDir: os.Getenv("BOB_CONTEXT_DIR"), + ExternalBuildkitd: os.Getenv("BOB_EXTERNAL_BUILDKITD"), + localCacheImport: os.Getenv("BOB_LOCAL_CACHE_IMPORT"), } if cfg.BaseRef == "" { @@ -86,15 +86,15 @@ func GetConfigFromEnv() (*Config, error) { return nil, fmt.Errorf("cannot decrypt BOB_BASELAYER_AUTH: %w", err) } } - if cfg.GPLayerAuth != "" { - dec := make([]byte, base64.RawStdEncoding.DecodedLen(len(cfg.GPLayerAuth))) - _, err := base64.RawStdEncoding.Decode(dec, []byte(cfg.GPLayerAuth)) + if cfg.WorkspaceLayerAuth != "" { + dec := make([]byte, base64.RawStdEncoding.DecodedLen(len(cfg.WorkspaceLayerAuth))) + _, err := base64.RawStdEncoding.Decode(dec, []byte(cfg.WorkspaceLayerAuth)) if err != nil { - return nil, fmt.Errorf("BOB_GPLAYER_AUTH is not base64 encoded but BOB_AUTH_KEY is present") + return nil, fmt.Errorf("BOB_WSLAYER_AUTH is not base64 encoded but BOB_AUTH_KEY is present") } - cfg.GPLayerAuth, err = decrypt(dec, authKey) + cfg.WorkspaceLayerAuth, err = decrypt(dec, authKey) if err != nil { - return nil, fmt.Errorf("cannot decrypt BOB_GPLAYER_AUTH: %w", err) + return nil, fmt.Errorf("cannot decrypt BOB_WSLAYER_AUTH: %w", err) } } } diff --git a/components/image-builder-mk3/BUILD.yaml b/components/image-builder-mk3/BUILD.yaml index f3086d3812afbd..f7f1eda3046a4c 100644 --- a/components/image-builder-mk3/BUILD.yaml +++ b/components/image-builder-mk3/BUILD.yaml @@ -22,7 +22,6 @@ packages: type: docker deps: - :app - - components/image-builder-mk3/workspace-image-layer:pack argdeps: - imageRepoBase config: diff --git a/components/image-builder-mk3/leeway.Dockerfile b/components/image-builder-mk3/leeway.Dockerfile index 575c53d3cd9b7d..2f9abe4ced6f8c 100644 --- a/components/image-builder-mk3/leeway.Dockerfile +++ b/components/image-builder-mk3/leeway.Dockerfile @@ -11,7 +11,5 @@ RUN apk upgrade --no-cache \ COPY components-image-builder-mk3--app/image-builder /app/ RUN chmod +x /app/image-builder -COPY components-image-builder-mk3-workspace-image-layer--pack/pack.tar /app/workspace-image-layer.tar.gz - ENTRYPOINT [ "/app/image-builder" ] CMD [ "-v", "help" ] \ No newline at end of file diff --git a/components/image-builder-mk3/pkg/orchestrator/orchestrator.go b/components/image-builder-mk3/pkg/orchestrator/orchestrator.go index fdbc532c4cf647..f66a3b797f9a4e 100644 --- a/components/image-builder-mk3/pkg/orchestrator/orchestrator.go +++ b/components/image-builder-mk3/pkg/orchestrator/orchestrator.go @@ -49,6 +49,10 @@ const ( // maxBuildRuntime is the maximum time a build is allowed to take maxBuildRuntime = 60 * time.Minute + + // workspaceBuildProcessVersion controls how we build workspace images. + // Incrementing this value will trigger a rebuild of all workspace images. + workspaceBuildProcessVersion = 1 ) // Configuration configures the orchestrator @@ -72,9 +76,6 @@ type Configuration struct { // Note that the workspace nodes/kubelets need access to this repository. WorkspaceImageRepository string `json:"workspaceImageRepository"` - // GitpodLayerLoc is the path to the Gitpod layer tar file - GitpodLayerLoc string `json:"gitpodLayerLoc"` - // BuilderImage is an image ref to the workspace builder image BuilderImage string `json:"builderImage"` @@ -98,11 +99,6 @@ func NewOrchestratingBuilder(cfg Configuration) (res *Orchestrator, err error) { } } - gplayerHash, err := computeGitpodLayerHash(cfg.GitpodLayerLoc) - if err != nil { - return - } - var builderAuthKey [32]byte if cfg.BuilderAuthKeyFile != "" { fn := cfg.BuilderAuthKeyFile @@ -178,7 +174,6 @@ func NewOrchestratingBuilder(cfg Configuration) (res *Orchestrator, err error) { RefResolver: &resolve.StandaloneRefResolver{}, wsman: wsmanapi.NewWorkspaceManagerClient(conn), - gplayerHash: gplayerHash, buildListener: make(map[string]map[buildListener]struct{}), logListener: make(map[string]map[logListener]struct{}), censorship: make(map[string][]string), @@ -189,28 +184,6 @@ func NewOrchestratingBuilder(cfg Configuration) (res *Orchestrator, err error) { return o, nil } -func computeGitpodLayerHash(gitpodLayerLoc string) (string, error) { - if tproot := os.Getenv("TELEPRESENCE_ROOT"); tproot != "" { - gitpodLayerLoc = filepath.Join(tproot, gitpodLayerLoc) - } - if fn := os.Getenv("GITPOD_LAYER_LOC"); fn != "" { - gitpodLayerLoc = fn - } - - inpt, err := os.OpenFile(gitpodLayerLoc, os.O_RDONLY, 0600) - if err != nil { - return "", xerrors.Errorf("cannot compute gitpod layer hash: %w", err) - } - defer inpt.Close() - - hash := sha256.New() - _, err = io.Copy(hash, inpt) - if err != nil { - return "", xerrors.Errorf("cannot compute gitpod layer hash: %w", err) - } - return fmt.Sprintf("%x", hash.Sum([]byte{})), nil -} - // Orchestrator runs image builds by orchestrating headless build workspaces type Orchestrator struct { Config Configuration @@ -218,8 +191,7 @@ type Orchestrator struct { AuthResolver auth.Resolver RefResolver resolve.DockerRefResolver - gplayerHash string - wsman wsmanapi.WorkspaceManagerClient + wsman wsmanapi.WorkspaceManagerClient builderAuthKey [32]byte buildListener map[string]map[buildListener]struct{} @@ -432,7 +404,7 @@ func (o *Orchestrator) Build(req *protocol.BuildRequest, resp protocol.ImageBuil {Name: "BOB_BASE_REF", Value: baseref}, {Name: "BOB_BUILD_BASE", Value: buildBase}, {Name: "BOB_BASELAYER_AUTH", Value: baseLayerAuth}, - {Name: "BOB_GPLAYER_AUTH", Value: gplayerAuth}, + {Name: "BOB_WSLAYER_AUTH", Value: gplayerAuth}, {Name: "BOB_DOCKERFILE_PATH", Value: dockerfilePath}, {Name: "BOB_CONTEXT_DIR", Value: contextPath}, {Name: "BOB_AUTH_KEY", Value: string(o.builderAuthKey[:])}, @@ -655,11 +627,7 @@ func (o *Orchestrator) getBaseImageRef(ctx context.Context, bs *protocol.BuildSo } func (o *Orchestrator) getWorkspaceImageRef(ctx context.Context, baseref string, allowedAuth auth.AllowedAuthFor) (ref string, err error) { - //nolint:staticcheck,ineffassign - span, ctx := opentracing.StartSpanFromContext(ctx, "getWorkspaceImageRef") - defer tracing.FinishSpan(span, &err) - - cnt := []byte(fmt.Sprintf("%s\n%s\n", baseref, o.gplayerHash)) + cnt := []byte(fmt.Sprintf("%s\n%d\n", baseref, workspaceBuildProcessVersion)) hash := sha256.New() n, err := hash.Write(cnt) if err != nil { diff --git a/components/image-builder-mk3/workspace-image-layer/BUILD.yaml b/components/image-builder-mk3/workspace-image-layer/BUILD.yaml deleted file mode 100644 index 48fede063ee56e..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/BUILD.yaml +++ /dev/null @@ -1,15 +0,0 @@ -packages: - - name: pack - type: generic - srcs: - - "gitpod-layer/**" - - "scripts/**" - deps: - - components/gitpod-cli:app - config: - commands: - - ["mkdir", "pack"] - - ["mv", "components-gitpod-cli--app/gitpod-cli", "pack/gitpod-cli"] - - ["mv", "gitpod-layer", "scripts", "pack/"] - - ["rm", "-r", "components-gitpod-cli--app"] - - ["tar", "cvfz", "pack.tar", "-C", "pack", "."] diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/Dockerfile b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/Dockerfile deleted file mode 100644 index 19818e6ada924d..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# 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. - -ARG baseref -FROM ${baseref} AS prep - -USER root - -# Copy config and layer script -COPY . /var/gitpod - -# Run layer -WORKDIR /var/gitpod -RUN mv /var/gitpod/gitpod-cli /usr/bin/gp \ - && sh /var/gitpod/build.sh - -# Switch to user gitpod -USER gitpod - -# Configure user shell -# TODO Remove this in the near future when we do not need ~/.bashrc appends/prepends any more -RUN \ - # REALLY do not print motd - touch ~/.hushlogin && \ - # Configure shell - BASH_RC=~/.bashrc; if [ -f "$BASH_RC" ]; then cp "$BASH_RC" ~/.bashrc-org; else touch ~/.bashrc-org; fi && \ - cat /var/gitpod/gitpod/.bashrc-prepend > "$BASH_RC" && \ - cat ~/.bashrc-org >> "$BASH_RC" && \ - cat /var/gitpod/gitpod/.bashrc-append >> "$BASH_RC" - -USER root -RUN rm -rf /var/gitpod -USER gitpod diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/Dockerfile b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/Dockerfile deleted file mode 100644 index b2fe09d1943532..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2020 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 ${BASE_IMAGE}' prepended here - -############################################################################### -# REQUIRED -############################################################################### -# !!! We expect users to configure their containers as root !!! -USER root - -# Copy config and layer script -COPY ./gitpod /var/gitpod - -# Run layer -RUN /var/gitpod/layer.sh \ - # Remove the script itself - # TODO Really necessary? - && rm -f /var/gitpod/layer.sh - -# Switch to user gitpod -USER gitpod - -# Configure user shell -# TODO Remove this in the near future when we do not need ~/.bashrc appends/prepends any more -RUN \ - # REALLY do not print motd - touch ~/.hushlogin && \ - # Configure shell - BASH_RC=~/.bashrc; if [ -f "$BASH_RC" ]; then cp "$BASH_RC" ~/.bashrc-org; else touch ~/.bashrc-org; fi && \ - cat /var/gitpod/.bashrc-prepend > "$BASH_RC" && \ - cat ~/.bashrc-org >> "$BASH_RC" && \ - cat /var/gitpod/.bashrc-append >> "$BASH_RC" diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-append b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-append deleted file mode 100644 index b9cf898682b6a5..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-append +++ /dev/null @@ -1,27 +0,0 @@ - -############################################################################### -########## Gitpod - append - begin -############################################################################### - -export GEM_HOME=/workspace/.rvm -export GEM_PATH=$GEM_HOME:$GEM_PATH -export PATH=/workspace/.rvm/bin:$PATH - -export PIPENV_VENV_IN_PROJECT=true -export PIP_USER=yes -export PYTHONUSERBASE=/workspace/.pip-modules -export PATH=$PYTHONUSERBASE/bin:$PATH -unset PIP_TARGET -unset PYTHONPATH - -# Set CARGO_HOME to reside in workspace if: -# - it's RUNTIME (/workspace present) -if [ -d /workspace ]; then - export CARGO_HOME=/workspace/.cargo - export PATH=$CARGO_HOME/bin:$PATH -fi - -############################################################################### -########## Gitpod - append - end -############################################################################### - diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-prepend b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-prepend deleted file mode 100644 index a500a0b1c76d72..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/.bashrc-prepend +++ /dev/null @@ -1,37 +0,0 @@ - -############################################################################### -########## Gitpod - prepend -############################################################################### - -# Prompt color and bash_completion -export PS1='\[\e]0;\u \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u\[\033[00m\] \[\033[01;34m\]\w \$ \[\033[00m\]' - -# editor config - should be removed when registry facade is default -if [ -z "$EDITOR" ]; then - export EDITOR="gp open -w" -fi -if [ -z "$VISUAL" ]; then - export VISUAL="$EDITOR" -fi -if [ -z "$GIT_EDITOR" ]; then - export GIT_EDITOR="$EDITOR" -fi - -# Workaround Java pre v10 by explicitly setting "-Xmx" for all Hotspot/openJDK VMs -if [ -n "$GITPOD_MEMORY" ]; then - export JAVA_TOOL_OPTIONS="-Xmx${GITPOD_MEMORY}m"; -fi - -# Completion for gp command -. <(gp completion) -# ide cli config - should be removed when registry facade is default -if [ ! -d "/ide/bin/" ]; then - alias open='gp open' - alias code='gp open' -fi - -export BROWSER="${BROWSER:=gp-preview}" - -############################################################################### -########## Gitpod - prepend -############################################################################### diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/layer.sh b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/layer.sh deleted file mode 100755 index 7bb5ba38a72f95..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/alpine/gitpod/layer.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh -# Copyright (c) 2020 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. - -# >>> Expects to be run as root - -# Quit immediately on non-zero exit code -set -e; - -# Install necessary tools only if they are not yet installed -INSTALLED_PACKAGES=$(apk list -I git bash | wc -l) -if [ "$INSTALLED_PACKAGES" != 2 ]; then - # Install - apk add --no-cache --update \ - git \ - bash -fi - -# Disable root login -# -# Note: The root account should already be disabled by default, at least in Ubuntu. -# Source: https://askubuntu.com/a/20453 -# -# In the past, we used to set a password here, when Gitpod managed workspaces via SSH. -# Now, it doesn't really matter if root is locked or not, because we prevent privilege -# escalation in containers with "allowPrivilegeEscalation=false" anyway: -# https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -passwd -l root || true - -# Create gp-preview symlink required for the browser variable -ln -s /usr/bin/gp /usr/bin/gp-preview - -# Create Gitpod user -if ! id -u gitpod; then - # user doesn't exist, let's add it. - echo "Creating new user 'gitpod'."; - addgroup -g 33333 gitpod; - adduser -D -h /home/gitpod -s /bin/sh -u 33333 -G gitpod gitpod; - echo "gitpod:gitpod" | chpasswd; - - # To allow users to not know anything about our gitpod user, copy over all stuff from the previous user (root) - cp -R /root/. /home/gitpod; - chown -R gitpod:gitpod /home/gitpod/; -else - USER_ID=$(id -u gitpod) - if [ "$USER_ID" -eq 33333 ]; then - # users exists and has user id 33333. We hope that the user does not have ID 0, because that grants root privileges - echo "Found user 'gitpod'. Reusing it."; - echo "gitpod:gitpod" | chpasswd; - else - # error - echo "Error: User 'gitpod' exists but does not have user-id 33333. The user-id is $(id -u)"; - exit 1; - fi -fi diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/Dockerfile b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/Dockerfile deleted file mode 100644 index 5a0f247827a7d7..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2020 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 ${BASE_IMAGE}' prepended here - -############################################################################### -# REQUIRED -############################################################################### -# !!! We expect users to configure their containers as root !!! -USER root - -# Copy config and layer script -# FIXME(Kreyren): This is a duplicate code that should be present in all distros -COPY ./gitpod /var/gitpod - -# Run layer -# FIXME(Kreyren): This is a duplicate code that should be present in all distros -RUN /var/gitpod/layer.sh \ - # Remove the script itself - # TODO Really necessary? - && rm -f /var/gitpod/layer.sh - -# Switch to user gitpod -# FIXME(Kreyren): This is a duplicate code that should be present in all distros -USER gitpod - -# Configure user shell -# TODO Remove this in the near future when we do not need ~/.bashrc appends/prepends any more -# FIXME(Kreyren): This is a duplicate code that should be present in all distros -RUN \ - # REALLY do not print motd - touch ~/.hushlogin && \ - # Configure shell - BASH_RC=~/.bashrc; if [ -f "$BASH_RC" ]; then cp "$BASH_RC" ~/.bashrc-org; else touch ~/.bashrc-org; fi && \ - cat /var/gitpod/.bashrc-prepend > "$BASH_RC" && \ - cat ~/.bashrc-org >> "$BASH_RC" && \ - cat /var/gitpod/.bashrc-append >> "$BASH_RC" diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/cla.md.gpg b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/cla.md.gpg deleted file mode 100644 index 0e27a7cc8bff71..00000000000000 Binary files a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/cla.md.gpg and /dev/null differ diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-append b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-append deleted file mode 100644 index a437676f8f4b02..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-append +++ /dev/null @@ -1,11 +0,0 @@ - - -############################################################################### -########## Gitpod - append - begin -############################################################################### - - -############################################################################### -########## Gitpod - append - end -############################################################################### - diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-prepend b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-prepend deleted file mode 100644 index c1b70b76754e50..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/.bashrc-prepend +++ /dev/null @@ -1,53 +0,0 @@ - - -############################################################################### -########## Gitpod - prepend -############################################################################### - -# Prompt color and bash_completion -export PS1='\[\e]0;\u \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u\[\033[00m\] \[\033[01;34m\]\w \$ \[\033[00m\]' -#source /etc/bash_completion - -# editor config - should be removed when registry facade is default -if [ -z "$EDITOR" ]; then - export EDITOR="gp open -w" -fi -if [ -z "$VISUAL" ]; then - export VISUAL="$EDITOR" -fi -if [ -z "$GIT_EDITOR" ]; then - export GIT_EDITOR="$EDITOR" -fi - -# Completion for gp command -. <(gp completion) -# ide cli config - should be removed when registry facade is default -if [ ! -d "/ide/bin/" ]; then - alias open='gp open' - alias code='gp open' -fi - -export GEM_HOME=/workspace/.rvm -export GEM_PATH=$GEM_HOME:$GEM_PATH -export PATH=/workspace/.rvm/bin:$PATH - -export PIPENV_VENV_IN_PROJECT=true -export PIP_USER=yes -export PYTHONUSERBASE=/workspace/.pip-modules -export PATH=$PYTHONUSERBASE/bin:$PATH -unset PIP_TARGET -unset PYTHONPATH - -# Set CARGO_HOME to reside in workspace if: -# - it's RUNTIME (/workspace present) -if [ -d /workspace ]; then - export CARGO_HOME=/workspace/.cargo - export PATH=$CARGO_HOME/bin:$PATH -fi - -export BROWSER="${BROWSER:=gp-preview}" - -############################################################################### -########## Gitpod - prepend -############################################################################### - diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/layer.sh b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/layer.sh deleted file mode 100755 index cf2c71086af398..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/amazon/gitpod/layer.sh +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/sh -# Copyright (c) 2020 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. - -# Created by Jacob Hrbek under WTFPL license - -###! This script is designed to be run in docker environment - -# Required for docker to terminate the build on failure -set -e - -myName="amazonlinux Layer" - -efixme() { - if [ "$IGNORE_FIXME" != 1 ]; then - printf 'FIXME: %s\n' "$1" - else - # NOTICE(Krey): Terminates the script otherwise - true - fi -} -edebug() { - if [ "$DEBUG" = 1 ]; then - printf 'DEBUG: %s\n' "$1" - else - # NOTICE(Krey): Terminates the script otherwise - true - fi -} -die() { - case "$1" in - 1|3) printf 'FATAL: %s\n' "$2" ;; - 26) printf 'SECURITY: %s\n' "$2" ;; - *) - printf 'FATAL: %s\n' "$2" - exit 1 - esac - - exit "$1" -} - -# Expects to be run as root -if [ "$(id -u)" != 0 ]; then - die 3 "Amazonlinux wrapper is not expected to be invoked on non-root" -elif [ "$(id -u)" = 0 ]; then - # FIXME(Kreyren): Sanitization needed - true -else - die 255 "Checking for root acces in amazonlinux layer" -fi - -# Disable root login -# Notice(Krey): Not a big deal according to jankermones -if ! command -v passwd; then - true -elif command -v passwd; then - passwd -l root || true -else - die 255 "Unexpected happend while checking for passwd command" -fi - -# Create gp-preview symlink required for the browser variable -ln -s /usr/bin/gp /usr/bin/gp-preview || die 1 "Unable to symlink gp to gp-preview" - -## Gitpod user -expected_user="gitpod" -expected_uid="33333" -## Gitpod group -expected_group="gitpod" -expected_gid="33333" - -# Disable repository protection -# HOTFIX(Krey): Results in `packages excluded due to repository priority protections` on gitpod for unknown reason -printf '%s\n' "[main]" "enabled = 0" > /etc/yum/pluginconf.d/priorities.conf - -# Install git and vim -yum install -y git || die 1 "Unable to install required git package" -yum install -y vim || die 1 "Unable to install required vim package" -# DNM(Krey): Hotfix due weird behaviour -##yum install -y bash || die 1 "Unable to install required bash package" - -# Create Gitpod user -# INFO(Kreyren): This is stripped from https://github.com/jankeromnes/gitpod-layers/pull/3 -# Resolve expected group -if grep -q "$expected_group:.*:$expected_gid:" /etc/group; then - edebug "Expected group $expected_group with gid $expected_gid is already present, skipping resolution logic" -elif ! grep -q "$expected_group:.*:$expected_gid:" /etc/group; then - edebug "Expected group '$expected_group' with expected gid '$expected_gid' is not present, resolving.." - # CORE - Make a new group if needed - if command -v groupadd >/dev/null; then - edebug "Detected that command 'groupadd' is available for us to use" - groupadd \ - --gid "$expected_gid" \ - "$expected_group" \ - || die 1 "Command groupadd failed to create expected group $expected_group with expected gid $expected_gid" - edebug "Command groupadd returned true for creating expected group $expected_group with expected gid $expected_gid" - elif ! command -v groupadd; then - die 1 "Expected command 'groupadd' is not present, unable to create expected group $expected_group with gid $expected_gid" - else - die 255 "processing expected group $expected_group with expected id $expected_gid in $myName" - fi -fi - -# Self-check: Resolve expected group -edebug "processing 'Self-check: Resolve expected group' step in $myName" -if grep -q "$expected_group:.*:$expected_gid:" /etc/group; then - edebug "Expected group $expected_group with expected gid $expected_gid passed self-check" -elif ! grep -q "$expected_group:.*:$expected_gid:" /etc/group; then - die 23 "Expected group $expected_group with expected gid $expected_gid failed self-check, see output of command 'grep -q \"$expected_group:.*:$expected_gid:\" /etc/group': $(grep "$expected_group:.*:$expected_gid:" /etc/group)" -else - die 255 "self-checking Resolve expected group step" -fi - -# Resolve expected user -if grep -q "$expected_user:.*:$expected_uid:$expected_gid:.*" /etc/passwd; then - edebug "Expected user $expected_user with expected uid $expected_uid is already present, skipping resolution.." -elif ! grep -q "$expected_user:.*:$expected_uid:$expected_gid:.*" /etc/passwd; then - edebug "Expected user $expected_user with expected uid $expected_uid is not present, resolving.." - # CORE - Make a new user if needed - if command -v useradd >/dev/null; then - edebug "Found command useradd for resolution" - # We need --no-log-init due https://github.com/golang/go/issues/13548, see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user - # FIXME: Implement logic that applies --no-log-init based on provided bug state - useradd \ - --create-home --home-dir "/home/$expected_user" \ - --no-log-init \ - --uid "$expected_uid" \ - --gid "$expected_group" \ - --password "$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c10)" \ - --comment "Created by $myName for gitpod usage" \ - "$expected_user" \ - || die 1 "Command useradd failed to create expected user $expected_user with uid $expected_uid" - edebug "Expected user $expected_user with expected uid $expected_uid has been created according to command useradd" - elif command -v adduser >/dev/null; then - # FIXME: Blocked by https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user - die 23 "Command useradd is not available and we are refusing to sue adduser due to the https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user" - elif ! command -v useradd >/dev/null && ! command -v adduser >/dev/null; then - die 23 "Neither of expected commands useradd nor adduser are available on this environment, this usage of gitpod is unexpected and most likely malicious injection of altered dockerfile. Instance $GITPOD_WORKSPACE_ID with user $GITPOD_GIT_USER_EMAIL has been reported to upstream" - else - die 255 "Resolving expected user" - fi -else - die 255 "Checking if expected user is present" -fi - -# Self-check -if grep -q "$expected_user:.*:$expected_uid:$expected_gid:.*" /etc/passwd; then - edebug "Expected user $expected_user with expected uid $expected_uid passed self-check" -elif ! grep -q "$expected_user:.*:$expected_uid:$expected_gid:.*" /etc/passwd; then - edebug "Output of 'grep \"$expected_user\" /etc/passwd' is: '$(grep "$expected_user" /etc/passwd)'" - efixme "Logic for self-check of expected user is required" - #die 23 "Expected user $expected_user with expected uid $expected_uid failed self-check" -else - die 255 "Self-checking expected user" -fi \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/build.sh b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/build.sh deleted file mode 100755 index 314204894268ff..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/build.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# 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. - - -set -e - -if [ ! -f /etc/os-release ]; then - DISTRO="UNDEFINED" -else - # Read the line starting with 'ID=' from /etc/os-release and print the rest of the line - DISTRO="$(sed -nr 's/^ID=(.+)$/\1/p' /etc/os-release)" -fi - -# Unify DISTRO values -case "$DISTRO" in - "debian" | "ubuntu" | "linuxmint") - DISTRO="debian" - ;; - - # NOTICE(Kreyren): Amazonlinux has non-standard /etc/os-release - "\"amzn\"") - # Kreyren: Made for https://github.com/gitpod-io/gitpod/issues/1490 - DISTRO="amazon" - ;; - - "alpine") - DISTRO="alpine" - ;; - - *) - DISTRO="UNDEFINED" - ;; -esac - -if [ ! -d "$DISTRO" ]; then - echo "Error: unsupported distro: $DISTRO" -fi - -ln -s $DISTRO/gitpod gitpod -sh gitpod/layer.sh \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/Dockerfile b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/Dockerfile deleted file mode 100644 index b2fe09d1943532..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2020 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 ${BASE_IMAGE}' prepended here - -############################################################################### -# REQUIRED -############################################################################### -# !!! We expect users to configure their containers as root !!! -USER root - -# Copy config and layer script -COPY ./gitpod /var/gitpod - -# Run layer -RUN /var/gitpod/layer.sh \ - # Remove the script itself - # TODO Really necessary? - && rm -f /var/gitpod/layer.sh - -# Switch to user gitpod -USER gitpod - -# Configure user shell -# TODO Remove this in the near future when we do not need ~/.bashrc appends/prepends any more -RUN \ - # REALLY do not print motd - touch ~/.hushlogin && \ - # Configure shell - BASH_RC=~/.bashrc; if [ -f "$BASH_RC" ]; then cp "$BASH_RC" ~/.bashrc-org; else touch ~/.bashrc-org; fi && \ - cat /var/gitpod/.bashrc-prepend > "$BASH_RC" && \ - cat ~/.bashrc-org >> "$BASH_RC" && \ - cat /var/gitpod/.bashrc-append >> "$BASH_RC" diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-append b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-append deleted file mode 100644 index a437676f8f4b02..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-append +++ /dev/null @@ -1,11 +0,0 @@ - - -############################################################################### -########## Gitpod - append - begin -############################################################################### - - -############################################################################### -########## Gitpod - append - end -############################################################################### - diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-prepend b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-prepend deleted file mode 100644 index 60e7b3cabd69b4..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/.bashrc-prepend +++ /dev/null @@ -1,58 +0,0 @@ - - -############################################################################### -########## Gitpod - prepend -############################################################################### - -# Prompt color and bash_completion -export PS1='\[\e]0;\u \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u\[\033[00m\] \[\033[01;34m\]\w \$ \[\033[00m\]' -#source /etc/bash_completion - -# editor config - should be removed when registry facade is default -if [ -z "$EDITOR" ]; then - export EDITOR="gp open -w" -fi -if [ -z "$VISUAL" ]; then - export VISUAL="$EDITOR" -fi -if [ -z "$GIT_EDITOR" ]; then - export GIT_EDITOR="$EDITOR" -fi - -# Workaround Java pre v10 by explicitly setting "-Xmx" for all Hotspot/openJDK VMs -if [ -n "$GITPOD_MEMORY" ]; then - export JAVA_TOOL_OPTIONS="-Xmx${GITPOD_MEMORY}m"; -fi - -# Completion for gp command -. <(gp completion) -# ide cli config - should be removed when registry facade is default -if [ ! -d "/ide/bin/" ]; then - alias open='gp open' - alias code='gp open' -fi - -export GEM_HOME=/workspace/.rvm -export GEM_PATH=$GEM_HOME:$GEM_PATH -export PATH=/workspace/.rvm/bin:$PATH - -export PIPENV_VENV_IN_PROJECT=true -export PIP_USER=yes -export PYTHONUSERBASE=/workspace/.pip-modules -export PATH=$PYTHONUSERBASE/bin:$PATH -unset PIP_TARGET -unset PYTHONPATH - -# Set CARGO_HOME to reside in workspace if: -# - it's RUNTIME (/workspace present) -if [ -d /workspace ]; then - export CARGO_HOME=/workspace/.cargo - export PATH=$CARGO_HOME/bin:$PATH -fi - -export BROWSER="${BROWSER:=gp-preview}" - -############################################################################### -########## Gitpod - prepend -############################################################################### - diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/layer.sh b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/layer.sh deleted file mode 100755 index 86821df942953b..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/debian/gitpod/layer.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# Copyright (c) 2020 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. - -# >>> Expects to be run as root - -# Quit immediately on non-zero exit code -set -e; - -# Install necessary tools only if they are not yet installed -INSTALLED_PACKAGES=$(dpkg-query -f '${Package} ${Status}\n' -W bash-completion git | wc -l) -if [ "$INSTALLED_PACKAGES" != 2 ]; then - # The first 'clean' is needed to avoid apt-get detecting package meta data changes - # (like changed labels) which result in errors and broken builds/workspaces! - apt-get clean && rm -rf /var/lib/apt/lists/*; - - apt-get update --allow-insecure-repositories; - apt-get install -yq \ - bash-completion \ - git - - # Cleanup to keep the image as small as possible - apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*; -fi - -# Disable root login -# -# Note: The root account should already be disabled by default, at least in Ubuntu. -# Source: https://askubuntu.com/a/20453 -# -# In the past, we used to set a password here, when Gitpod managed workspaces via SSH. -# Now, it doesn't really matter if root is locked or not, because we prevent privilege -# escalation in containers with "allowPrivilegeEscalation=false" anyway: -# https://kubernetes.io/docs/concepts/policy/pod-security-policy/#privilege-escalation -passwd -l root || true - -# Create gp-preview symlink required for the browser variable -ln -s /usr/bin/gp /usr/bin/gp-preview - -# Create Gitpod user -if ! id -u gitpod; then - # user doesn't exist, let's add it. - echo "Creating new user 'gitpod'."; - addgroup --gid 33333 gitpod; - # '--no-log-init': see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user - useradd --no-log-init --create-home --home-dir /home/gitpod --shell /bin/bash --uid 33333 --gid 33333 gitpod; - echo "gitpod:gitpod" | chpasswd; - - # To allow users to not know anything about our gitpod user, copy over all stuff from the previous user (root) - cp -R /root/. /home/gitpod; - chown -R gitpod:gitpod /home/gitpod/; -else - USER_ID=$(id -u gitpod) - if [ "$USER_ID" -eq 33333 ]; then - # users exists and has user id 33333. We hope that the user does not have ID 0, because that grants root privileges - echo "Found user 'gitpod'. Reusing it."; - echo "gitpod:gitpod" | chpasswd; - else - # error - echo "Error: User 'gitpod' exists but does not have user-id 33333. The user-id is $UID"; - exit 1; - fi -fi diff --git a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/prepend.dockerfile b/components/image-builder-mk3/workspace-image-layer/gitpod-layer/prepend.dockerfile deleted file mode 100644 index 146aaffa18c97f..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/gitpod-layer/prepend.dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 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. - - -USER ROOT -COPY ./gitpod-cli /usr/bin/gp \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/scripts/detect-distro.sh b/components/image-builder-mk3/workspace-image-layer/scripts/detect-distro.sh deleted file mode 100755 index 5a7c0f9836bac6..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/scripts/detect-distro.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# Copyright (c) 2020 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 is run inside the base image provided by the user. -# It should detect the name of the distro by looking at /etc/os-release. -# The goal here is to determine the set of tools that are available to us to install the necessary dependencies for gitpod into the image -# E.g., which package manager to use etc. -# Dependencies: -# - /bin/sh -# - sed -# - /etc/os-release to contain the distro 'ID=' -# Postconditions: -# - stores result in file '/workspace/distro' -# - valid values: debian | alpine | "amzn" | UNDEFINED - -if [ ! -f /etc/os-release ]; then - DISTRO="UNDEFINED" -else - # Read the line starting with 'ID=' from /etc/os-release and print the rest of the line - DISTRO="$(sed -nr 's/^ID=(.+)$/\1/p' /etc/os-release)" -fi - -# Unify DISTRO values -case "$DISTRO" in - "debian" | "ubuntu" | "linuxmint") - DISTRO="debian" - ;; - - # NOTICE(Kreyren): Amazonlinux has non-standard /etc/os-release - "\"amzn\"") - # Kreyren: Made for https://github.com/gitpod-io/gitpod/issues/1490 - DISTRO="amazon" - ;; - - "alpine") - DISTRO="alpine" - ;; - - *) - DISTRO="UNDEFINED" - ;; -esac - -OUT_FILE="/workspace/distro" -printf '%s\n' "$DISTRO" > "$OUT_FILE" -printf '%s\n' "Found distro: $DISTRO. Wrote file $OUT_FILE." \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/scripts/generate-dockerfile.sh b/components/image-builder-mk3/workspace-image-layer/scripts/generate-dockerfile.sh deleted file mode 100755 index 24e60ffbfcf5a8..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/scripts/generate-dockerfile.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# Copyright (c) 2020 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. - -# Parameters: -# $1: BASE_IMAGE -BASE_DIR="$( cd "$( dirname "$0" )/.." >/dev/null 2>&1 && pwd )" -BASE_IMAGE=$1 - -# 1. Read distro value -DISTRO_IN_FILE="/workspace/distro" -if [ ! -f "$DISTRO_IN_FILE" ]; then - echo "Unable to find file $DISTRO_IN_FILE. Exit with code 1."; - exit 1; -fi -DISTRO=$(cat $DISTRO_IN_FILE) -if [ -z "$DISTRO" ] || [ "$DISTRO" = "UNDEFINED" ]; then - echo "Distro value '$DISTRO'! Exit with code 1."; - exit 1; -fi -# The file has served it's purpose, now move it out of the way -rm -f $DISTRO_IN_FILE - -# 2. Copy distro-specific files into workspace (default path in Google Cloud Container builder: /workspace) -DISTRO_PATH="$BASE_DIR/gitpod-layer/$DISTRO" -cp -R "$DISTRO_PATH"/. ./ - -# 3. Copy the gitpod-cli into the workspaace -cp "$BASE_DIR"/gitpod-cli gitpod-cli - -# 4. Create Dockerfile in /workspace starting from BASE_IMAGE and append the distro-specific part -echo "FROM $BASE_IMAGE" > Dockerfile -(cat "$BASE_DIR/gitpod-layer/prepend.dockerfile"; echo) >> Dockerfile -cat "$DISTRO_PATH/Dockerfile" >> Dockerfile - -echo "Generated Dockerfile with BASE_IMAGE: $BASE_IMAGE" diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine-withuser.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine-withuser.dockerfile deleted file mode 100644 index 2614287f74042c..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine-withuser.dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM alpine:3.13 - -RUN apk add --no-cache --update bash - -RUN addgroup -g 33333 gitpod -RUN adduser -D -h /home/gitpod -s /bin/sh -u 33333 -G gitpod gitpod \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine.dockerfile deleted file mode 100644 index a70195ff8af1f5..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/alpine.dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine:3.13 - -RUN apk add --no-cache --update bash \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-bionic.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-bionic.dockerfile deleted file mode 100644 index a47d2861734b1f..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-bionic.dockerfile +++ /dev/null @@ -1 +0,0 @@ -FROM buildpack-deps:bionic \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser-sudo.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser-sudo.dockerfile deleted file mode 100644 index 2aefcc2c0eed80..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser-sudo.dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM buildpack-deps:xenial - -RUN addgroup --gid 33333 gitpod -# '--no-log-init': see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user -RUN useradd --no-log-init --create-home --home-dir /home/gitpod --shell /bin/bash --uid 33333 --gid 33333 gitpod -RUN usermod -a -G sudo gitpod diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser.dockerfile deleted file mode 100644 index 3c2fddd3819531..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial-withuser.dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM buildpack-deps:xenial - -RUN addgroup --gid 33333 gitpod -# '--no-log-init': see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user -RUN useradd --no-log-init --create-home --home-dir /home/gitpod --shell /bin/bash --uid 33333 --gid 33333 gitpod diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial.dockerfile b/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial.dockerfile deleted file mode 100644 index 2af3eb86cce42a..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/ubuntu-xenial.dockerfile +++ /dev/null @@ -1 +0,0 @@ -FROM buildpack-deps:xenial \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/tests/positive/verify.sh b/components/image-builder-mk3/workspace-image-layer/tests/positive/verify.sh deleted file mode 100755 index 16bed08c4a0b45..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/positive/verify.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -USER_ID=$(id -u gitpod) -if [ "$USER_ID" -ne 33333 ]; then - echo "user 'gitpod' not present or wrong user-id." - exit 1 -fi - -if [ -z "$(command -v git)" ]; then - echo "git not installed!" -fi - -if [ -z "$(command -v bash)" ]; then - echo "bash not installed!" -fi - -echo "Tests passed successfully!" -exit 0 \ No newline at end of file diff --git a/components/image-builder-mk3/workspace-image-layer/tests/runtests.sh b/components/image-builder-mk3/workspace-image-layer/tests/runtests.sh deleted file mode 100755 index 34436f287050f7..00000000000000 --- a/components/image-builder-mk3/workspace-image-layer/tests/runtests.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Quit immediately on non-zero exit code -set -e; - -BASE=$(pwd) - -cd positive - -for DOCKERFILE in ls *.dockerfile; do - echo "********* BEGIN TEST $DOCKERFILE ************" - BASE_IMG="$DOCKERFILE:test" - WORKSPACE_IMG="$DOCKERFILE:layered" - WORKSPACE="$(sudo rm -rf .tmp; mkdir .tmp; cd .tmp; pwd)" - - cp "$BASE/"../scripts/* "$WORKSPACE" - cp "$BASE/positive/verify.sh" "$WORKSPACE" - docker build -f "$DOCKERFILE" -t "$BASE_IMG" . - docker run -v "$WORKSPACE":/workspace "$BASE_IMG" /workspace/detect-distro.sh - # Fake-satisfy generate-dockerfile.sh dependency - touch "$BASE/../gitpod-cli" - docker run -v "$WORKSPACE":/workspace -v "$BASE/..":/base "$BASE_IMG" sh -c "cd /workspace && /base/scripts/generate-dockerfile.sh $BASE_IMG" - - docker build -f "$WORKSPACE/Dockerfile" -t "$WORKSPACE_IMG" "$WORKSPACE" - - echo "docker run -v $WORKSPACE:/workspace $WORKSPACE_IMG /workspace/verify.sh" - if ! docker run -v "$WORKSPACE:/workspace" --entrypoint="" "$WORKSPACE_IMG" /workspace/verify.sh; then - echo "verify.sh failed." - exit 1 - fi - sudo rm -rf "$WORKSPACE" - rm -f "$BASE/../gitpod-cli" - echo "********* END TEST $DOCKERFILE ************" -done diff --git a/components/supervisor/BUILD.yaml b/components/supervisor/BUILD.yaml index 06263fc120b52e..0f18c33b7f6a98 100644 --- a/components/supervisor/BUILD.yaml +++ b/components/supervisor/BUILD.yaml @@ -25,6 +25,7 @@ packages: - components/supervisor/frontend:app - components/workspacekit:app - components/workspacekit:fuse-overlayfs + - components/gitpod-cli:app argdeps: - imageRepoBase config: diff --git a/components/supervisor/cmd/root.go b/components/supervisor/cmd/root.go index ba3a8ac41217eb..9f69484ae636b4 100644 --- a/components/supervisor/cmd/root.go +++ b/components/supervisor/cmd/root.go @@ -8,6 +8,7 @@ import ( "fmt" "os" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/gitpod-io/gitpod/common-go/log" @@ -30,9 +31,25 @@ var ( // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { log.Init(ServiceName, Version, false, true) + log.Log.Logger.AddHook(fatalTerminationLogHook{}) if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } + +type fatalTerminationLogHook struct{} + +func (fatalTerminationLogHook) Levels() []logrus.Level { + return []logrus.Level{logrus.FatalLevel} +} + +func (fatalTerminationLogHook) Fire(e *logrus.Entry) error { + msg := e.Message + if err := e.Data[logrus.ErrorKey]; err != nil { + msg += ": " + err.(error).Error() + } + + return os.WriteFile("/dev/termination-log", []byte(msg), 0644) +} diff --git a/components/supervisor/leeway.Dockerfile b/components/supervisor/leeway.Dockerfile index 769c7f9dd1c2e9..5aa55a1f2dc691 100644 --- a/components/supervisor/leeway.Dockerfile +++ b/components/supervisor/leeway.Dockerfile @@ -14,6 +14,7 @@ COPY components-supervisor--app/supervisor \ supervisor-config.json \ components-workspacekit--app/workspacekit \ components-workspacekit--fuse-overlayfs/fuse-overlayfs \ + components-gitpod-cli--app/gitpod-cli \ ./ WORKDIR "/.supervisor/dropbear" COPY components-supervisor--dropbear/dropbear \ diff --git a/components/supervisor/pkg/supervisor/supervisor.go b/components/supervisor/pkg/supervisor/supervisor.go index 1716fb691384be..65feecb2e33e37 100644 --- a/components/supervisor/pkg/supervisor/supervisor.go +++ b/components/supervisor/pkg/supervisor/supervisor.go @@ -52,6 +52,13 @@ import ( grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" ) +const ( + gitpodUID = 33333 + gitpodUserName = "gitpod" + gitpodGID = 33333 + gitpodGroupName = "gitpod" +) + var ( additionalServices []RegisterableService apiEndpointOpts []grpc.ServerOption @@ -122,7 +129,11 @@ func Run(options ...RunOption) { return } - buildIDEEnv(&Config{}) + err = AddGitpodUserIfNotExists() + if err != nil { + log.WithError(err).Fatal("cannot ensure Gitpod user exists") + } + symlinkBinaries(cfg) configureGit(cfg) tokenService := NewInMemoryTokenService() @@ -183,10 +194,10 @@ func Run(options ...RunOption) { go analyseConfigChanges(ctx, cfg, analytics, gitpodConfigService) termMuxSrv.DefaultWorkdir = cfg.RepoRoot - termMuxSrv.Env = buildIDEEnv(cfg) + termMuxSrv.Env = buildChildProcEnv(cfg) termMuxSrv.DefaultCreds = &syscall.Credential{ - Uid: 33333, - Gid: 33333, + Uid: gitpodUID, + Gid: gitpodGID, } apiServices := []RegisterableService{ @@ -318,6 +329,31 @@ func createExposedPortsImpl(cfg *Config, gitpodService *gitpod.APIoverJSONRPC) p return ports.NewGitpodExposedPorts(cfg.WorkspaceID, cfg.WorkspaceInstanceID, gitpodService) } +// supervisor ships some binaries we want in the PATH. We could just add some directory to the path, but +// instead of producing a strange path setup, we symlink the binary to /usr/bin. +func symlinkBinaries(cfg *Config) { + bin, err := os.Executable() + if err != nil { + log.WithError(err).Error("cannot get executable path - hence cannot symlink binaries") + return + } + base := filepath.Dir(bin) + + binaries := map[string]string{ + "gitpod-cli": "gp", + } + for k, v := range binaries { + var ( + from = filepath.Join(base, k) + to = filepath.Join("/usr/bin", v) + ) + err = os.Symlink(from, to) + if err != nil { + log.WithError(err).WithField("from", from).WithField("to", to).Warn("cannot create symlink") + } + } +} + func configureGit(cfg *Config) { settings := [][]string{ {"push.default", "simple"}, @@ -514,18 +550,20 @@ func prepareIDELaunch(cfg *Config) *exec.Cmd { log.WithField("args", args).WithField("entrypoint", cfg.Entrypoint).Info("launching IDE") cmd := exec.Command(cfg.Entrypoint, args...) - cmd.Env = buildIDEEnv(cfg) - - // We need the IDE to run in its own process group, s.t. we can suspend and resume - // IDE and its children. cmd.SysProcAttr = &syscall.SysProcAttr{ + // We need the child process to run in its own process group, s.t. we can suspend and resume + // IDE and its children. Setpgid: true, Pdeathsig: syscall.SIGKILL, + + // All supervisor children run as gitpod user. The environment variables we produce are also + // gitpod user specific. Credential: &syscall.Credential{ - Uid: 33333, - Gid: 33333, + Uid: gitpodUID, + Gid: gitpodGID, }, } + cmd.Env = buildChildProcEnv(cfg) // Here we must resist the temptation to "neaten up" the IDE output for headless builds. // This would break the JSON parsing of the headless builds. @@ -541,28 +579,47 @@ func prepareIDELaunch(cfg *Config) *exec.Cmd { return cmd } -func buildIDEEnv(cfg *Config) []string { - var env, envn []string +func buildChildProcEnv(cfg *Config) []string { + envs := make(map[string]string) for _, e := range os.Environ() { segs := strings.Split(e, "=") if len(segs) < 2 { log.Printf("\"%s\" has invalid format, not including in IDE environment", e) continue } - nme := segs[0] + nme, val := segs[0], segs[1] if isBlacklistedEnvvar(nme) { continue } - env = append(env, e) - envn = append(envn, nme) - } + envs[nme] = val + } + envs["SUPERVISOR_ADDR"] = fmt.Sprintf("localhost:%d", cfg.APIEndpointPort) + + // We're forcing basic environment variables here, because supervisor acts like a login process at this point. + // The gitpod user might not have existed when supervisor was started, hence the HOME coming + // from the container runtime is probably wrong ("/" to be exact). + // + // Wait, how does this env var stuff work on Linux? + // First, the kernel does not care or set environment variables, it's all userland. + // It's the login process (e.g. /bin/login called by e.g. getty) that sets conventional + // environment variables such as HOME and sometimes PATH or TERM. + // + // Where can I read up on this, e.g. how others do it? + // BusyBox is a good place to start, because it's small enough to be easy to understand. + // Start here: + // - https://github.com/mirror/busybox/blob/24198f652f10dca5603df7c704263358ca21f5ce/libbb/setup_environment.c#L32 + // - https://github.com/mirror/busybox/blob/24198f652f10dca5603df7c704263358ca21f5ce/libbb/login.c#L140-L170 + // + envs["HOME"] = "/home/gitpod" + envs["USER"] = "gitpod" + + // Particular Java optimisation: Java pre v10 did not gauge it's available memory correctly, and needed explicitly setting "-Xmx" for all Hotspot/openJDK VMs + envs["JAVA_TOOL_OPTIONS"] += fmt.Sprintf(" -Xmx%sm", os.Getenv("GITPOD_MEMORY")) - ce := map[string]string{ - "SUPERVISOR_ADDR": fmt.Sprintf("localhost:%d", cfg.APIEndpointPort), - } - for nme, val := range ce { + var env, envn []string + for nme, val := range envs { log.WithField("envvar", nme).Debug("passing environment variable to IDE") env = append(env, fmt.Sprintf("%s=%s", nme, val)) envn = append(envn, nme) @@ -831,14 +888,28 @@ func startSSHServer(ctx context.Context, cfg *Config, wg *sync.WaitGroup) { hostkeyFN.Close() os.Remove(hostkeyFN.Name()) - out, err := exec.Command(dropbearkey, "-t", "rsa", "-f", hostkeyFN.Name()).CombinedOutput() + keycmd := exec.Command(dropbearkey, "-t", "rsa", "-f", hostkeyFN.Name()) + // We need to force HOME because the Gitpod user might not have existed at the start of the container + // which makes the container runtime set an invalid HOME value. + keycmd.Env = func() []string { + env := os.Environ() + res := make([]string, 0, len(env)) + for _, e := range env { + if strings.HasPrefix(e, "HOME=") { + e = "HOME=/root" + } + res = append(res, e) + } + return res + }() + out, err := keycmd.CombinedOutput() if err != nil { log.WithError(err).WithField("out", string(out)).Error("cannot create hostkey file") return } cmd := exec.Command(dropbear, "-F", "-E", "-w", "-s", "-p", fmt.Sprintf(":%d", cfg.SSHPort), "-r", hostkeyFN.Name()) - cmd.Env = buildIDEEnv(cfg) + cmd.Env = buildChildProcEnv(cfg) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Start() @@ -1019,7 +1090,7 @@ func socketActivationForDocker(ctx context.Context, wg *sync.WaitGroup, term *te if err != nil { log.WithError(err).Error("cannot provide Docker activation socket") } - _ = os.Chown(fn, 33333, 33333) + _ = os.Chown(fn, gitpodUID, gitpodGID) err = activation.Listen(ctx, l, func(socketFD *os.File) error { cmd := exec.Command("docker-up") cmd.Env = append(os.Environ(), "LISTEN_FDS=1") @@ -1117,7 +1188,7 @@ func runAsGitpodUser(cmd *exec.Cmd) *exec.Cmd { if cmd.SysProcAttr.Credential == nil { cmd.SysProcAttr.Credential = &syscall.Credential{} } - cmd.SysProcAttr.Credential.Gid = 33333 - cmd.SysProcAttr.Credential.Uid = 33333 + cmd.SysProcAttr.Credential.Uid = gitpodUID + cmd.SysProcAttr.Credential.Gid = gitpodGID return cmd } diff --git a/components/supervisor/pkg/supervisor/user.go b/components/supervisor/pkg/supervisor/user.go new file mode 100644 index 00000000000000..d1eff6cfc54d6a --- /dev/null +++ b/components/supervisor/pkg/supervisor/user.go @@ -0,0 +1,233 @@ +// 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. + +package supervisor + +import ( + "fmt" + "os/exec" + "os/user" + "strconv" + "strings" + + "github.com/gitpod-io/gitpod/common-go/log" +) + +type lookup interface { + LookupGroup(name string) (grp *user.Group, err error) + LookupGroupId(id string) (grp *user.Group, err error) + Lookup(name string) (grp *user.User, err error) + LookupId(id string) (grp *user.User, err error) +} + +type osLookup struct{} + +func (osLookup) LookupGroup(name string) (grp *user.Group, err error) { return user.LookupGroup(name) } +func (osLookup) LookupGroupId(id string) (grp *user.Group, err error) { return user.LookupGroupId(id) } +func (osLookup) Lookup(name string) (grp *user.User, err error) { return user.Lookup(name) } +func (osLookup) LookupId(id string) (grp *user.User, err error) { return user.LookupId(id) } + +var defaultLookup lookup = osLookup{} + +func AddGitpodUserIfNotExists() error { + ok, err := hasGroup(gitpodGroupName, gitpodGID) + if err != nil { + return err + } + if !ok { + err = addGroup(gitpodGroupName, gitpodGID) + if err != nil { + return err + } + } + + targetUser := &user.User{ + Uid: strconv.Itoa(gitpodUID), + Gid: strconv.Itoa(gitpodGID), + Username: gitpodUserName, + HomeDir: "/home/" + gitpodUserName, + } + ok, err = hasUser(targetUser) + if err != nil { + return err + } + if ok { + return nil + } + + return addUser(targetUser) +} + +func hasGroup(name string, gid int) (bool, error) { + grpByName, err := defaultLookup.LookupGroup(name) + if err == user.UnknownGroupError(name) { + err = nil + } + if err != nil { + return false, err + } + grpByID, err := defaultLookup.LookupGroupId(strconv.Itoa(gid)) + if err == user.UnknownGroupIdError(strconv.Itoa(gid)) { + err = nil + } + if err != nil { + return false, err + } + + if grpByID == nil && grpByName == nil { + // group does not exist + return false, nil + } + if grpByID != nil && grpByName == nil { + // a group with this GID exists already, but has a different name + return true, fmt.Errorf("group %s already uses GID %d", grpByID.Name, gid) + } + if grpByID == nil && grpByName != nil { + // a group with this name already exists, but has a different GID + return true, fmt.Errorf("group named %s exists but uses different GID %s", name, grpByName.Gid) + } + + // group exists and all is well + return true, nil +} + +func hasUser(u *user.User) (bool, error) { + userByName, err := defaultLookup.Lookup(u.Username) + if err == user.UnknownUserError(u.Username) { + err = nil + } + if err != nil { + return false, err + } + userByID, err := defaultLookup.LookupId(u.Uid) + uid, _ := strconv.Atoi(u.Uid) + if err == user.UnknownUserIdError(uid) { + err = nil + } + if err != nil { + return false, err + } + + if userByID == nil && userByName == nil { + // user does not exist + return false, nil + } + if userByID != nil && userByName == nil { + // a user with this GID exists already, but has a different name + return true, fmt.Errorf("user %s already uses UID %s", userByID.Username, u.Uid) + } + if userByID == nil && userByName != nil { + // a user with this name already exists, but has a different GID + return true, fmt.Errorf("user named %s exists but uses different UID %s", u.Username, userByName.Uid) + } + + // at this point it doesn't matter if we use userByID or byName - they're likely the same + // because of the way we looked them up. + existingUser := userByID + if existingUser.Gid != u.Gid { + return true, fmt.Errorf("existing user %s has different GID %s (instead of %s)", existingUser.Username, existingUser.Gid, u.Gid) + } + if existingUser.HomeDir != u.HomeDir { + return true, fmt.Errorf("existing user %s has different home directory %s (instead of %s)", existingUser.Username, existingUser.HomeDir, u.HomeDir) + } + + // user exists and all is well + return true, nil +} + +func addGroup(name string, gid int) error { + flavour := determineAdduserFlavour() + if flavour == adduserUnknown { + return fmt.Errorf("no addgroup command found") + } + + args := addgroupCommand[flavour](name, gid) + out, err := exec.Command(args[0], args[1:]...).CombinedOutput() + if err != nil { + return fmt.Errorf("%w: %s", err, string(out)) + } + log.WithField("args", args).Debug("addgroup") + + return nil +} + +func addUser(opts *user.User) error { + flavour := determineAdduserFlavour() + if flavour == adduserUnknown { + return fmt.Errorf("no adduser command found") + } + + args := adduserCommand[flavour](opts) + out, err := exec.Command(args[0], args[1:]...).CombinedOutput() + if err != nil { + return fmt.Errorf("%v: %w: %s", args, err, string(out)) + } + log.WithField("args", args).Debug("adduser") + + return nil +} + +func determineAdduserFlavour() adduserFlavour { + for flavour, gen := range adduserCommand { + args := gen(&user.User{}) + var flags []string + for _, a := range args { + if len(a) > 0 && a[0] == '-' { + flags = append(flags, a) + } + } + + rout, _ := exec.Command(args[0], "-h").CombinedOutput() + var ( + out = string(rout) + found = true + ) + for _, f := range flags { + if !strings.Contains(out, f) { + found = false + break + } + } + if found { + return flavour + } + } + + return adduserUnknown +} + +type adduserFlavour int + +const ( + adduserUnknown adduserFlavour = iota + adduserBusybox + adduserDebian + adduserUseradd +) + +const defaultShell = "/bin/sh" + +var adduserCommand = map[adduserFlavour]func(*user.User) []string{ + adduserBusybox: func(opts *user.User) []string { + return []string{"adduser", "-h", opts.HomeDir, "-s", defaultShell, "-D", "-G", opts.Gid, "-u", opts.Uid, opts.Username} + }, + adduserDebian: func(opts *user.User) []string { + return []string{"adduser", "--home", opts.HomeDir, "--shell", defaultShell, "--disabled-login", "--gid", opts.Gid, "--uid", opts.Uid, opts.Username} + }, + adduserUseradd: func(opts *user.User) []string { + return []string{"useradd", "-m", "--home-dir", opts.HomeDir, "--shell", defaultShell, "--gid", opts.Gid, "--uid", opts.Uid, opts.Username} + }, +} + +var addgroupCommand = map[adduserFlavour]func(name string, gid int) []string{ + adduserBusybox: func(name string, gid int) []string { + return []string{"addgroup", "-g", strconv.Itoa(gid), name} + }, + adduserDebian: func(name string, gid int) []string { + return []string{"addgroup", "--gid", strconv.Itoa(gid), name} + }, + adduserUseradd: func(name string, gid int) []string { + return []string{"groupadd", "--gid", strconv.Itoa(gid), name} + }, +} diff --git a/components/supervisor/pkg/supervisor/user_test.go b/components/supervisor/pkg/supervisor/user_test.go new file mode 100644 index 00000000000000..dea1271de38f93 --- /dev/null +++ b/components/supervisor/pkg/supervisor/user_test.go @@ -0,0 +1,204 @@ +// 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. + +package supervisor + +import ( + "os/user" + "strconv" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestHasUser(t *testing.T) { + gitpodUser := user.User{Username: gitpodUserName, Uid: strconv.Itoa(gitpodUID), HomeDir: "/home/gitpod", Gid: strconv.Itoa(gitpodGID)} + mod := func(u user.User, m func(u *user.User)) *user.User { + m(&u) + return &u + } + + type Expectation struct { + Exists bool + Error string + } + tests := []struct { + Name string + Ops ops + Expectation Expectation + }{ + { + Name: "does exist", + Ops: ops{ + RLookup: opsResult{User: &gitpodUser}, + RLookupId: opsResult{User: &gitpodUser}, + }, + Expectation: Expectation{Exists: true}, + }, + { + Name: "does not exist", + Ops: ops{ + RLookup: opsResult{Err: user.UnknownUserError(gitpodUserName)}, + RLookupId: opsResult{Err: user.UnknownUserIdError(gitpodUID)}, + }, + }, + { + Name: "different UID", + Ops: ops{ + RLookup: opsResult{User: mod(gitpodUser, func(u *user.User) { u.Uid = "1000" })}, + RLookupId: opsResult{Err: user.UnknownUserIdError(gitpodUID)}, + }, + Expectation: Expectation{ + Exists: true, + Error: "user named gitpod exists but uses different UID 1000", + }, + }, + { + Name: "different name", + Ops: ops{ + RLookup: opsResult{Err: user.UnknownUserError(gitpodUserName)}, + RLookupId: opsResult{User: mod(gitpodUser, func(u *user.User) { u.Username = "foobar" })}, + }, + Expectation: Expectation{ + Exists: true, + Error: "user foobar already uses UID 33333", + }, + }, + { + Name: "different GID", + Ops: ops{ + RLookup: opsResult{User: mod(gitpodUser, func(u *user.User) { u.Gid = "1000" })}, + RLookupId: opsResult{User: mod(gitpodUser, func(u *user.User) { u.Gid = "1000" })}, + }, + Expectation: Expectation{ + Exists: true, + Error: "existing user gitpod has different GID 1000 (instead of 33333)", + }, + }, + { + Name: "different home dir", + Ops: ops{ + RLookup: opsResult{User: mod(gitpodUser, func(u *user.User) { u.HomeDir = "1000" })}, + RLookupId: opsResult{User: mod(gitpodUser, func(u *user.User) { u.HomeDir = "1000" })}, + }, + Expectation: Expectation{ + Exists: true, + Error: "existing user gitpod has different home directory 1000 (instead of /home/gitpod)", + }, + }, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + defaultLookup = test.Ops + exists, err := hasUser(&gitpodUser) + var act Expectation + act.Exists = exists + if err != nil { + act.Error = err.Error() + } + + if diff := cmp.Diff(test.Expectation, act); diff != "" { + t.Errorf("unexpected hasUser (-want +got):\n%s", diff) + } + }) + } +} + +func TestHasGroup(t *testing.T) { + gitpodGroup := user.Group{Name: gitpodGroupName, Gid: strconv.Itoa(gitpodGID)} + mod := func(u user.Group, m func(u *user.Group)) *user.Group { + m(&u) + return &u + } + + type Expectation struct { + Exists bool + Error string + } + tests := []struct { + Name string + Ops ops + Expectation Expectation + }{ + { + Name: "does exist", + Ops: ops{ + RLookupGroup: opsResult{Group: &gitpodGroup}, + RLookupGroupId: opsResult{Group: &gitpodGroup}, + }, + Expectation: Expectation{Exists: true}, + }, + { + Name: "does not exist", + Ops: ops{ + RLookupGroup: opsResult{Err: user.UnknownGroupError(gitpodGroupName)}, + RLookupGroupId: opsResult{Err: user.UnknownGroupIdError(gitpodGroup.Gid)}, + }, + }, + { + Name: "different GID", + Ops: ops{ + RLookupGroup: opsResult{Group: mod(gitpodGroup, func(u *user.Group) { u.Gid = "1000" })}, + RLookupGroupId: opsResult{Err: user.UnknownGroupIdError(gitpodGroup.Gid)}, + }, + Expectation: Expectation{ + Exists: true, + Error: "group named gitpod exists but uses different GID 1000", + }, + }, + { + Name: "different name", + Ops: ops{ + RLookupGroup: opsResult{Err: user.UnknownGroupError(gitpodGroupName)}, + RLookupGroupId: opsResult{Group: mod(gitpodGroup, func(u *user.Group) { u.Name = "foobar" })}, + }, + Expectation: Expectation{ + Exists: true, + Error: "group foobar already uses GID 33333", + }, + }, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + defaultLookup = test.Ops + exists, err := hasGroup(gitpodGroupName, gitpodGID) + var act Expectation + act.Exists = exists + if err != nil { + act.Error = err.Error() + } + + if diff := cmp.Diff(test.Expectation, act); diff != "" { + t.Errorf("unexpected hasGroup (-want +got):\n%s", diff) + } + }) + } +} + +type opsResult struct { + Group *user.Group + User *user.User + Err error +} +type ops struct { + RLookup opsResult + RLookupId opsResult + RLookupGroup opsResult + RLookupGroupId opsResult +} + +func (o ops) LookupGroup(name string) (grp *user.Group, err error) { + return o.RLookupGroup.Group, o.RLookupGroup.Err +} +func (o ops) LookupGroupId(id string) (grp *user.Group, err error) { + return o.RLookupGroupId.Group, o.RLookupGroupId.Err +} +func (o ops) Lookup(name string) (grp *user.User, err error) { + return o.RLookup.User, o.RLookup.Err +} +func (o ops) LookupId(id string) (grp *user.User, err error) { + return o.RLookupId.User, o.RLookupId.Err +} diff --git a/components/workspacekit/cmd/rings.go b/components/workspacekit/cmd/rings.go index 44d4f7a71ad142..29fcf3fdd1af23 100644 --- a/components/workspacekit/cmd/rings.go +++ b/components/workspacekit/cmd/rings.go @@ -737,6 +737,10 @@ func handleExit(ec *int) { } func sleepForDebugging() { + if os.Getenv("GITPOD_WORKSPACEKIT_SLEEP_FOR_DEBUGGING") != "true" { + return + } + log.Info("sleeping five minutes to allow debugging") sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) diff --git a/components/ws-manager/pkg/manager/testdata/status_headless_STOPPING00.json b/components/ws-manager/pkg/manager/testdata/status_headless_STOPPING00.json index 8d9f6e0d372873..df4f5f4c5da4aa 100644 --- a/components/ws-manager/pkg/manager/testdata/status_headless_STOPPING00.json +++ b/components/ws-manager/pkg/manager/testdata/status_headless_STOPPING00.json @@ -1 +1 @@ -{"pod":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/pods/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","resourceVersion":"237707407","creationTimestamp":"2021-07-21T16:02:45Z","labels":{"app":"gitpod","component":"workspace","gitpod.io/networkpolicy":"default","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict":"false","cni.projectcalico.org/podIP":"","cni.projectcalico.org/podIPs":"","container.apparmor.security.beta.kubernetes.io/workspace":"unconfined","gitpod.io/annotation.baseref":"eu.gcr.io/gitpod-core-dev/registry/base-images:d04c64d5d108632a1768e4af9c3a8a3e6a87c96d2566fb1b0d1aec2fd630e8bd","gitpod.io/annotation.ref":"eu.gcr.io/gitpod-core-dev/registry/workspace-images:a277dab62e839192eb320da283d4e8488a2b2f46fceb4677a7d571431e239aa5","gitpod.io/nodeName":"gke-dev-workload-1-49d27f81-8s5c","gitpod.io/requiredNodeServices":"ws-daemon,registry-facade","gitpod/admission":"admit_owner_only","gitpod/contentInitializer":"[redacted]","gitpod/customTimeout":"1h0m0s","gitpod/id":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","gitpod/imageSpec":"Cl5ldS5nY3IuaW8vZ2l0cG9kLWNvcmUtZGV2L2J1aWxkL2ltYWdlLWJ1aWxkZXItbWszL2JvYjoyY2Y3NDc4NjdmZjgwNGVlMGVkYzBhMjYwN2NiOGNhMDYyNDIwODNhEl5ldS5nY3IuaW8vZ2l0cG9kLWNvcmUtZGV2L2J1aWxkL2ltYWdlLWJ1aWxkZXItbWszL2JvYjoyY2Y3NDc4NjdmZjgwNGVlMGVkYzBhMjYwN2NiOGNhMDYyNDIwODNh","gitpod/never-ready":"true","gitpod/ownerToken":"osZStmqg3TI0NrkLe3edax9bYCknXWtr","gitpod/servicePrefix":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","gitpod/url":"https://0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com","kubernetes.io/psp":"staging-cw-imgbuilder-mk3-rebase-ns-workspace","prometheus.io/path":"/metrics","prometheus.io/port":"23000","prometheus.io/scrape":"true","seccomp.security.alpha.kubernetes.io/pod":"localhost/workspace_default_cw-imgbuilder-mk3-rebase.100.json"},"finalizers":["gitpod.io/finalizer"],"managedFields":[{"manager":"calico","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:46Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:cni.projectcalico.org/podIP":{},"f:cni.projectcalico.org/podIPs":{}}}}},{"manager":"ws-manager","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:04Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:cluster-autoscaler.kubernetes.io/safe-to-evict":{},"f:container.apparmor.security.beta.kubernetes.io/workspace":{},"f:gitpod.io/annotation.baseref":{},"f:gitpod.io/annotation.ref":{},"f:gitpod.io/nodeName":{},"f:gitpod.io/requiredNodeServices":{},"f:gitpod/admission":{},"f:gitpod/contentInitializer":{},"f:gitpod/customTimeout":{},"f:gitpod/id":{},"f:gitpod/imageSpec":{},"f:gitpod/never-ready":{},"f:gitpod/ownerToken":{},"f:gitpod/servicePrefix":{},"f:gitpod/url":{},"f:prometheus.io/path":{},"f:prometheus.io/port":{},"f:prometheus.io/scrape":{},"f:seccomp.security.alpha.kubernetes.io/pod":{}},"f:finalizers":{".":{},"v:\"gitpod.io/finalizer\"":{}},"f:labels":{".":{},"f:app":{},"f:component":{},"f:gitpod.io/networkpolicy":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}}},"f:spec":{"f:automountServiceAccountToken":{},"f:containers":{"k:{\"name\":\"workspace\"}":{".":{},"f:command":{},"f:env":{".":{},"k:{\"name\":\"BOB_AUTH_KEY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BASELAYER_AUTH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BASE_REF\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BUILD_BASE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_CONTEXT_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_DOCKERFILE_PATH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_GPLAYER_AUTH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_TARGET_REF\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_CLI_APITOKEN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_HEADLESS\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_HOST\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_INSTANCE_ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_INTERVAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_MEMORY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_REPO_ROOT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_TASKS\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_THEIA_PORT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_CLUSTER_HOST\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_URL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_MINI_BROWSER_HOST_PATTERN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_SUPERVISOR_ENDPOINT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_WEBVIEW_EXTERNAL_ENDPOINT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_WORKSPACE_ROOT\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:ports":{".":{},"k:{\"containerPort\":23000,\"protocol\":\"TCP\"}":{".":{},"f:containerPort":{},"f:protocol":{}}},"f:readinessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:ephemeral-storage":{},"f:memory":{}}},"f:securityContext":{".":{},"f:allowPrivilegeEscalation":{},"f:capabilities":{".":{},"f:add":{},"f:drop":{}},"f:privileged":{},"f:readOnlyRootFilesystem":{},"f:runAsGroup":{},"f:runAsNonRoot":{},"f:runAsUser":{}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/.workspace\"}":{".":{},"f:mountPath":{},"f:mountPropagation":{},"f:name":{}},"k:{\"mountPath\":\"/workspace\"}":{".":{},"f:mountPath":{},"f:mountPropagation":{},"f:name":{}}}}},"f:dnsConfig":{".":{},"f:nameservers":{}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:imagePullSecrets":{".":{},"k:{\"name\":\"gcp-sa-registry-auth\"}":{".":{},"f:name":{}}},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{".":{},"f:fsGroup":{},"f:seccompProfile":{"f:localhostProfile":{},"f:type":{}},"f:supplementalGroups":{}},"f:serviceAccount":{},"f:serviceAccountName":{},"f:terminationGracePeriodSeconds":{},"f:tolerations":{},"f:volumes":{".":{},"k:{\"name\":\"daemon-mount\"}":{".":{},"f:hostPath":{".":{},"f:path":{},"f:type":{}},"f:name":{}},"k:{\"name\":\"vol-this-workspace\"}":{".":{},"f:hostPath":{".":{},"f:path":{},"f:type":{}},"f:name":{}}}}}},{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:08:00Z","fieldsType":"FieldsV1","fieldsV1":{"f:status":{"f:conditions":{"k:{\"type\":\"ContainersReady\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Initialized\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Ready\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}}},"f:containerStatuses":{},"f:hostIP":{},"f:phase":{},"f:podIP":{},"f:podIPs":{".":{},"k:{\"ip\":\"10.60.22.132\"}":{".":{},"f:ip":{}}},"f:startTime":{}}}}]},"spec":{"volumes":[{"name":"vol-this-workspace","hostPath":{"path":"/mnt/disks/ssd0/workspaces/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","type":"DirectoryOrCreate"}},{"name":"daemon-mount","hostPath":{"path":"/mnt/disks/ssd0/workspaces/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-daemon","type":"DirectoryOrCreate"}}],"containers":[{"name":"workspace","image":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","command":["/.supervisor/workspacekit","ring0"],"ports":[{"containerPort":23000,"protocol":"TCP"}],"env":[{"name":"GITPOD_REPO_ROOT","value":"/workspace"},{"name":"GITPOD_CLI_APITOKEN","value":"TUf744QntqioSRIrnIVpic9CpLnKQCbj"},{"name":"GITPOD_WORKSPACE_ID","value":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b"},{"name":"GITPOD_INSTANCE_ID","value":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b"},{"name":"GITPOD_THEIA_PORT","value":"23000"},{"name":"THEIA_WORKSPACE_ROOT","value":"/workspace/workspace"},{"name":"GITPOD_HOST","value":"https://cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"GITPOD_WORKSPACE_URL","value":"https://0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"GITPOD_WORKSPACE_CLUSTER_HOST","value":"ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"THEIA_SUPERVISOR_ENDPOINT","value":":22999"},{"name":"THEIA_WEBVIEW_EXTERNAL_ENDPOINT","value":"webview-{{hostname}}"},{"name":"THEIA_MINI_BROWSER_HOST_PATTERN","value":"browser-{{hostname}}"},{"name":"BOB_TARGET_REF","value":"eu.gcr.io/gitpod-core-dev/registry/workspace-images:a277dab62e839192eb320da283d4e8488a2b2f46fceb4677a7d571431e239aa5"},{"name":"BOB_BASE_REF","value":"eu.gcr.io/gitpod-core-dev/registry/base-images:d04c64d5d108632a1768e4af9c3a8a3e6a87c96d2566fb1b0d1aec2fd630e8bd"},{"name":"BOB_BUILD_BASE","value":"true"},{"name":"BOB_BASELAYER_AUTH","value":"bI9gBDvDtwGZby8T1Wd3HdjrKz0HH4Kcrdyxtij1"},{"name":"BOB_GPLAYER_AUTH","value":"PetXlerz2kjoa7FPdWuqdaC6o48qmFNCSUlx/DY+VvEh56pB85zB/0xcM2N4haYk3Umoa9OAJvu33AuB9GakbIOxHtF7IqgQUFRD+p2+yM80mWtHcTn13wVrpo2diIH91Ne58Qr+qz8l6q2sXKg/U4YJr0x4kIg1110iKD1r1GklhvlaQuIudUTQdY264ama2FQcrJjpnqaQIYIO4cOhc2lI9y34MGqwSlFfzuqjcKLpt2/XW+CwZxH2h5JKcgmZjcUyClA/GcC1mgJX3b4eqgsravlTloRvMti8IgWK8s4xiOU9qFEFCWcGIXwdj16Abtn5GoWDNFyHFF5Ojss7QzTEx395QnMgLEVxZrkscJc0Afn+ewKXF3oceoIuWe0GmgvbRnzuUv9ftnc7BPWgNq0HXr8J3RBBcnlXSQlcECljq8TW6vtkSDKrOnPeTSLZ12jj+PtmVwDvPCRYevo6TSIluyt6EEpm1aKV9Rt6VuGAFNFZfRLlKx0UivOUzgcUUN0UJ6itBsQKW97o/8sax03PTvcHbP+CtvYYwGXKqF3nO3SQs0eiDhqi0IV4/TvzjvsLm5UFC+VqEzahRMm7fhvoKdmPMBu0kGiFE3bZK4w7s3vWoliWnHS27Mg8GawGySOp1Y8cy15B07Y6tyRcxwJ3dRxYulvEm8w4+9RgGor1w8ScMqZ/GugXhHOUVfDjomTqDhooDLWw7VB3JKqCLlOcZ42cdheHWnEyLtFhDMisESukMfT99cq95L5ZIARTqS2gpcRDro/iiumvwe6Hr+gNtuz/NCA0dKPgst5vLZYzcjJvcHzOSR88iqnottSeuX2NVU5FoqNaMqURcXXvp9oXkrAJ8JILDmE+cMhna+pKK+nbFa7NE8zzvGoxUnZNbPUzu2FT7AXyMPKr5mWOBwQY9Jb7OxQXoqAtCBoAT6pKgan/BkaC02o3kwgt50aYWt0bmdl2/JPoF01+bhbmbIGK6I/B/oOMU5VMXTfHIKg4Q5LJX540JxQB6g4z7wR8eAHLQ3F6GyXcV69xZX64veKXvx3NhZ75lcwjzC9mtUvoXzftM3lsTFwQGlBrzC6wKPGotQJh7dRH8HYKuUdjm/z0xElVKaaNHtMkQ6yNGNQ1lQZpdGDYQwqxMXHd61zolL3JVwovDPax3tNn69mfeAnhnKJ4MQHi+804EO80NrLMJNHxbETdcaE6M/meprmmlsd8Z0ZxSrAcbU4pqNoeSEfC5U2W6DWhP5jiagqml/d7wq2rh8CV1wAct/FLLX/nWC9BejZ2caTTennh3bNpaTfDHDL35+a7+24k74SAw8Py1CsRGqm8LyfwbQEgw4Lihe8k24DA5R3nB+pSFcze4SQhFBWNFK8ZS9MHYWPKEi3ptvCoeTs+fkXuhqDy3pIlkVPJNrP9eCQES7+INgFAUmQ3yuB1YZeev6bjz5mGV+XIV2P12ngz4+y/tTL75+y2QEDC2FWO9rgMC27Q/4WZo+PUIEyf7tLHsOKvvPCJrRIQzBNFCSRg4I6j2A9cK84l6NFKPQhfkzttv8YdsNWClflaDuf5Te3PKPh2pozWmFIeYlufgNFZ7TIEziwFzp9p9emI1O0pVaDlQ0hKeK67GJTNXh5vzYCwBbMSLQECMmClinYHYYS7fMzfmlRwsvKIdeHf2yjCbN8dBhQx7AuLvyiHVNmrBDhPlmB8wbzvAAz8ODz4OiNisXbOJq0+nmok5Jdf1tfuJOnfdKeVwDVRrDkTqUP0W53a34pBdHWctD70o/fVmxxqzJ7R1I6U3YuCYJkTlvvEjCqCbNPKseNBfEAVy/FYpKYj0A7IgILtbVi5SCSPnEAkOnZD1x2yrH0bUhQoBpJ38Je69pkVOnZwpyPvgJFWfKun8WRgdQMzIYA6SrBqRItKOAN7Fd1YHMys8BaJZbwQo7ZuEsnAYwKIS563dc67clKsjbUJ+VkiXeRyUaZiubHweu6vgouSPi8kvZ5aNx98oj+vGUQpoJK1yhZH/siAiPBmf5JIm9qzDM64Y99Biai7Mw4eICCz0qHk4kboS2n1cHePk780o2mpXifVtuc7RK2Rr9UbxQ2PiygFNYZh7mPWc0qCJm/81b/rOP7UQDJuBbNw9U0EslW7uS3Fvl80kvO43SgWxXJTykMJJ3vr94WyAoNagV2e3AB+qCvsCWkn4o7Mwb6EmbobvHBuOHEJVeA4P030B+KCpSLNxwnmZdxJG7NdTjTxXakYV2AEGQLGQuUuYtkMLBBoeQUInNwpJvwslcQCXGn4naVQjCerwip/vMOKaW+vHYhdl8zlg30tjx+oUuyx86LNcv3sNpZapvJvo9UoyfMxmwVv4X/GGkB73v1bRJbH5BJ5+5v+phLvYRMc3rsrSk76Us1hKVyKAfK14m4T+RqAprplf8k1crdaniOnebFRJCWg0QujgS+2EUBpIoAZu184zTirARHs2ip9WikVLXD3gqY2dIbrsCsiNLjTAR/pf8Og9e/VjYfszM56de9q9tNBcNM15oA1w60UwSLlyLNIZR8Uum75UICOEGVimsS73P6rFFsmlvIK8Tr+uVsgt8IKhJsyVArrCVGx3cwaVKMNp2XXNfzEUTy6r86pPXvqQEfKhiDgRkf79HLjx0BxVFgpxjMNHUdgsARTK2ElIAsO/sh/WbsvsHByfQZeTR7iDgxxfJQzA1xpnltctQp95tPWbsj2HlzI9rr95/jAUASJcyMA9cWfN5NZWrgkxP//Prc7pMHsmjCNh0PbSVyPTdRWqdxjZXqMPdm0PNQXWEjtkE5R5830JtqhLLToHBHpbCVbmHTUllkFOYnzob9YkrHYdhez/66VDJGNhms2aVi3bu4X2sjo4f8rbP+1dxdi8n/vRf3zaEAW3vy2fASfwvmPN7yFH9Y4mxiezSNdH16y+c2/NOlM8cgGLA1WJX1liFGvFzDNHsjYRX4sHLlx+zuUf/YBqBTGPzxNZz8GOx/7LZhg3ilcqfDl4fChqEDDvSrsXLX88Hv+1St0FpRikIKimUHUx5X0ClVihAkRamm1M9lR9NsxVV6DEGC6JeWmAls/DD+cEUybS+JwQItLz+lbi5kMTibJale+pl5pFg/eNNZQkTPE1GoEf85JZ6moOp6fwqAhBLLCYzcWTYGHKYdknPkvfopB5HFMQi/biBdvbg7N3cYpH/DpfHs2bNAlI8xTn0lxi6ABuie7o4XPpKt1m2eQw3VGYK5n8b22e2aVjIilOwUQmfrdBX2QuOxLg1OVJGAYJkOjmBaAM14bTMaMGSJo0t60EuFydwaiQ9nYVecjploe8I4RCjYLBskzQICb8XlEeSCIThqKiFaaEis"},{"name":"BOB_DOCKERFILE_PATH","value":"/workspace/.gitpod.dockerfile"},{"name":"BOB_CONTEXT_DIR","value":"/workspace"},{"name":"BOB_AUTH_KEY","value":"GR9u6Y6MnUp4BxDZmSFvwaciqkNOqpQ1"},{"name":"GITPOD_TASKS","value":"[{\"name\": \"build\", \"init\": \"sudo -E /app/bob build\"}]"},{"name":"GITPOD_INTERVAL","value":"30000"},{"name":"GITPOD_MEMORY","value":"2415"},{"name":"GITPOD_HEADLESS","value":"true"}],"resources":{"limits":{"cpu":"5","memory":"12Gi"},"requests":{"cpu":"1m","ephemeral-storage":"5Gi","memory":"2304Mi"}},"volumeMounts":[{"name":"vol-this-workspace","mountPath":"/workspace","mountPropagation":"HostToContainer"},{"name":"daemon-mount","mountPath":"/.workspace","mountPropagation":"HostToContainer"}],"readinessProbe":{"httpGet":{"path":"/_supervisor/v1/status/content/wait/true","port":22999,"scheme":"HTTP"},"timeoutSeconds":1,"periodSeconds":1,"successThreshold":1,"failureThreshold":600},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{"add":["AUDIT_WRITE","FSETID","KILL","NET_BIND_SERVICE","SYS_PTRACE"],"drop":["SETPCAP","CHOWN","NET_RAW","DAC_OVERRIDE","FOWNER","SYS_CHROOT","SETFCAP","SETUID","SETGID"]},"privileged":false,"runAsUser":33333,"runAsGroup":33333,"runAsNonRoot":true,"readOnlyRootFilesystem":false,"allowPrivilegeEscalation":true}}],"restartPolicy":"Never","terminationGracePeriodSeconds":30,"dnsPolicy":"None","serviceAccountName":"workspace","serviceAccount":"workspace","automountServiceAccountToken":false,"nodeName":"gke-dev-workload-1-49d27f81-8s5c","securityContext":{"supplementalGroups":[1],"fsGroup":1,"seccompProfile":{"type":"Localhost","localhostProfile":"workspace_default_cw-imgbuilder-mk3-rebase.100.json"}},"imagePullSecrets":[{"name":"gcp-sa-registry-auth"}],"schedulerName":"workspace-scheduler","tolerations":[{"key":"node.kubernetes.io/disk-pressure","operator":"Exists","effect":"NoExecute"},{"key":"node.kubernetes.io/memory-pressure","operator":"Exists","effect":"NoExecute"},{"key":"node.kubernetes.io/network-unavailable","operator":"Exists","effect":"NoExecute","tolerationSeconds":30},{"key":"node.kubernetes.io/not-ready","operator":"Exists","effect":"NoExecute","tolerationSeconds":300},{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute","tolerationSeconds":300}],"priority":0,"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"enableServiceLinks":false,"preemptionPolicy":"PreemptLowerPriority"},"status":{"phase":"Succeeded","conditions":[{"type":"Initialized","status":"True","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:02:45Z","reason":"PodCompleted"},{"type":"Ready","status":"False","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:08:00Z","reason":"PodCompleted"},{"type":"ContainersReady","status":"False","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:08:00Z","reason":"PodCompleted"},{"type":"PodScheduled","status":"True","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:02:45Z"}],"hostIP":"10.132.0.17","podIP":"10.60.22.132","podIPs":[{"ip":"10.60.22.132"}],"startTime":"2021-07-21T16:02:45Z","containerStatuses":[{"name":"workspace","state":{"terminated":{"exitCode":0,"reason":"Completed","startedAt":"2021-07-21T16:03:04Z","finishedAt":"2021-07-21T16:07:59Z","containerID":"containerd://b1a0fe3f35a826fbf8fee1518f2ccb7c75f818b4ea9cc17bb22586c18aaa1410"}},"lastState":{},"ready":false,"restartCount":0,"image":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b:latest","imageID":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b@sha256:d86c7d32f939aa04b1092968a624ffe697c9c35268be230169070a2a52d4bda9","containerID":"containerd://b1a0fe3f35a826fbf8fee1518f2ccb7c75f818b4ea9cc17bb22586c18aaa1410","started":false}],"qosClass":"Burstable"}},"theiaService":{"kind":"Service","apiVersion":"v1","metadata":{"name":"ws-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-theia","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/services/ws-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-theia","uid":"cdb765b1-60ee-4bf9-9e5e-c8e635c719df","resourceVersion":"237704855","creationTimestamp":"2021-07-21T16:02:45Z","labels":{"app":"gitpod","component":"workspace","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"managedFields":[{"manager":"ws-manager","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:45Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:labels":{".":{},"f:app":{},"f:component":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}}},"f:spec":{"f:ports":{".":{},"k:{\"port\":22999,\"protocol\":\"TCP\"}":{".":{},"f:name":{},"f:port":{},"f:protocol":{},"f:targetPort":{}},"k:{\"port\":23000,\"protocol\":\"TCP\"}":{".":{},"f:name":{},"f:port":{},"f:protocol":{},"f:targetPort":{}}},"f:selector":{".":{},"f:app":{},"f:component":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}},"f:sessionAffinity":{},"f:type":{}}}}]},"spec":{"ports":[{"name":"ide","protocol":"TCP","port":23000,"targetPort":23000},{"name":"supervisor","protocol":"TCP","port":22999,"targetPort":22999}],"selector":{"app":"gitpod","component":"workspace","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"clusterIP":"10.63.242.92","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"events":[{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b - scrdhnl","generateName":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b - scheduled","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b%20-%20scrdhnl","uid":"b09f5f40-c5a1-49c4-abb4-c12889a4c151","resourceVersion":"14681306","creationTimestamp":"2021-07-21T16:02:45Z","managedFields":[{"manager":"ws-scheduler","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:45Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:kind":{},"f:name":{},"f:namespace":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:metadata":{"f:generateName":{}},"f:reason":{},"f:source":{"f:component":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07"},"reason":"Scheduled","message":"Placed pod [staging-cw-imgbuilder-mk3-rebase/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b] on gke-dev-workload-1-49d27f81-8s5c\n","source":{"component":"workspace-scheduler"},"firstTimestamp":"2021-07-21T16:02:45Z","lastTimestamp":"2021-07-21T16:02:45Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9cd60f7517f","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9cd60f7517f","uid":"4aadb7e6-0974-4245-bacf-733a3de21487","resourceVersion":"14681307","creationTimestamp":"2021-07-21T16:02:46Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:46Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Pulling","message":"Pulling image \"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b\"","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:02:46Z","lastTimestamp":"2021-07-21T16:02:46Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d0efea9977","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d0efea9977","uid":"1914f2c6-0da1-4efc-bcd4-561c33c44f87","resourceVersion":"14681308","creationTimestamp":"2021-07-21T16:03:01Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:01Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Pulled","message":"Successfully pulled image \"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b\" in 15.283188815s","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:01Z","lastTimestamp":"2021-07-21T16:03:01Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d162cf7143","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d162cf7143","uid":"2abb038a-e90b-44f1-85fd-5b4d61a8e307","resourceVersion":"14681309","creationTimestamp":"2021-07-21T16:03:03Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:03Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Created","message":"Created container workspace","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:03Z","lastTimestamp":"2021-07-21T16:03:03Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d17488b910","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d17488b910","uid":"0f2b6737-f1c8-4956-b834-5cd51f342d41","resourceVersion":"14681310","creationTimestamp":"2021-07-21T16:03:04Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:04Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Started","message":"Started container workspace","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:04Z","lastTimestamp":"2021-07-21T16:03:04Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""}]} \ No newline at end of file +{"pod":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/pods/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","resourceVersion":"237707407","creationTimestamp":"2021-07-21T16:02:45Z","labels":{"app":"gitpod","component":"workspace","gitpod.io/networkpolicy":"default","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict":"false","cni.projectcalico.org/podIP":"","cni.projectcalico.org/podIPs":"","container.apparmor.security.beta.kubernetes.io/workspace":"unconfined","gitpod.io/annotation.baseref":"eu.gcr.io/gitpod-core-dev/registry/base-images:d04c64d5d108632a1768e4af9c3a8a3e6a87c96d2566fb1b0d1aec2fd630e8bd","gitpod.io/annotation.ref":"eu.gcr.io/gitpod-core-dev/registry/workspace-images:a277dab62e839192eb320da283d4e8488a2b2f46fceb4677a7d571431e239aa5","gitpod.io/nodeName":"gke-dev-workload-1-49d27f81-8s5c","gitpod.io/requiredNodeServices":"ws-daemon,registry-facade","gitpod/admission":"admit_owner_only","gitpod/contentInitializer":"[redacted]","gitpod/customTimeout":"1h0m0s","gitpod/id":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","gitpod/imageSpec":"Cl5ldS5nY3IuaW8vZ2l0cG9kLWNvcmUtZGV2L2J1aWxkL2ltYWdlLWJ1aWxkZXItbWszL2JvYjoyY2Y3NDc4NjdmZjgwNGVlMGVkYzBhMjYwN2NiOGNhMDYyNDIwODNhEl5ldS5nY3IuaW8vZ2l0cG9kLWNvcmUtZGV2L2J1aWxkL2ltYWdlLWJ1aWxkZXItbWszL2JvYjoyY2Y3NDc4NjdmZjgwNGVlMGVkYzBhMjYwN2NiOGNhMDYyNDIwODNh","gitpod/never-ready":"true","gitpod/ownerToken":"osZStmqg3TI0NrkLe3edax9bYCknXWtr","gitpod/servicePrefix":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","gitpod/url":"https://0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com","kubernetes.io/psp":"staging-cw-imgbuilder-mk3-rebase-ns-workspace","prometheus.io/path":"/metrics","prometheus.io/port":"23000","prometheus.io/scrape":"true","seccomp.security.alpha.kubernetes.io/pod":"localhost/workspace_default_cw-imgbuilder-mk3-rebase.100.json"},"finalizers":["gitpod.io/finalizer"],"managedFields":[{"manager":"calico","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:46Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{"f:cni.projectcalico.org/podIP":{},"f:cni.projectcalico.org/podIPs":{}}}}},{"manager":"ws-manager","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:04Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:cluster-autoscaler.kubernetes.io/safe-to-evict":{},"f:container.apparmor.security.beta.kubernetes.io/workspace":{},"f:gitpod.io/annotation.baseref":{},"f:gitpod.io/annotation.ref":{},"f:gitpod.io/nodeName":{},"f:gitpod.io/requiredNodeServices":{},"f:gitpod/admission":{},"f:gitpod/contentInitializer":{},"f:gitpod/customTimeout":{},"f:gitpod/id":{},"f:gitpod/imageSpec":{},"f:gitpod/never-ready":{},"f:gitpod/ownerToken":{},"f:gitpod/servicePrefix":{},"f:gitpod/url":{},"f:prometheus.io/path":{},"f:prometheus.io/port":{},"f:prometheus.io/scrape":{},"f:seccomp.security.alpha.kubernetes.io/pod":{}},"f:finalizers":{".":{},"v:\"gitpod.io/finalizer\"":{}},"f:labels":{".":{},"f:app":{},"f:component":{},"f:gitpod.io/networkpolicy":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}}},"f:spec":{"f:automountServiceAccountToken":{},"f:containers":{"k:{\"name\":\"workspace\"}":{".":{},"f:command":{},"f:env":{".":{},"k:{\"name\":\"BOB_AUTH_KEY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BASELAYER_AUTH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BASE_REF\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_BUILD_BASE\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_CONTEXT_DIR\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_DOCKERFILE_PATH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_WSLAYER_AUTH\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"BOB_TARGET_REF\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_CLI_APITOKEN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_HEADLESS\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_HOST\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_INSTANCE_ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_INTERVAL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_MEMORY\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_REPO_ROOT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_TASKS\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_THEIA_PORT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_CLUSTER_HOST\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GITPOD_WORKSPACE_URL\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_MINI_BROWSER_HOST_PATTERN\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_SUPERVISOR_ENDPOINT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_WEBVIEW_EXTERNAL_ENDPOINT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"THEIA_WORKSPACE_ROOT\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:ports":{".":{},"k:{\"containerPort\":23000,\"protocol\":\"TCP\"}":{".":{},"f:containerPort":{},"f:protocol":{}}},"f:readinessProbe":{".":{},"f:failureThreshold":{},"f:httpGet":{".":{},"f:path":{},"f:port":{},"f:scheme":{}},"f:periodSeconds":{},"f:successThreshold":{},"f:timeoutSeconds":{}},"f:resources":{".":{},"f:limits":{".":{},"f:cpu":{},"f:memory":{}},"f:requests":{".":{},"f:cpu":{},"f:ephemeral-storage":{},"f:memory":{}}},"f:securityContext":{".":{},"f:allowPrivilegeEscalation":{},"f:capabilities":{".":{},"f:add":{},"f:drop":{}},"f:privileged":{},"f:readOnlyRootFilesystem":{},"f:runAsGroup":{},"f:runAsNonRoot":{},"f:runAsUser":{}},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{},"f:volumeMounts":{".":{},"k:{\"mountPath\":\"/.workspace\"}":{".":{},"f:mountPath":{},"f:mountPropagation":{},"f:name":{}},"k:{\"mountPath\":\"/workspace\"}":{".":{},"f:mountPath":{},"f:mountPropagation":{},"f:name":{}}}}},"f:dnsConfig":{".":{},"f:nameservers":{}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:imagePullSecrets":{".":{},"k:{\"name\":\"gcp-sa-registry-auth\"}":{".":{},"f:name":{}}},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{".":{},"f:fsGroup":{},"f:seccompProfile":{"f:localhostProfile":{},"f:type":{}},"f:supplementalGroups":{}},"f:serviceAccount":{},"f:serviceAccountName":{},"f:terminationGracePeriodSeconds":{},"f:tolerations":{},"f:volumes":{".":{},"k:{\"name\":\"daemon-mount\"}":{".":{},"f:hostPath":{".":{},"f:path":{},"f:type":{}},"f:name":{}},"k:{\"name\":\"vol-this-workspace\"}":{".":{},"f:hostPath":{".":{},"f:path":{},"f:type":{}},"f:name":{}}}}}},{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:08:00Z","fieldsType":"FieldsV1","fieldsV1":{"f:status":{"f:conditions":{"k:{\"type\":\"ContainersReady\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Initialized\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Ready\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:reason":{},"f:status":{},"f:type":{}}},"f:containerStatuses":{},"f:hostIP":{},"f:phase":{},"f:podIP":{},"f:podIPs":{".":{},"k:{\"ip\":\"10.60.22.132\"}":{".":{},"f:ip":{}}},"f:startTime":{}}}}]},"spec":{"volumes":[{"name":"vol-this-workspace","hostPath":{"path":"/mnt/disks/ssd0/workspaces/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","type":"DirectoryOrCreate"}},{"name":"daemon-mount","hostPath":{"path":"/mnt/disks/ssd0/workspaces/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-daemon","type":"DirectoryOrCreate"}}],"containers":[{"name":"workspace","image":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","command":["/.supervisor/workspacekit","ring0"],"ports":[{"containerPort":23000,"protocol":"TCP"}],"env":[{"name":"GITPOD_REPO_ROOT","value":"/workspace"},{"name":"GITPOD_CLI_APITOKEN","value":"TUf744QntqioSRIrnIVpic9CpLnKQCbj"},{"name":"GITPOD_WORKSPACE_ID","value":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b"},{"name":"GITPOD_INSTANCE_ID","value":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b"},{"name":"GITPOD_THEIA_PORT","value":"23000"},{"name":"THEIA_WORKSPACE_ROOT","value":"/workspace/workspace"},{"name":"GITPOD_HOST","value":"https://cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"GITPOD_WORKSPACE_URL","value":"https://0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"GITPOD_WORKSPACE_CLUSTER_HOST","value":"ws-dev.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com"},{"name":"THEIA_SUPERVISOR_ENDPOINT","value":":22999"},{"name":"THEIA_WEBVIEW_EXTERNAL_ENDPOINT","value":"webview-{{hostname}}"},{"name":"THEIA_MINI_BROWSER_HOST_PATTERN","value":"browser-{{hostname}}"},{"name":"BOB_TARGET_REF","value":"eu.gcr.io/gitpod-core-dev/registry/workspace-images:a277dab62e839192eb320da283d4e8488a2b2f46fceb4677a7d571431e239aa5"},{"name":"BOB_BASE_REF","value":"eu.gcr.io/gitpod-core-dev/registry/base-images:d04c64d5d108632a1768e4af9c3a8a3e6a87c96d2566fb1b0d1aec2fd630e8bd"},{"name":"BOB_BUILD_BASE","value":"true"},{"name":"BOB_BASELAYER_AUTH","value":"bI9gBDvDtwGZby8T1Wd3HdjrKz0HH4Kcrdyxtij1"},{"name":"BOB_WSLAYER_AUTH","value":"PetXlerz2kjoa7FPdWuqdaC6o48qmFNCSUlx/DY+VvEh56pB85zB/0xcM2N4haYk3Umoa9OAJvu33AuB9GakbIOxHtF7IqgQUFRD+p2+yM80mWtHcTn13wVrpo2diIH91Ne58Qr+qz8l6q2sXKg/U4YJr0x4kIg1110iKD1r1GklhvlaQuIudUTQdY264ama2FQcrJjpnqaQIYIO4cOhc2lI9y34MGqwSlFfzuqjcKLpt2/XW+CwZxH2h5JKcgmZjcUyClA/GcC1mgJX3b4eqgsravlTloRvMti8IgWK8s4xiOU9qFEFCWcGIXwdj16Abtn5GoWDNFyHFF5Ojss7QzTEx395QnMgLEVxZrkscJc0Afn+ewKXF3oceoIuWe0GmgvbRnzuUv9ftnc7BPWgNq0HXr8J3RBBcnlXSQlcECljq8TW6vtkSDKrOnPeTSLZ12jj+PtmVwDvPCRYevo6TSIluyt6EEpm1aKV9Rt6VuGAFNFZfRLlKx0UivOUzgcUUN0UJ6itBsQKW97o/8sax03PTvcHbP+CtvYYwGXKqF3nO3SQs0eiDhqi0IV4/TvzjvsLm5UFC+VqEzahRMm7fhvoKdmPMBu0kGiFE3bZK4w7s3vWoliWnHS27Mg8GawGySOp1Y8cy15B07Y6tyRcxwJ3dRxYulvEm8w4+9RgGor1w8ScMqZ/GugXhHOUVfDjomTqDhooDLWw7VB3JKqCLlOcZ42cdheHWnEyLtFhDMisESukMfT99cq95L5ZIARTqS2gpcRDro/iiumvwe6Hr+gNtuz/NCA0dKPgst5vLZYzcjJvcHzOSR88iqnottSeuX2NVU5FoqNaMqURcXXvp9oXkrAJ8JILDmE+cMhna+pKK+nbFa7NE8zzvGoxUnZNbPUzu2FT7AXyMPKr5mWOBwQY9Jb7OxQXoqAtCBoAT6pKgan/BkaC02o3kwgt50aYWt0bmdl2/JPoF01+bhbmbIGK6I/B/oOMU5VMXTfHIKg4Q5LJX540JxQB6g4z7wR8eAHLQ3F6GyXcV69xZX64veKXvx3NhZ75lcwjzC9mtUvoXzftM3lsTFwQGlBrzC6wKPGotQJh7dRH8HYKuUdjm/z0xElVKaaNHtMkQ6yNGNQ1lQZpdGDYQwqxMXHd61zolL3JVwovDPax3tNn69mfeAnhnKJ4MQHi+804EO80NrLMJNHxbETdcaE6M/meprmmlsd8Z0ZxSrAcbU4pqNoeSEfC5U2W6DWhP5jiagqml/d7wq2rh8CV1wAct/FLLX/nWC9BejZ2caTTennh3bNpaTfDHDL35+a7+24k74SAw8Py1CsRGqm8LyfwbQEgw4Lihe8k24DA5R3nB+pSFcze4SQhFBWNFK8ZS9MHYWPKEi3ptvCoeTs+fkXuhqDy3pIlkVPJNrP9eCQES7+INgFAUmQ3yuB1YZeev6bjz5mGV+XIV2P12ngz4+y/tTL75+y2QEDC2FWO9rgMC27Q/4WZo+PUIEyf7tLHsOKvvPCJrRIQzBNFCSRg4I6j2A9cK84l6NFKPQhfkzttv8YdsNWClflaDuf5Te3PKPh2pozWmFIeYlufgNFZ7TIEziwFzp9p9emI1O0pVaDlQ0hKeK67GJTNXh5vzYCwBbMSLQECMmClinYHYYS7fMzfmlRwsvKIdeHf2yjCbN8dBhQx7AuLvyiHVNmrBDhPlmB8wbzvAAz8ODz4OiNisXbOJq0+nmok5Jdf1tfuJOnfdKeVwDVRrDkTqUP0W53a34pBdHWctD70o/fVmxxqzJ7R1I6U3YuCYJkTlvvEjCqCbNPKseNBfEAVy/FYpKYj0A7IgILtbVi5SCSPnEAkOnZD1x2yrH0bUhQoBpJ38Je69pkVOnZwpyPvgJFWfKun8WRgdQMzIYA6SrBqRItKOAN7Fd1YHMys8BaJZbwQo7ZuEsnAYwKIS563dc67clKsjbUJ+VkiXeRyUaZiubHweu6vgouSPi8kvZ5aNx98oj+vGUQpoJK1yhZH/siAiPBmf5JIm9qzDM64Y99Biai7Mw4eICCz0qHk4kboS2n1cHePk780o2mpXifVtuc7RK2Rr9UbxQ2PiygFNYZh7mPWc0qCJm/81b/rOP7UQDJuBbNw9U0EslW7uS3Fvl80kvO43SgWxXJTykMJJ3vr94WyAoNagV2e3AB+qCvsCWkn4o7Mwb6EmbobvHBuOHEJVeA4P030B+KCpSLNxwnmZdxJG7NdTjTxXakYV2AEGQLGQuUuYtkMLBBoeQUInNwpJvwslcQCXGn4naVQjCerwip/vMOKaW+vHYhdl8zlg30tjx+oUuyx86LNcv3sNpZapvJvo9UoyfMxmwVv4X/GGkB73v1bRJbH5BJ5+5v+phLvYRMc3rsrSk76Us1hKVyKAfK14m4T+RqAprplf8k1crdaniOnebFRJCWg0QujgS+2EUBpIoAZu184zTirARHs2ip9WikVLXD3gqY2dIbrsCsiNLjTAR/pf8Og9e/VjYfszM56de9q9tNBcNM15oA1w60UwSLlyLNIZR8Uum75UICOEGVimsS73P6rFFsmlvIK8Tr+uVsgt8IKhJsyVArrCVGx3cwaVKMNp2XXNfzEUTy6r86pPXvqQEfKhiDgRkf79HLjx0BxVFgpxjMNHUdgsARTK2ElIAsO/sh/WbsvsHByfQZeTR7iDgxxfJQzA1xpnltctQp95tPWbsj2HlzI9rr95/jAUASJcyMA9cWfN5NZWrgkxP//Prc7pMHsmjCNh0PbSVyPTdRWqdxjZXqMPdm0PNQXWEjtkE5R5830JtqhLLToHBHpbCVbmHTUllkFOYnzob9YkrHYdhez/66VDJGNhms2aVi3bu4X2sjo4f8rbP+1dxdi8n/vRf3zaEAW3vy2fASfwvmPN7yFH9Y4mxiezSNdH16y+c2/NOlM8cgGLA1WJX1liFGvFzDNHsjYRX4sHLlx+zuUf/YBqBTGPzxNZz8GOx/7LZhg3ilcqfDl4fChqEDDvSrsXLX88Hv+1St0FpRikIKimUHUx5X0ClVihAkRamm1M9lR9NsxVV6DEGC6JeWmAls/DD+cEUybS+JwQItLz+lbi5kMTibJale+pl5pFg/eNNZQkTPE1GoEf85JZ6moOp6fwqAhBLLCYzcWTYGHKYdknPkvfopB5HFMQi/biBdvbg7N3cYpH/DpfHs2bNAlI8xTn0lxi6ABuie7o4XPpKt1m2eQw3VGYK5n8b22e2aVjIilOwUQmfrdBX2QuOxLg1OVJGAYJkOjmBaAM14bTMaMGSJo0t60EuFydwaiQ9nYVecjploe8I4RCjYLBskzQICb8XlEeSCIThqKiFaaEis"},{"name":"BOB_DOCKERFILE_PATH","value":"/workspace/.gitpod.dockerfile"},{"name":"BOB_CONTEXT_DIR","value":"/workspace"},{"name":"BOB_AUTH_KEY","value":"GR9u6Y6MnUp4BxDZmSFvwaciqkNOqpQ1"},{"name":"GITPOD_TASKS","value":"[{\"name\": \"build\", \"init\": \"sudo -E /app/bob build\"}]"},{"name":"GITPOD_INTERVAL","value":"30000"},{"name":"GITPOD_MEMORY","value":"2415"},{"name":"GITPOD_HEADLESS","value":"true"}],"resources":{"limits":{"cpu":"5","memory":"12Gi"},"requests":{"cpu":"1m","ephemeral-storage":"5Gi","memory":"2304Mi"}},"volumeMounts":[{"name":"vol-this-workspace","mountPath":"/workspace","mountPropagation":"HostToContainer"},{"name":"daemon-mount","mountPath":"/.workspace","mountPropagation":"HostToContainer"}],"readinessProbe":{"httpGet":{"path":"/_supervisor/v1/status/content/wait/true","port":22999,"scheme":"HTTP"},"timeoutSeconds":1,"periodSeconds":1,"successThreshold":1,"failureThreshold":600},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{"add":["AUDIT_WRITE","FSETID","KILL","NET_BIND_SERVICE","SYS_PTRACE"],"drop":["SETPCAP","CHOWN","NET_RAW","DAC_OVERRIDE","FOWNER","SYS_CHROOT","SETFCAP","SETUID","SETGID"]},"privileged":false,"runAsUser":33333,"runAsGroup":33333,"runAsNonRoot":true,"readOnlyRootFilesystem":false,"allowPrivilegeEscalation":true}}],"restartPolicy":"Never","terminationGracePeriodSeconds":30,"dnsPolicy":"None","serviceAccountName":"workspace","serviceAccount":"workspace","automountServiceAccountToken":false,"nodeName":"gke-dev-workload-1-49d27f81-8s5c","securityContext":{"supplementalGroups":[1],"fsGroup":1,"seccompProfile":{"type":"Localhost","localhostProfile":"workspace_default_cw-imgbuilder-mk3-rebase.100.json"}},"imagePullSecrets":[{"name":"gcp-sa-registry-auth"}],"schedulerName":"workspace-scheduler","tolerations":[{"key":"node.kubernetes.io/disk-pressure","operator":"Exists","effect":"NoExecute"},{"key":"node.kubernetes.io/memory-pressure","operator":"Exists","effect":"NoExecute"},{"key":"node.kubernetes.io/network-unavailable","operator":"Exists","effect":"NoExecute","tolerationSeconds":30},{"key":"node.kubernetes.io/not-ready","operator":"Exists","effect":"NoExecute","tolerationSeconds":300},{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute","tolerationSeconds":300}],"priority":0,"dnsConfig":{"nameservers":["1.1.1.1","8.8.8.8"]},"enableServiceLinks":false,"preemptionPolicy":"PreemptLowerPriority"},"status":{"phase":"Succeeded","conditions":[{"type":"Initialized","status":"True","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:02:45Z","reason":"PodCompleted"},{"type":"Ready","status":"False","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:08:00Z","reason":"PodCompleted"},{"type":"ContainersReady","status":"False","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:08:00Z","reason":"PodCompleted"},{"type":"PodScheduled","status":"True","lastProbeTime":null,"lastTransitionTime":"2021-07-21T16:02:45Z"}],"hostIP":"10.132.0.17","podIP":"10.60.22.132","podIPs":[{"ip":"10.60.22.132"}],"startTime":"2021-07-21T16:02:45Z","containerStatuses":[{"name":"workspace","state":{"terminated":{"exitCode":0,"reason":"Completed","startedAt":"2021-07-21T16:03:04Z","finishedAt":"2021-07-21T16:07:59Z","containerID":"containerd://b1a0fe3f35a826fbf8fee1518f2ccb7c75f818b4ea9cc17bb22586c18aaa1410"}},"lastState":{},"ready":false,"restartCount":0,"image":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b:latest","imageID":"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b@sha256:d86c7d32f939aa04b1092968a624ffe697c9c35268be230169070a2a52d4bda9","containerID":"containerd://b1a0fe3f35a826fbf8fee1518f2ccb7c75f818b4ea9cc17bb22586c18aaa1410","started":false}],"qosClass":"Burstable"}},"theiaService":{"kind":"Service","apiVersion":"v1","metadata":{"name":"ws-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-theia","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/services/ws-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b-theia","uid":"cdb765b1-60ee-4bf9-9e5e-c8e635c719df","resourceVersion":"237704855","creationTimestamp":"2021-07-21T16:02:45Z","labels":{"app":"gitpod","component":"workspace","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"managedFields":[{"manager":"ws-manager","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:45Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:labels":{".":{},"f:app":{},"f:component":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}}},"f:spec":{"f:ports":{".":{},"k:{\"port\":22999,\"protocol\":\"TCP\"}":{".":{},"f:name":{},"f:port":{},"f:protocol":{},"f:targetPort":{}},"k:{\"port\":23000,\"protocol\":\"TCP\"}":{".":{},"f:name":{},"f:port":{},"f:protocol":{},"f:targetPort":{}}},"f:selector":{".":{},"f:app":{},"f:component":{},"f:gpwsman":{},"f:headless":{},"f:metaID":{},"f:owner":{},"f:workspaceID":{},"f:workspaceType":{}},"f:sessionAffinity":{},"f:type":{}}}}]},"spec":{"ports":[{"name":"ide","protocol":"TCP","port":23000,"targetPort":23000},{"name":"supervisor","protocol":"TCP","port":22999,"targetPort":22999}],"selector":{"app":"gitpod","component":"workspace","gpwsman":"true","headless":"true","metaID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","owner":"image-builder","workspaceID":"0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","workspaceType":"imagebuild"},"clusterIP":"10.63.242.92","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"events":[{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b - scrdhnl","generateName":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b - scheduled","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b%20-%20scrdhnl","uid":"b09f5f40-c5a1-49c4-abb4-c12889a4c151","resourceVersion":"14681306","creationTimestamp":"2021-07-21T16:02:45Z","managedFields":[{"manager":"ws-scheduler","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:45Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:kind":{},"f:name":{},"f:namespace":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:metadata":{"f:generateName":{}},"f:reason":{},"f:source":{"f:component":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07"},"reason":"Scheduled","message":"Placed pod [staging-cw-imgbuilder-mk3-rebase/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b] on gke-dev-workload-1-49d27f81-8s5c\n","source":{"component":"workspace-scheduler"},"firstTimestamp":"2021-07-21T16:02:45Z","lastTimestamp":"2021-07-21T16:02:45Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9cd60f7517f","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9cd60f7517f","uid":"4aadb7e6-0974-4245-bacf-733a3de21487","resourceVersion":"14681307","creationTimestamp":"2021-07-21T16:02:46Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:02:46Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Pulling","message":"Pulling image \"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b\"","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:02:46Z","lastTimestamp":"2021-07-21T16:02:46Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d0efea9977","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d0efea9977","uid":"1914f2c6-0da1-4efc-bcd4-561c33c44f87","resourceVersion":"14681308","creationTimestamp":"2021-07-21T16:03:01Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:01Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Pulled","message":"Successfully pulled image \"reg.cw-imgbuilder-mk3-rebase.staging.gitpod-dev.com:30815/remote/0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b\" in 15.283188815s","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:01Z","lastTimestamp":"2021-07-21T16:03:01Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d162cf7143","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d162cf7143","uid":"2abb038a-e90b-44f1-85fd-5b4d61a8e307","resourceVersion":"14681309","creationTimestamp":"2021-07-21T16:03:03Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:03Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Created","message":"Created container workspace","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:03Z","lastTimestamp":"2021-07-21T16:03:03Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""},{"metadata":{"name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d17488b910","namespace":"staging-cw-imgbuilder-mk3-rebase","selfLink":"/api/v1/namespaces/staging-cw-imgbuilder-mk3-rebase/events/imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b.1693d9d17488b910","uid":"0f2b6737-f1c8-4956-b834-5cd51f342d41","resourceVersion":"14681310","creationTimestamp":"2021-07-21T16:03:04Z","managedFields":[{"manager":"kubelet","operation":"Update","apiVersion":"v1","time":"2021-07-21T16:03:04Z","fieldsType":"FieldsV1","fieldsV1":{"f:count":{},"f:firstTimestamp":{},"f:involvedObject":{"f:apiVersion":{},"f:fieldPath":{},"f:kind":{},"f:name":{},"f:namespace":{},"f:resourceVersion":{},"f:uid":{}},"f:lastTimestamp":{},"f:message":{},"f:reason":{},"f:source":{"f:component":{},"f:host":{}},"f:type":{}}}]},"involvedObject":{"kind":"Pod","namespace":"staging-cw-imgbuilder-mk3-rebase","name":"imagebuild-0dd5700a790e7ca2-95291c91f6e61c2e-e06ba50b","uid":"a87d12cb-d5ef-4dad-a1fa-44284e994f07","apiVersion":"v1","resourceVersion":"237704853","fieldPath":"spec.containers{workspace}"},"reason":"Started","message":"Started container workspace","source":{"component":"kubelet","host":"gke-dev-workload-1-49d27f81-8s5c"},"firstTimestamp":"2021-07-21T16:03:04Z","lastTimestamp":"2021-07-21T16:03:04Z","count":1,"type":"Normal","eventTime":null,"reportingComponent":"","reportingInstance":""}]} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b0c9a543c455dd..effc1180b1ac21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4732,7 +4732,7 @@ "@types/history" "*" "@types/react" "*" -"@types/react@*", "@types/react@^17.0.0": +"@types/react@*", "@types/react@17.0.0", "@types/react@^17.0.0": version "17.0.0" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.0.tgz#5af3eb7fad2807092f0046a1302b7823e27919b8" integrity sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw== @@ -14934,7 +14934,7 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.12.1, nan@^2.13.2, nan@^2.9.2: +nan@2.14.1, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.9.2: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== @@ -15499,6 +15499,13 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +oniguruma@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.1.tgz#51775834f7819b6e31aa878706aa7f65ad16b07f" + integrity sha512-WPS/e1uzhswPtJSe+Zls/kAj27+lEqZjCmRSjnYk/Z4L2Mu+lJC2JWtkZhPJe4kZeTQfz7ClcLyXlI4J68MG2w== + dependencies: + nan "^2.14.0" + open@^7.0.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" @@ -17656,7 +17663,7 @@ react-dev-utils@^11.0.3: strip-ansi "6.0.0" text-table "0.2.0" -react-dom@^17.0.1: +react-dom@17.0.1, react-dom@^17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6" integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug== @@ -17785,7 +17792,7 @@ react-scripts@^4.0.3: optionalDependencies: fsevents "^2.1.3" -react@^17.0.1: +react@17.0.1, react@^17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w== @@ -21046,11 +21053,24 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== -vscode-jsonrpc@^5.0.0: +vscode-jsonrpc@^5.0.0, vscode-jsonrpc@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794" integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A== +vscode-languageserver-protocol@3.15.3: + version "3.15.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb" + integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw== + dependencies: + vscode-jsonrpc "^5.0.1" + vscode-languageserver-types "3.15.1" + +vscode-languageserver-types@3.15.1: + version "3.15.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de" + integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ== + vscode-uri@^1.0.1: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59"