Skip to content

Commit 5bdf477

Browse files
akosyakovroboquat
authored andcommitted
Revert "ws-daemon: Use a pair of veths instead of slirp4netns"
This reverts commit 4fef102.
1 parent 95f83d5 commit 5bdf477

File tree

9 files changed

+220
-85
lines changed

9 files changed

+220
-85
lines changed

components/ee/agent-smith/pkg/detector/proc_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,15 @@ func TestFindWorkspaces(t *testing.T) {
8888
Env: []string{"GITPOD_WORKSPACE_ID=foobar", "GITPOD_INSTANCE_ID=baz"},
8989
}
9090
res[3] = memoryProcEntry{P: &process{PID: 3, Parent: res[2].P, Cmdline: []string{"supervisor", "init"}}}
91+
res[4] = memoryProcEntry{P: &process{PID: 4, Parent: res[2].P, Cmdline: []string{"slirp4netns"}}}
9192
res[1].P.Children = []*process{res[2].P}
92-
res[2].P.Children = []*process{res[3].P}
93+
res[2].P.Children = []*process{res[3].P, res[4].P}
9394
return res
9495
})(),
9596
Expectation: []WorkspaceAndDepth{
9697
{PID: 2, D: 1, K: ProcessSandbox, C: "/proc/self/exe", W: ws},
9798
{PID: 3, D: 2, K: ProcessSupervisor, C: "supervisor", W: ws},
99+
{PID: 4, D: 2, K: ProcessUserWorkload, C: "slirp4netns", W: ws},
98100
},
99101
},
100102
{

components/supervisor/pkg/ports/ports.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,28 @@ func init() {
3333
}
3434

3535
// NewManager creates a new port manager
36-
func NewManager(exposed ExposedPortsInterface, served ServedPortsObserver, config ConfigInterace, tunneled TunneledPortsInterface, internalPorts ...uint32) *Manager {
36+
func NewManager(exposed ExposedPortsInterface, served ServedPortsObserver, config ConfigInterace, tunneled TunneledPortsInterface, slirp SlirpClient, internalPorts ...uint32) *Manager {
3737
state := make(map[uint32]*managedPort)
3838
internal := make(map[uint32]struct{})
3939
for _, p := range internalPorts {
4040
internal[p] = struct{}{}
4141
}
4242

43+
if slirp != nil {
44+
for _, p := range internalPorts {
45+
err := slirp.Expose(p)
46+
if err != nil {
47+
log.WithError(err).WithField("port", p).Error("cannot expose port")
48+
}
49+
}
50+
}
51+
4352
return &Manager{
44-
E: exposed,
45-
S: served,
46-
C: config,
47-
T: tunneled,
53+
E: exposed,
54+
S: served,
55+
C: config,
56+
T: tunneled,
57+
Slirp: slirp,
4858

4959
forceUpdates: make(chan struct{}, 1),
5060

@@ -75,10 +85,11 @@ type autoExposure struct {
7585
// Manager brings together served and exposed ports. It keeps track of which port is exposed, which one is served,
7686
// auto-exposes ports and proxies ports served on localhost only.
7787
type Manager struct {
78-
E ExposedPortsInterface
79-
S ServedPortsObserver
80-
C ConfigInterace
81-
T TunneledPortsInterface
88+
E ExposedPortsInterface
89+
S ServedPortsObserver
90+
C ConfigInterace
91+
T TunneledPortsInterface
92+
Slirp SlirpClient
8293

8394
forceUpdates chan struct{}
8495

@@ -277,6 +288,7 @@ func (pm *Manager) updateState(ctx context.Context, exposed []ExposedPort, serve
277288
log.WithField("served", newServed).Debug("updating served ports")
278289
pm.served = newServed
279290
pm.updateProxies()
291+
pm.updateSlirp()
280292
pm.autoTunnel(ctx)
281293
}
282294
}
@@ -525,6 +537,19 @@ func (pm *Manager) autoTunnel(ctx context.Context) {
525537
}
526538
}
527539

540+
func (pm *Manager) updateSlirp() {
541+
if pm.Slirp == nil {
542+
return
543+
}
544+
545+
for _, served := range pm.served {
546+
err := pm.Slirp.Expose(served.Port)
547+
if err != nil {
548+
log.WithError(err).Debug("cannot expose port for slirp")
549+
}
550+
}
551+
}
552+
528553
func (pm *Manager) updateProxies() {
529554
servedPortMap := map[uint32]bool{}
530555
for _, s := range pm.served {

components/supervisor/pkg/ports/ports_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ func TestPortsUpdateState(t *testing.T) {
517517
Error: make(chan error, 1),
518518
}
519519

520-
pm = NewManager(exposed, served, config, tunneled, test.InternalPorts...)
520+
pm = NewManager(exposed, served, config, tunneled, nil, test.InternalPorts...)
521521
updts [][]*api.PortsStatus
522522
)
523523
pm.proxyStarter = func(port uint32) (io.Closer, error) {
@@ -683,7 +683,7 @@ func TestPortsConcurrentSubscribe(t *testing.T) {
683683
Changes: make(chan []PortTunnelState),
684684
Error: make(chan error, 1),
685685
}
686-
pm = NewManager(exposed, served, config, tunneled)
686+
pm = NewManager(exposed, served, config, tunneled, nil)
687687
)
688688
pm.proxyStarter = func(local uint32) (io.Closer, error) {
689689
return io.NopCloser(nil), nil
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package ports
6+
7+
import (
8+
"encoding/json"
9+
"io"
10+
"net"
11+
12+
"golang.org/x/xerrors"
13+
)
14+
15+
type SlirpClient interface {
16+
Expose(port uint32) error
17+
}
18+
19+
type request struct {
20+
Execute string `json:"execute"`
21+
Arguments interface{} `json:"arguments"`
22+
}
23+
24+
type reply struct {
25+
Return map[string]interface{} `json:"return,omitempty"`
26+
Error map[string]interface{} `json:"error,omitempty"`
27+
}
28+
29+
type Slirp4Netns string
30+
31+
func (s Slirp4Netns) Expose(port uint32) error {
32+
type addHostFwdArguments struct {
33+
Proto string `json:"proto"`
34+
HostAddr string `json:"host_addr"`
35+
HostPort int `json:"host_port"`
36+
GuestAddr string `json:"guest_addr"`
37+
GuestPort int `json:"guest_port"`
38+
}
39+
40+
_, err := s.sendRequest(request{
41+
Execute: "add_hostfwd",
42+
Arguments: addHostFwdArguments{
43+
GuestAddr: "10.0.2.100",
44+
GuestPort: int(port),
45+
HostAddr: "0.0.0.0",
46+
HostPort: int(port),
47+
Proto: "tcp",
48+
},
49+
})
50+
if err != nil {
51+
return err
52+
}
53+
54+
return nil
55+
}
56+
57+
func (s Slirp4Netns) sendRequest(req request) (resp map[string]interface{}, err error) {
58+
conn, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: string(s), Net: "unix"})
59+
if err != nil {
60+
return nil, err
61+
}
62+
defer conn.Close()
63+
64+
if err := json.NewEncoder(conn).Encode(req); err != nil {
65+
return nil, err
66+
}
67+
if err := conn.CloseWrite(); err != nil {
68+
return nil, err
69+
}
70+
b, err := io.ReadAll(conn)
71+
if err != nil {
72+
return nil, err
73+
}
74+
var rep reply
75+
if err := json.Unmarshal(b, &rep); err != nil {
76+
return nil, err
77+
}
78+
79+
if len(rep.Error) > 0 {
80+
return nil, xerrors.Errorf("error reply: %+v", rep.Error)
81+
}
82+
return rep.Return, nil
83+
}

components/supervisor/pkg/supervisor/supervisor.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ func Run(options ...RunOption) {
193193
log.WithError(err).Warn("cannot tunnel internal ports")
194194
}
195195

196+
var slirp ports.SlirpClient
197+
if _, err := os.Stat("/.supervisor/slirp4netns.sock/slirp4netns.sock"); err == nil {
198+
slirp = ports.Slirp4Netns("/.supervisor/slirp4netns.sock/slirp4netns.sock")
199+
}
200+
196201
ctx, cancel := context.WithCancel(context.Background())
197202

198203
internalPorts := []uint32{uint32(cfg.IDEPort), uint32(cfg.APIEndpointPort), uint32(cfg.SSHPort)}
@@ -214,6 +219,7 @@ func Run(options ...RunOption) {
214219
},
215220
ports.NewConfigService(cfg.WorkspaceID, gitpodConfigService, gitpodService),
216221
tunneledPortsService,
222+
slirp,
217223
internalPorts...,
218224
)
219225
termMux = terminal.NewMux()

components/workspacekit/cmd/rings.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ var ring1Cmd = &cobra.Command{
249249
fsshift = api.FSShiftMethod(v)
250250
}
251251

252+
var (
253+
slirp4netnsSocket string
254+
)
255+
252256
type mnte struct {
253257
Target string
254258
Source string
@@ -309,6 +313,15 @@ var ring1Cmd = &cobra.Command{
309313
)
310314
}
311315

316+
f, err := ioutil.TempDir("", "wskit-slirp4netns")
317+
if err != nil {
318+
log.WithError(err).Error("cannot create slirp4netns socket tempdir")
319+
return
320+
}
321+
322+
slirp4netnsSocket = filepath.Join(f, "slirp4netns.sock")
323+
mnts = append(mnts, mnte{Target: "/.supervisor/slirp4netns.sock", Source: f, Flags: unix.MS_BIND | unix.MS_REC})
324+
312325
for _, m := range mnts {
313326
dst := filepath.Join(ring2Root, m.Target)
314327
_ = os.MkdirAll(dst, 0644)
@@ -462,6 +475,26 @@ var ring1Cmd = &cobra.Command{
462475
return
463476
}
464477

478+
slirpCmd := exec.Command(filepath.Join(filepath.Dir(ring2Opts.SupervisorPath), "slirp4netns"),
479+
"--configure",
480+
"--mtu=65520",
481+
"--disable-host-loopback",
482+
"--api-socket", slirp4netnsSocket,
483+
strconv.Itoa(cmd.Process.Pid),
484+
"tap0",
485+
)
486+
slirpCmd.SysProcAttr = &syscall.SysProcAttr{
487+
Pdeathsig: syscall.SIGKILL,
488+
}
489+
490+
err = slirpCmd.Start()
491+
if err != nil {
492+
log.WithError(err).Error("cannot start slirp4netns")
493+
return
494+
}
495+
//nolint:errcheck
496+
defer slirpCmd.Process.Kill()
497+
465498
client, err = connectToInWorkspaceDaemonService(ctx)
466499
if err != nil {
467500
log.WithError(err).Error("cannot connect to daemon")

components/workspacekit/leeway.Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
# Licensed under the GNU Affero General Public License (AGPL).
33
# See License-AGPL.txt in the project root for license information.
44

5+
FROM alpine:3.15 as download
6+
ENV SLIRP4NETNS_VERSION=v1.1.12
7+
WORKDIR /download
8+
RUN wget https://github.com/rootless-containers/slirp4netns/releases/download/${SLIRP4NETNS_VERSION}/slirp4netns-x86_64 -O slirp4netns && chmod 755 slirp4netns
9+
510
FROM scratch
611

712
COPY components-workspacekit--app/workspacekit \
813
components-workspacekit--fuse-overlayfs/fuse-overlayfs \
914
/.supervisor/
15+
COPY --from=download /download/slirp4netns /.supervisor/
1016

1117
ARG __GIT_COMMIT
1218
ARG VERSION

0 commit comments

Comments
 (0)