Skip to content

Commit 88abad6

Browse files
committed
Add rdd-guest socket bridge for Windows Docker socket forwarding
Build rdd-guest from rancher-desktop-daemon's cmd/rdd-guest and include it in the VM image. Add a systemd unit that starts it on WSL2 instances as part of rancher-desktop.target. Signed-off-by: Nino Kodabande <nkodabande@suse.com>
1 parent 5a997bc commit 88abad6

7 files changed

Lines changed: 138 additions & 0 deletions

File tree

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ WORKDIR /rd/rd-init
1717
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
1818
go build -ldflags '-s -w' -o /go/bin/rd-init .
1919

20+
WORKDIR /rd/rdd-guest
21+
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod \
22+
CGO_ENABLED=0 go build -ldflags '-s -w' -o /go/bin/rdd-guest .
23+
2024
FROM registry.opensuse.org/opensuse/bci/kiwi:10 AS builder
2125
ARG type=qcow2.xz
2226
ARG NERDCTL_VERSION

config.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ if [[ ${kiwi_profiles:-} =~ wsl ]]; then
117117
systemctl enable network-setup
118118
systemctl enable rancher-desktop-guest-agent.service
119119
systemctl enable wsl-proxy.service
120+
systemctl enable rdd-guest.service
120121
# Do not manage /tmp; that is managed by WSL.
121122
mkdir -p /usr/local/lib/tmpfiles.d
122123
touch /usr/local/lib/tmpfiles.d/fs-tmp.conf
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[Unit]
2+
Description=Rancher Desktop Guest Socket Bridge
3+
Documentation=https://github.com/rancher-sandbox/rancher-desktop-daemon
4+
ConditionVirtualization=wsl
5+
6+
[Service]
7+
ExecStart=/usr/local/bin/rdd-guest
8+
Restart=on-failure
9+
RestartSec=5s
10+
StandardOutput=journal
11+
StandardError=journal
12+
13+
[Install]
14+
WantedBy=rancher-desktop.target

src/rdd-guest/go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module github.com/rancher-sandbox/rancher-desktop-opensuse/src/rdd-guest
2+
3+
go 1.23.0
4+
5+
require github.com/mdlayher/vsock v1.2.1
6+
7+
require (
8+
github.com/mdlayher/socket v0.5.1 // indirect
9+
golang.org/x/net v0.26.0 // indirect
10+
golang.org/x/sync v0.7.0 // indirect
11+
golang.org/x/sys v0.21.0 // indirect
12+
)

src/rdd-guest/go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
2+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3+
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
4+
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
5+
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
6+
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
7+
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
8+
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
9+
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
10+
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
11+
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
12+
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

src/rdd-guest/main.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Package main is the rdd-guest agent that runs inside the Lima/WSL2 VM.
2+
// It listens on a vsock port and forwards connections to the Docker socket,
3+
// enabling the Windows host to reach /var/run/docker.sock via Hyper-V vsock.
4+
//
5+
package main
6+
7+
import (
8+
"context"
9+
"errors"
10+
"io"
11+
"log"
12+
"net"
13+
"os"
14+
"os/signal"
15+
"syscall"
16+
17+
"github.com/mdlayher/vsock"
18+
)
19+
20+
const (
21+
vsockPort = 6660
22+
dockerSockPath = "/var/run/docker.sock"
23+
)
24+
25+
func main() {
26+
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
27+
defer stop()
28+
29+
l, err := vsock.Listen(vsockPort, nil)
30+
if err != nil {
31+
log.Fatalf("vsock listen: %v", err)
32+
}
33+
defer l.Close()
34+
35+
log.Printf("rdd-guest: listening on vsock port %d", vsockPort)
36+
37+
go func() {
38+
<-ctx.Done()
39+
l.Close()
40+
}()
41+
42+
for {
43+
conn, err := l.Accept()
44+
if err != nil {
45+
if ctx.Err() != nil {
46+
return
47+
}
48+
log.Printf("rdd-guest: accept: %v", err)
49+
continue
50+
}
51+
go handleConn(conn)
52+
}
53+
}
54+
55+
// TODO: once rancher-desktop-daemon is public, replace the inlined halfCloser,
56+
// pipe(), and handleConn() here with a direct import of pkg/socketbridge, which
57+
// contains the implementations (HalfCloser interface, Pipe function).
58+
// halfCloser is a net.Conn that can independently close the write side.
59+
type halfCloser interface {
60+
net.Conn
61+
CloseWrite() error
62+
}
63+
64+
// handleConn forwards bytes between the vsock connection and the Docker socket.
65+
func handleConn(vsockConn net.Conn) {
66+
defer vsockConn.Close()
67+
68+
dockerConn, err := (&net.Dialer{}).DialContext(context.Background(), "unix", dockerSockPath)
69+
if err != nil {
70+
log.Printf("rdd-guest: dial docker: %v", err)
71+
return
72+
}
73+
defer dockerConn.Close()
74+
75+
pipe(vsockConn.(halfCloser), dockerConn.(halfCloser))
76+
}
77+
78+
// pipe bidirectionally proxies between a and b until both directions are done.
79+
func pipe(a, b halfCloser) {
80+
done := make(chan error, 2)
81+
82+
forward := func(dst, src halfCloser) {
83+
_, err := io.Copy(dst, src)
84+
if err != nil && !errors.Is(err, io.EOF) {
85+
log.Printf("rdd-guest: copy: %v", err)
86+
}
87+
_ = dst.CloseWrite()
88+
done <- err
89+
}
90+
91+
go forward(a, b)
92+
go forward(b, a)
93+
<-done
94+
<-done
95+
}

src/rdd-guest/rdd-guest

3.51 MB
Binary file not shown.

0 commit comments

Comments
 (0)