Skip to content

Commit 004b142

Browse files
committed
[content-service] add prestop hook to extract git status when workspace is using pvc
1 parent 6205d22 commit 004b142

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

components/content-service/pkg/layer/provider.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,15 +465,27 @@ func contentDescriptorToLayer(cdesc []byte) (*Layer, error) {
465465
)
466466
}
467467

468+
var prestophookScript = `#!/bin/bash
469+
cd ${GITPOD_REPO_ROOT}
470+
git config --global --add safe.directory ${GITPOD_REPO_ROOT}
471+
git status --porcelain=v2 --branch -uall > /.workspace/prestophookdata/git_status.txt
472+
git log --pretty='%h: %s' --branches --not --remotes > /.workspace/prestophookdata/git_log_1.txt
473+
git log --pretty=%H -n 1 > /.workspace/prestophookdata/git_log_2.txt
474+
`
475+
468476
// version of this function for persistent volume claim feature
469477
// we cannot use /workspace folder as when mounting /workspace folder through PVC
470478
// it will mask anything that was in container layer, hence we are using /.workspace instead here
471479
func contentDescriptorToLayerPVC(cdesc []byte) (*Layer, error) {
472-
return layerFromContent(
473-
fileInLayer{&tar.Header{Typeflag: tar.TypeDir, Name: "/.workspace", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755}, nil},
474-
fileInLayer{&tar.Header{Typeflag: tar.TypeDir, Name: "/.workspace/.gitpod", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755}, nil},
475-
fileInLayer{&tar.Header{Typeflag: tar.TypeReg, Name: "/.workspace/.gitpod/content.json", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755, Size: int64(len(cdesc))}, cdesc},
476-
)
480+
layers := []fileInLayer{
481+
{&tar.Header{Typeflag: tar.TypeDir, Name: "/.workspace", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755}, nil},
482+
{&tar.Header{Typeflag: tar.TypeDir, Name: "/.workspace/.gitpod", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755}, nil},
483+
{&tar.Header{Typeflag: tar.TypeReg, Name: "/.supervisor/prestophook.sh", Uid: 0, Gid: 0, Mode: 0775, Size: int64(len(prestophookScript))}, []byte(prestophookScript)},
484+
}
485+
if len(cdesc) > 0 {
486+
layers = append(layers, fileInLayer{&tar.Header{Typeflag: tar.TypeReg, Name: "/.workspace/.gitpod/content.json", Uid: initializer.GitpodUID, Gid: initializer.GitpodGID, Mode: 0755, Size: int64(len(cdesc))}, cdesc})
487+
}
488+
return layerFromContent(layers...)
477489
}
478490

479491
func workspaceReadyLayer(src csapi.WorkspaceInitSource) (*Layer, error) {

components/ws-daemon/pkg/content/service.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"math"
1313
"os"
14+
"os/exec"
1415
"path/filepath"
1516
"syscall"
1617
"time"
@@ -240,6 +241,22 @@ func (s *WorkspaceService) InitWorkspace(ctx context.Context, req *api.InitWorks
240241
}
241242
}
242243

244+
if req.PersistentVolumeClaim {
245+
// create a folder that is used to store data from running prestophook
246+
deamonDir := fmt.Sprintf("%s-daemon", req.Id)
247+
prestophookDir := filepath.Join(s.config.WorkingArea, deamonDir, "prestophookdata")
248+
_, err = exec.CommandContext(ctx, "mkdir", "-p", prestophookDir).CombinedOutput()
249+
if err != nil {
250+
log.WithError(err).WithField("workspaceId", req.Id).Error("cannot create prestophookdata folder")
251+
return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot create prestophookdata: %v", err))
252+
}
253+
_, err = exec.CommandContext(ctx, "chown", "-R", fmt.Sprintf("%d:%d", wsinit.GitpodUID, wsinit.GitpodGID), prestophookDir).CombinedOutput()
254+
if err != nil {
255+
log.WithError(err).WithField("workspaceId", req.Id).Error("cannot chown prestophookdata folder")
256+
return nil, status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot chown prestophookdata: %v", err))
257+
}
258+
}
259+
243260
// Tell the world we're done
244261
err = workspace.MarkInitDone(ctx)
245262
if err != nil {

components/ws-manager/pkg/manager/create.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,15 @@ func (m *Manager) createDefiniteWorkspacePod(startContext *startWorkspaceContext
543543
// not needed, since it is using dedicated disk
544544
pod.Spec.Containers[0].VolumeMounts[0].MountPropagation = nil
545545

546+
// add prestop hook to capture git status
547+
pod.Spec.Containers[0].Lifecycle = &corev1.Lifecycle{
548+
PreStop: &corev1.LifecycleHandler{
549+
Exec: &corev1.ExecAction{
550+
Command: []string{"/bin/sh", "-c", "/.supervisor/workspacekit lift /.supervisor/prestophook.sh"},
551+
},
552+
},
553+
}
554+
546555
// pavel: 133332 is the Gitpod UID (33333) shifted by 99999. The shift happens inside the workspace container due to the user namespace use.
547556
// We set this magical ID to make sure that gitpod user inside the workspace can write into /workspace folder mounted by PVC
548557
gitpodGUID := int64(133332)

0 commit comments

Comments
 (0)