Skip to content

Commit 3bf682b

Browse files
authored
fix(envd): make package build and tests pass on macOS (#2605)
Gate Linux-only syscalls (cgroup2, ClockSettime, SysProcAttr cgroup FD fields) behind build tags and provide non-Linux stubs so envd compiles and tests run on darwin. Skip Linux-specific filesystem and /proc tests on other platforms.
1 parent fc58318 commit 3bf682b

14 files changed

Lines changed: 132 additions & 9 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build linux
2+
3+
package api
4+
5+
import (
6+
"time"
7+
8+
"golang.org/x/sys/unix"
9+
)
10+
11+
func setSystemTime(t time.Time) error {
12+
ts := unix.NsecToTimespec(t.UnixNano())
13+
14+
return unix.ClockSettime(unix.CLOCK_REALTIME, &ts)
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build !linux
2+
3+
package api
4+
5+
import (
6+
"errors"
7+
"time"
8+
)
9+
10+
func setSystemTime(_ time.Time) error {
11+
return errors.New("setting system time is only supported on Linux")
12+
}

packages/envd/internal/api/init.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/rs/zerolog"
1717
"github.com/txn2/txeh"
1818
"golang.org/x/sync/errgroup"
19-
"golang.org/x/sys/unix"
2019

2120
"github.com/e2b-dev/infra/packages/envd/internal/host"
2221
"github.com/e2b-dev/infra/packages/envd/internal/logs"
@@ -175,9 +174,7 @@ func (a *API) SetData(ctx context.Context, logger zerolog.Logger, data PostInitJ
175174
// Check if current time differs significantly from the received timestamp
176175
if shouldSetSystemTime(time.Now(), *data.Timestamp) {
177176
logger.Debug().Msgf("Setting sandbox start time to: %v", *data.Timestamp)
178-
ts := unix.NsecToTimespec(data.Timestamp.UnixNano())
179-
err := unix.ClockSettime(unix.CLOCK_REALTIME, &ts)
180-
if err != nil {
177+
if err := setSystemTime(*data.Timestamp); err != nil {
181178
logger.Error().Msgf("Failed to set system time: %v", err)
182179
}
183180
} else {

packages/envd/internal/api/upload_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"os/exec"
1111
"path/filepath"
12+
"runtime"
1213
"testing"
1314

1415
"github.com/rs/zerolog"
@@ -54,6 +55,10 @@ func TestProcessFile(t *testing.T) {
5455

5556
t.Run("fail to create file", func(t *testing.T) {
5657
t.Parallel()
58+
// /proc as a virtual filesystem with specific error semantics is Linux-only.
59+
if runtime.GOOS != "linux" {
60+
t.Skip("relies on Linux /proc virtual filesystem semantics")
61+
}
5762
httpStatus, err := processFile(&emptyReq, "/proc/invalid-filename", emptyPart, uid, gid, emptyLogger)
5863
require.Error(t, err)
5964
assert.Equal(t, http.StatusInternalServerError, httpStatus)

packages/envd/internal/port/forward.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,9 @@ func (f *Forwarder) startPortForwarding(ctx context.Context, p *PortToForward) {
144144
cgroupFD, ok := f.cgroupManager.GetFileDescriptor(cgroups.ProcessTypeSocat)
145145

146146
cmd.SysProcAttr = &syscall.SysProcAttr{
147-
Setpgid: true,
148-
CgroupFD: cgroupFD,
149-
UseCgroupFD: ok,
147+
Setpgid: true,
150148
}
149+
applyCgroupFD(cmd.SysProcAttr, cgroupFD, ok)
151150

152151
f.logger.Debug().
153152
Str("socatCmd", cmd.String()).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//go:build linux
2+
3+
package port
4+
5+
import "syscall"
6+
7+
// applyCgroupFD sets cgroup-related fields on Linux SysProcAttr.
8+
func applyCgroupFD(attr *syscall.SysProcAttr, fd int, use bool) {
9+
attr.CgroupFD = fd
10+
attr.UseCgroupFD = use
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build !linux
2+
3+
package port
4+
5+
import "syscall"
6+
7+
// applyCgroupFD is a no-op on non-Linux platforms; cgroup v2 is Linux-only.
8+
func applyCgroupFD(_ *syscall.SysProcAttr, _ int, _ bool) {}

packages/envd/internal/services/cgroups/cgroup2.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build linux
2+
13
package cgroups
24

35
import (
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//go:build !linux
2+
3+
package cgroups
4+
5+
// Cgroup2Manager is a non-functional stub on non-Linux platforms.
6+
// cgroups v2 is a Linux-only kernel feature.
7+
type Cgroup2Manager struct{}
8+
9+
var _ Manager = (*Cgroup2Manager)(nil)
10+
11+
type Cgroup2Config struct {
12+
Path string
13+
Properties map[string]string
14+
}
15+
16+
type cgroup2Config struct {
17+
rootPath string
18+
processTypes map[ProcessType]Cgroup2Config
19+
}
20+
21+
type Cgroup2ManagerOption func(*cgroup2Config)
22+
23+
func WithCgroup2RootSysFSPath(path string) Cgroup2ManagerOption {
24+
return func(config *cgroup2Config) {
25+
config.rootPath = path
26+
}
27+
}
28+
29+
func WithCgroup2ProcessType(processType ProcessType, path string, properties map[string]string) Cgroup2ManagerOption {
30+
return func(config *cgroup2Config) {
31+
if config.processTypes == nil {
32+
config.processTypes = make(map[ProcessType]Cgroup2Config)
33+
}
34+
config.processTypes[processType] = Cgroup2Config{Path: path, Properties: properties}
35+
}
36+
}
37+
38+
func NewCgroup2Manager(_ ...Cgroup2ManagerOption) (*Cgroup2Manager, error) {
39+
return &Cgroup2Manager{}, nil
40+
}
41+
42+
func (c Cgroup2Manager) GetFileDescriptor(ProcessType) (int, bool) {
43+
return 0, false
44+
}
45+
46+
func (c Cgroup2Manager) Close() error {
47+
return nil
48+
}

packages/envd/internal/services/cgroups/cgroup2_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build linux
2+
13
package cgroups
24

35
import (

0 commit comments

Comments
 (0)