Skip to content

Commit 28ce50c

Browse files
committed
driver(external): implement the grpc client and server
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent 6c1a5cf commit 28ce50c

File tree

4 files changed

+474
-0
lines changed

4 files changed

+474
-0
lines changed

pkg/driver/external/client/client.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package client
5+
6+
import (
7+
"context"
8+
"io"
9+
"math"
10+
"net"
11+
"time"
12+
13+
pb "github.com/lima-vm/lima/pkg/driver/external"
14+
"github.com/sirupsen/logrus"
15+
"google.golang.org/grpc"
16+
"google.golang.org/grpc/credentials/insecure"
17+
"google.golang.org/grpc/keepalive"
18+
)
19+
20+
type DriverClient struct {
21+
Stdin io.WriteCloser
22+
Stdout io.ReadCloser
23+
Conn *grpc.ClientConn
24+
DriverSvc pb.DriverClient
25+
logger *logrus.Logger
26+
}
27+
28+
func NewDriverClient(stdin io.WriteCloser, stdout io.ReadCloser, logger *logrus.Logger) (*DriverClient, error) {
29+
pipeConn := &PipeConn{
30+
Reader: stdout,
31+
Writer: stdin,
32+
}
33+
34+
opts := []grpc.DialOption{
35+
grpc.WithDefaultCallOptions(
36+
grpc.MaxCallRecvMsgSize(math.MaxInt64),
37+
grpc.MaxCallSendMsgSize(math.MaxInt64),
38+
),
39+
grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) {
40+
return pipeConn, nil
41+
}),
42+
grpc.WithTransportCredentials(insecure.NewCredentials()),
43+
grpc.WithKeepaliveParams(keepalive.ClientParameters{
44+
Time: 10 * time.Second,
45+
Timeout: 20 * time.Second,
46+
PermitWithoutStream: true,
47+
}),
48+
}
49+
50+
conn, err := grpc.NewClient("pipe://", opts...)
51+
if err != nil {
52+
logger.Errorf("failed to create gRPC driver client connection: %v", err)
53+
return nil, err
54+
}
55+
56+
driverSvc := pb.NewDriverClient(conn)
57+
58+
return &DriverClient{
59+
Stdin: stdin,
60+
Stdout: stdout,
61+
Conn: conn,
62+
DriverSvc: driverSvc,
63+
logger: logger,
64+
}, nil
65+
}
66+
67+
type PipeConn struct {
68+
Reader io.Reader
69+
Writer io.Writer
70+
}
71+
72+
func (p *PipeConn) Read(b []byte) (n int, err error) {
73+
return p.Reader.Read(b)
74+
}
75+
76+
func (p *PipeConn) Write(b []byte) (n int, err error) {
77+
return p.Writer.Write(b)
78+
}
79+
80+
func (p *PipeConn) Close() error {
81+
var err error
82+
if closer, ok := p.Reader.(io.Closer); ok {
83+
err = closer.Close()
84+
}
85+
if closer, ok := p.Writer.(io.Closer); ok {
86+
if closeErr := closer.Close(); closeErr != nil && err == nil {
87+
err = closeErr
88+
}
89+
}
90+
return err
91+
}
92+
93+
func (p *PipeConn) LocalAddr() net.Addr {
94+
return pipeAddr{}
95+
}
96+
97+
func (p *PipeConn) RemoteAddr() net.Addr {
98+
return pipeAddr{}
99+
}
100+
101+
func (p *PipeConn) SetDeadline(t time.Time) error {
102+
return nil
103+
}
104+
105+
func (p *PipeConn) SetReadDeadline(t time.Time) error {
106+
return nil
107+
}
108+
109+
func (p *PipeConn) SetWriteDeadline(t time.Time) error {
110+
return nil
111+
}
112+
113+
type pipeAddr struct{}
114+
115+
func (pipeAddr) Network() string { return "pipe" }
116+
func (pipeAddr) String() string { return "pipe" }

pkg/driver/external/server/methods.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package server
5+
6+
import (
7+
"context"
8+
9+
pb "github.com/lima-vm/lima/pkg/driver/external"
10+
"google.golang.org/protobuf/types/known/emptypb"
11+
)
12+
13+
// TODO: Add more 3 functions Start, SetConfig & GuestAgentConn
14+
15+
func (s *DriverServer) Name(ctx context.Context, empty *emptypb.Empty) (*pb.NameResponse, error) {
16+
s.logger.Debug("Received Name request")
17+
return &pb.NameResponse{Name: s.driver.Name()}, nil
18+
}
19+
20+
func (s *DriverServer) GetVirtioPort(ctx context.Context, empty *emptypb.Empty) (*pb.GetVirtioPortResponse, error) {
21+
s.logger.Debug("Received GetVirtioPort request")
22+
return &pb.GetVirtioPortResponse{
23+
Port: s.driver.GetVirtioPort(),
24+
}, nil
25+
}
26+
27+
func (s *DriverServer) GetVSockPort(ctx context.Context, empty *emptypb.Empty) (*pb.GetVSockPortResponse, error) {
28+
s.logger.Debug("Received GetVSockPort request")
29+
return &pb.GetVSockPortResponse{
30+
Port: int64(s.driver.GetVSockPort()),
31+
}, nil
32+
}
33+
34+
func (s *DriverServer) Validate(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
35+
s.logger.Debugf("Received Validate request")
36+
err := s.driver.Validate()
37+
if err != nil {
38+
s.logger.Errorf("Validation failed: %v", err)
39+
return empty, err
40+
}
41+
s.logger.Debug("Validation succeeded")
42+
return empty, nil
43+
}
44+
45+
func (s *DriverServer) Initialize(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
46+
s.logger.Debug("Received Initialize request")
47+
err := s.driver.Initialize(ctx)
48+
if err != nil {
49+
s.logger.Errorf("Initialization failed: %v", err)
50+
return empty, err
51+
}
52+
s.logger.Debug("Initialization succeeded")
53+
return empty, nil
54+
}
55+
56+
func (s *DriverServer) CreateDisk(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
57+
s.logger.Debug("Received CreateDisk request")
58+
err := s.driver.CreateDisk(ctx)
59+
if err != nil {
60+
s.logger.Errorf("CreateDisk failed: %v", err)
61+
return empty, err
62+
}
63+
s.logger.Debug("CreateDisk succeeded")
64+
return empty, nil
65+
}
66+
67+
func (s *DriverServer) Stop(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
68+
s.logger.Debug("Received Stop request")
69+
err := s.driver.Stop(ctx)
70+
if err != nil {
71+
s.logger.Errorf("Stop failed: %v", err)
72+
return empty, err
73+
}
74+
s.logger.Debug("Stop succeeded")
75+
return empty, nil
76+
}
77+
78+
func (s *DriverServer) CanRunGUI(ctx context.Context, empty *emptypb.Empty) (*pb.CanRunGUIResponse, error) {
79+
s.logger.Debug("Received CanRunGUI request")
80+
return &pb.CanRunGUIResponse{CanRun: s.driver.CanRunGUI()}, nil
81+
}
82+
83+
func (s *DriverServer) RunGUI(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
84+
s.logger.Debug("Received RunGUI request")
85+
err := s.driver.RunGUI()
86+
if err != nil {
87+
s.logger.Errorf("RunGUI failed: %v", err)
88+
return empty, err
89+
}
90+
s.logger.Debug("RunGUI succeeded")
91+
return empty, nil
92+
}
93+
94+
func (s *DriverServer) ChangeDisplayPassword(ctx context.Context, req *pb.ChangeDisplayPasswordRequest) (*emptypb.Empty, error) {
95+
s.logger.Debug("Received ChangeDisplayPassword request")
96+
err := s.driver.ChangeDisplayPassword(ctx, req.Password)
97+
if err != nil {
98+
s.logger.Errorf("ChangeDisplayPassword failed: %v", err)
99+
return &emptypb.Empty{}, err
100+
}
101+
s.logger.Debug("ChangeDisplayPassword succeeded")
102+
return &emptypb.Empty{}, nil
103+
}
104+
105+
func (s *DriverServer) GetDisplayConnection(ctx context.Context, empty *emptypb.Empty) (*pb.GetDisplayConnectionResponse, error) {
106+
s.logger.Debug("Received GetDisplayConnection request")
107+
conn, err := s.driver.GetDisplayConnection(ctx)
108+
if err != nil {
109+
s.logger.Errorf("GetDisplayConnection failed: %v", err)
110+
return nil, err
111+
}
112+
s.logger.Debug("GetDisplayConnection succeeded")
113+
return &pb.GetDisplayConnectionResponse{Connection: conn}, nil
114+
}
115+
116+
func (s *DriverServer) CreateSnapshot(ctx context.Context, req *pb.CreateSnapshotRequest) (*emptypb.Empty, error) {
117+
s.logger.Debugf("Received CreateSnapshot request with tag: %s", req.Tag)
118+
err := s.driver.CreateSnapshot(ctx, req.Tag)
119+
if err != nil {
120+
s.logger.Errorf("CreateSnapshot failed: %v", err)
121+
return &emptypb.Empty{}, err
122+
}
123+
s.logger.Debug("CreateSnapshot succeeded")
124+
return &emptypb.Empty{}, nil
125+
}
126+
127+
func (s *DriverServer) ApplySnapshot(ctx context.Context, req *pb.ApplySnapshotRequest) (*emptypb.Empty, error) {
128+
s.logger.Debugf("Received ApplySnapshot request with tag: %s", req.Tag)
129+
err := s.driver.ApplySnapshot(ctx, req.Tag)
130+
if err != nil {
131+
s.logger.Errorf("ApplySnapshot failed: %v", err)
132+
return &emptypb.Empty{}, err
133+
}
134+
s.logger.Debug("ApplySnapshot succeeded")
135+
return &emptypb.Empty{}, nil
136+
}
137+
138+
func (s *DriverServer) DeleteSnapshot(ctx context.Context, req *pb.DeleteSnapshotRequest) (*emptypb.Empty, error) {
139+
s.logger.Debugf("Received DeleteSnapshot request with tag: %s", req.Tag)
140+
err := s.driver.DeleteSnapshot(ctx, req.Tag)
141+
if err != nil {
142+
s.logger.Errorf("DeleteSnapshot failed: %v", err)
143+
return &emptypb.Empty{}, err
144+
}
145+
s.logger.Debug("DeleteSnapshot succeeded")
146+
return &emptypb.Empty{}, nil
147+
}
148+
149+
func (s *DriverServer) ListSnapshots(ctx context.Context, empty *emptypb.Empty) (*pb.ListSnapshotsResponse, error) {
150+
s.logger.Debug("Received ListSnapshots request")
151+
snapshots, err := s.driver.ListSnapshots(ctx)
152+
if err != nil {
153+
s.logger.Errorf("ListSnapshots failed: %v", err)
154+
return nil, err
155+
}
156+
s.logger.Debug("ListSnapshots succeeded")
157+
return &pb.ListSnapshotsResponse{Snapshots: snapshots}, nil
158+
}
159+
160+
func (s *DriverServer) Register(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
161+
s.logger.Debug("Received Register request")
162+
err := s.driver.Register(ctx)
163+
if err != nil {
164+
s.logger.Errorf("Register failed: %v", err)
165+
return empty, err
166+
}
167+
s.logger.Debug("Register succeeded")
168+
return empty, nil
169+
}
170+
171+
func (s *DriverServer) Unregister(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
172+
s.logger.Debug("Received Unregister request")
173+
err := s.driver.Unregister(ctx)
174+
if err != nil {
175+
s.logger.Errorf("Unregister failed: %v", err)
176+
return empty, err
177+
}
178+
s.logger.Debug("Unregister succeeded")
179+
return empty, nil
180+
}
181+
182+
func (s *DriverServer) ForwardGuestAgent(ctx context.Context, empty *emptypb.Empty) (*pb.ForwardGuestAgentResponse, error) {
183+
s.logger.Debug("Received ForwardGuestAgent request")
184+
return &pb.ForwardGuestAgentResponse{ShouldForward: s.driver.ForwardGuestAgent()}, nil
185+
}

0 commit comments

Comments
 (0)