Skip to content

Commit 7f0119c

Browse files
committed
[ws-daemon] Add support for idmapped mounts
1 parent 7b6959d commit 7f0119c

File tree

7 files changed

+336
-204
lines changed

7 files changed

+336
-204
lines changed

components/workspacekit/cmd/rings.go

+26-39
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"runtime"
2323
"strconv"
2424
"strings"
25+
"sync"
2526
"syscall"
2627
"time"
2728

@@ -78,21 +79,7 @@ var ring0Cmd = &cobra.Command{
7879

7980
defer log.Info("ring0 stopped")
8081

81-
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
82-
defer cancel()
83-
84-
client, err := connectToInWorkspaceDaemonService(ctx)
85-
if err != nil {
86-
log.WithError(err).Error("cannot connect to daemon from ring0")
87-
return
88-
}
89-
90-
prep, err := client.PrepareForUserNS(ctx, &daemonapi.PrepareForUserNSRequest{})
91-
if err != nil {
92-
log.WithError(err).Fatal("cannot prepare for user namespaces")
93-
return
94-
}
95-
client.Close()
82+
var err error
9683

9784
defer func() {
9885
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -119,10 +106,6 @@ var ring0Cmd = &cobra.Command{
119106
cmd.Stdin = os.Stdin
120107
cmd.Stdout = os.Stdout
121108
cmd.Stderr = os.Stderr
122-
cmd.Env = append(os.Environ(),
123-
"WORKSPACEKIT_FSSHIFT="+prep.FsShift.String(),
124-
fmt.Sprintf("WORKSPACEKIT_NO_WORKSPACE_MOUNT=%v", prep.FullWorkspaceBackup || prep.PersistentVolumeClaim),
125-
)
126109

127110
if err := cmd.Start(); err != nil {
128111
log.WithError(err).Error("failed to start ring0")
@@ -210,7 +193,7 @@ var ring1Cmd = &cobra.Command{
210193

211194
defer log.Info("ring1 stopped")
212195

213-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
196+
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
214197
defer cancel()
215198

216199
mapping := []*daemonapi.WriteIDMappingRequest_Mapping{
@@ -258,11 +241,23 @@ var ring1Cmd = &cobra.Command{
258241
log.WithError(err).Fatal("cannot create tempdir")
259242
}
260243

261-
var fsshift api.FSShiftMethod
262-
if v, ok := api.FSShiftMethod_value[os.Getenv("WORKSPACEKIT_FSSHIFT")]; !ok {
263-
log.WithField("fsshift", os.Getenv("WORKSPACEKIT_FSSHIFT")).Fatal("unknown FS shift method")
264-
} else {
265-
fsshift = api.FSShiftMethod(v)
244+
client, err := connectToInWorkspaceDaemonService(ctx)
245+
if err != nil {
246+
log.WithError(err).Error("cannot connect to daemon from ring0")
247+
return
248+
}
249+
var closeOnce sync.Once
250+
closeClient := func() {
251+
closeOnce.Do(func() { client.Close() })
252+
}
253+
defer closeClient()
254+
255+
prep, err := client.PrepareForUserNS(ctx, &daemonapi.PrepareForUserNSRequest{
256+
UsernsPid: int64(os.Getpid()),
257+
})
258+
if err != nil {
259+
log.WithError(err).Fatal("cannot prepare for user namespaces")
260+
return
266261
}
267262

268263
type mnte struct {
@@ -273,8 +268,8 @@ var ring1Cmd = &cobra.Command{
273268
}
274269

275270
var mnts []mnte
276-
switch fsshift {
277-
case api.FSShiftMethod_FUSE:
271+
switch prep.FsShift {
272+
case api.FSShiftMethod_FUSE, api.FSShiftMethod_IDMAPPED:
278273
mnts = append(mnts,
279274
mnte{Target: "/", Source: "/.workspace/mark", Flags: unix.MS_BIND | unix.MS_REC},
280275
)
@@ -283,7 +278,7 @@ var ring1Cmd = &cobra.Command{
283278
mnte{Target: "/", Source: "/.workspace/mark", FSType: "shiftfs"},
284279
)
285280
default:
286-
log.WithField("fsshift", fsshift).Fatal("unknown FS shift method")
281+
log.WithField("fsshift", prep.FsShift).Fatal("unknown FS shift method")
287282
}
288283

289284
procMounts, err := ioutil.ReadFile("/proc/mounts")
@@ -320,7 +315,7 @@ var ring1Cmd = &cobra.Command{
320315
// FWB workspaces do not require mounting /workspace
321316
// if that is done, the backup will not contain any change in the directory
322317
// same applies to persistent volume claims, we cannot mount /workspace folder when PVC is used
323-
if os.Getenv("WORKSPACEKIT_NO_WORKSPACE_MOUNT") != "true" {
318+
if !prep.PersistentVolumeClaim && !prep.FullWorkspaceBackup {
324319
mnts = append(mnts,
325320
mnte{Target: "/workspace", Flags: unix.MS_BIND | unix.MS_REC},
326321
)
@@ -410,29 +405,21 @@ var ring1Cmd = &cobra.Command{
410405
log.WithError(err).Error("cannot create directory for mounting proc")
411406
return
412407
}
413-
414-
client, err := connectToInWorkspaceDaemonService(ctx)
415-
if err != nil {
416-
log.WithError(err).Error("cannot connect to daemon from ring1")
417-
return
418-
}
419408
_, err = client.MountProc(ctx, &daemonapi.MountProcRequest{
420409
Target: procLoc,
421410
Pid: int64(cmd.Process.Pid),
422411
})
423412
if err != nil {
424-
client.Close()
425413
log.WithError(err).Error("cannot mount proc")
426414
return
427415
}
428416

429417
_, err = client.EvacuateCGroup(ctx, &daemonapi.EvacuateCGroupRequest{})
430418
if err != nil {
431-
client.Close()
432419
log.WithError(err).Error("cannot evacuate cgroup")
433420
return
434421
}
435-
client.Close()
422+
defer closeClient()
436423

437424
// We have to wait for ring2 to come back to us and connect to the socket we've passed along.
438425
// There's a chance that ring2 crashes or misbehaves, so we don't want to wait forever, hence
@@ -496,7 +483,7 @@ var ring1Cmd = &cobra.Command{
496483
_, err = msgutil.MarshalToWriter(ring2Conn, ringSyncMsg{
497484
Stage: 1,
498485
Rootfs: ring2Root,
499-
FSShift: fsshift,
486+
FSShift: prep.FsShift,
500487
})
501488
if err != nil {
502489
log.WithError(err).Error("cannot send ring sync msg to ring2")

0 commit comments

Comments
 (0)