Skip to content

Commit d72cf46

Browse files
committed
driver(external): revamp grpchijack and GuestAgentConn()
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent a9cb37e commit d72cf46

File tree

11 files changed

+185
-148
lines changed

11 files changed

+185
-148
lines changed

cmd/limactl/main_darwin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
package main
77

88
// Import vz driver to register it in the registry on darwin.
9-
import _ "github.com/lima-vm/lima/pkg/driver/vz"
9+
// import _ "github.com/lima-vm/lima/pkg/driver/vz"

pkg/driver/external/client/client.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ import (
88
"io"
99
"math"
1010
"net"
11-
"time"
1211

1312
pb "github.com/lima-vm/lima/pkg/driver/external"
1413
"github.com/sirupsen/logrus"
1514
"google.golang.org/grpc"
1615
"google.golang.org/grpc/credentials/insecure"
17-
"google.golang.org/grpc/keepalive"
1816
)
1917

2018
type DriverClient struct {
@@ -36,18 +34,15 @@ func NewDriverClient(stdin io.WriteCloser, stdout io.ReadCloser, logger *logrus.
3634
return pipeConn, nil
3735
}),
3836
grpc.WithTransportCredentials(insecure.NewCredentials()),
39-
grpc.WithKeepaliveParams(keepalive.ClientParameters{
40-
Time: 10 * time.Second,
41-
Timeout: 20 * time.Second,
42-
PermitWithoutStream: true,
43-
}),
4437
}
4538

4639
// conn, err := grpc.NewClient("pipe", opts...)
4740
// if err != nil {
4841
// logger.Errorf("failed to create gRPC driver client connection: %v", err)
4942
// return nil, err
5043
// }
44+
// -> ERRO[2025-06-04T21:32:54+05:30] Failed to set config: rpc error: code =
45+
// Unavailable desc = name resolver error: produced zero addresses
5146

5247
conn, err := grpc.Dial("pipe", opts...)
5348
if err != nil {
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package grpchijack
5+
6+
import (
7+
"errors"
8+
"fmt"
9+
"io"
10+
"net"
11+
"sync"
12+
"time"
13+
14+
pb "github.com/lima-vm/lima/pkg/driver/external"
15+
"google.golang.org/grpc"
16+
)
17+
18+
type streamConn struct {
19+
stream pb.Driver_GuestAgentConnClient
20+
readBuf []byte
21+
lastBuf []byte
22+
readMu sync.Mutex
23+
writeMu sync.Mutex
24+
closeCh chan struct{}
25+
closedOnce sync.Once
26+
closed bool
27+
}
28+
29+
func StreamToConn(stream pb.Driver_GuestAgentConnClient) *streamConn {
30+
return &streamConn{
31+
stream: stream,
32+
closeCh: make(chan struct{}),
33+
}
34+
}
35+
36+
func (c *streamConn) Read(b []byte) (int, error) {
37+
c.readMu.Lock()
38+
defer c.readMu.Unlock()
39+
40+
if c.closed {
41+
return 0, io.EOF
42+
}
43+
44+
if c.lastBuf != nil {
45+
n := copy(b, c.lastBuf)
46+
c.lastBuf = c.lastBuf[n:]
47+
if len(c.lastBuf) == 0 {
48+
c.lastBuf = nil
49+
}
50+
return n, nil
51+
}
52+
53+
msg := new(pb.BytesMessage)
54+
msg, err := c.stream.Recv()
55+
if err != nil {
56+
c.closed = true
57+
if err == io.EOF {
58+
return 0, io.EOF
59+
}
60+
return 0, fmt.Errorf("stream receive error: %w", err)
61+
}
62+
63+
n := copy(b, msg.Data)
64+
if n < len(msg.Data) {
65+
c.readBuf = make([]byte, len(msg.Data)-n)
66+
copy(c.readBuf, msg.Data[n:])
67+
}
68+
69+
return n, nil
70+
}
71+
72+
func (c *streamConn) Write(b []byte) (int, error) {
73+
c.writeMu.Lock()
74+
defer c.writeMu.Unlock()
75+
76+
if c.closed {
77+
return 0, errors.New("connection closed")
78+
}
79+
80+
err := c.stream.Send(&pb.BytesMessage{Data: b})
81+
if err != nil {
82+
c.closed = true
83+
return 0, fmt.Errorf("stream send error: %w", err)
84+
}
85+
86+
return len(b), nil
87+
}
88+
89+
func (c *streamConn) Close() error {
90+
c.closedOnce.Do(func() {
91+
defer func() {
92+
close(c.closeCh)
93+
}()
94+
95+
if cs, ok := c.stream.(grpc.ClientStream); ok {
96+
c.writeMu.Lock()
97+
err := cs.CloseSend()
98+
c.writeMu.Unlock()
99+
if err != nil {
100+
return
101+
}
102+
}
103+
104+
c.readMu.Lock()
105+
for {
106+
m := new(pb.BytesMessage)
107+
m.Data = c.readBuf
108+
err := c.stream.RecvMsg(m)
109+
if err != nil {
110+
if !errors.Is(err, io.EOF) {
111+
c.readMu.Unlock()
112+
return
113+
}
114+
err = nil
115+
break
116+
}
117+
c.readBuf = m.Data[:cap(m.Data)]
118+
c.lastBuf = append(c.lastBuf, c.readBuf...)
119+
}
120+
c.readMu.Unlock()
121+
})
122+
return nil
123+
}
124+
125+
func (c *streamConn) LocalAddr() net.Addr { return &grpcAddr{} }
126+
func (c *streamConn) RemoteAddr() net.Addr { return &grpcAddr{} }
127+
128+
func (c *streamConn) SetDeadline(t time.Time) error { return nil }
129+
func (c *streamConn) SetReadDeadline(t time.Time) error { return nil }
130+
func (c *streamConn) SetWriteDeadline(t time.Time) error { return nil }
131+
132+
type grpcAddr struct{}
133+
134+
func (grpcAddr) Network() string { return "grpc" }
135+
func (grpcAddr) String() string { return "grpc-stream" }

pkg/driver/external/client/methods.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"github.com/lima-vm/lima/pkg/driver"
1616
pb "github.com/lima-vm/lima/pkg/driver/external"
17+
"github.com/lima-vm/lima/pkg/driver/external/client/grpchijack"
1718
"github.com/lima-vm/lima/pkg/store"
1819
)
1920

@@ -259,7 +260,7 @@ func (d *DriverClient) GuestAgentConn(ctx context.Context) (net.Conn, error) {
259260
return nil, err
260261
}
261262

262-
return streamToConn(connStream), nil
263+
return grpchijack.StreamToConn(connStream), nil
263264
}
264265

265266
func (d *DriverClient) GetInfo() driver.Info {

pkg/driver/external/client/pipe.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import (
1212
type PipeConn struct {
1313
Reader io.Reader
1414
Writer io.Writer
15+
Closer io.Closer
1516
}
1617

17-
func newPipeConn(writer io.WriteCloser, reader io.ReadCloser) *PipeConn {
18+
func newPipeConn(writer io.WriteCloser, reader io.ReadCloser) net.Conn {
1819
return &PipeConn{
1920
Reader: reader,
2021
Writer: writer,
@@ -30,16 +31,7 @@ func (p *PipeConn) Write(b []byte) (n int, err error) {
3031
}
3132

3233
func (p *PipeConn) Close() error {
33-
var err error
34-
if closer, ok := p.Reader.(io.Closer); ok {
35-
err = closer.Close()
36-
}
37-
if closer, ok := p.Writer.(io.Closer); ok {
38-
if closeErr := closer.Close(); closeErr != nil && err == nil {
39-
err = closeErr
40-
}
41-
}
42-
return err
34+
return p.Closer.Close()
4335
}
4436

4537
func (p *PipeConn) LocalAddr() net.Addr {

pkg/driver/external/client/stream.go

Lines changed: 0 additions & 93 deletions
This file was deleted.

0 commit comments

Comments
 (0)