Skip to content

Commit 6c1a5cf

Browse files
committed
driver(external): implement server defination
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent b91f166 commit 6c1a5cf

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

pkg/driver/external/server.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package external
5+
6+
import (
7+
"io"
8+
"net"
9+
"os"
10+
"os/signal"
11+
"sync"
12+
"syscall"
13+
"time"
14+
15+
"github.com/sirupsen/logrus"
16+
"google.golang.org/grpc"
17+
"google.golang.org/grpc/keepalive"
18+
19+
"github.com/lima-vm/lima/pkg/driver"
20+
)
21+
22+
type Server struct {
23+
UnimplementedDriverServer
24+
driver driver.Driver
25+
logger *logrus.Logger
26+
}
27+
28+
func Serve(driver driver.Driver) {
29+
logger := logrus.New()
30+
logger.SetLevel(logrus.DebugLevel)
31+
logger.SetFormatter(&logrus.TextFormatter{
32+
FullTimestamp: true,
33+
})
34+
logger.Infof("Starting external driver server for %s", driver.Name())
35+
36+
pipeConn := &PipeConn{
37+
Reader: os.Stdin,
38+
Writer: os.Stdout,
39+
}
40+
41+
listener := NewPipeListener(pipeConn)
42+
43+
kaProps := keepalive.ServerParameters{
44+
Time: 10 * time.Second,
45+
Timeout: 20 * time.Second,
46+
}
47+
48+
kaPolicy := keepalive.EnforcementPolicy{
49+
MinTime: 2 * time.Second,
50+
PermitWithoutStream: true,
51+
}
52+
53+
server := grpc.NewServer(
54+
grpc.KeepaliveParams(kaProps),
55+
grpc.KeepaliveEnforcementPolicy(kaPolicy),
56+
)
57+
58+
RegisterDriverServer(server, &Server{
59+
driver: driver,
60+
logger: logger,
61+
})
62+
63+
sigs := make(chan os.Signal, 1)
64+
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
65+
66+
go func() {
67+
<-sigs
68+
logger.Info("Received shutdown signal, stopping server...")
69+
server.Stop()
70+
os.Exit(0)
71+
}()
72+
73+
logger.Info("Server starting...")
74+
if err := server.Serve(listener); err != nil {
75+
logger.Fatalf("Failed to serve: %v", err)
76+
}
77+
}
78+
79+
type PipeConn struct {
80+
Reader io.Reader
81+
Writer io.Writer
82+
}
83+
84+
func (p *PipeConn) Read(b []byte) (n int, err error) {
85+
return p.Reader.Read(b)
86+
}
87+
88+
func (p *PipeConn) Write(b []byte) (n int, err error) {
89+
return p.Writer.Write(b)
90+
}
91+
92+
func (p *PipeConn) Close() error {
93+
return nil
94+
}
95+
96+
func (p *PipeConn) LocalAddr() net.Addr {
97+
return pipeAddr{}
98+
}
99+
100+
func (p *PipeConn) RemoteAddr() net.Addr {
101+
return pipeAddr{}
102+
}
103+
104+
func (p *PipeConn) SetDeadline(t time.Time) error {
105+
return nil
106+
}
107+
108+
func (p *PipeConn) SetReadDeadline(t time.Time) error {
109+
return nil
110+
}
111+
112+
func (p *PipeConn) SetWriteDeadline(t time.Time) error {
113+
return nil
114+
}
115+
116+
type pipeAddr struct{}
117+
118+
func (pipeAddr) Network() string { return "pipe" }
119+
func (pipeAddr) String() string { return "pipe" }
120+
121+
type PipeListener struct {
122+
conn net.Conn
123+
connSent bool
124+
mu sync.Mutex
125+
closed bool
126+
}
127+
128+
func NewPipeListener(conn net.Conn) *PipeListener {
129+
return &PipeListener{
130+
conn: conn,
131+
connSent: false,
132+
closed: false,
133+
}
134+
}
135+
136+
func (l *PipeListener) Accept() (net.Conn, error) {
137+
l.mu.Lock()
138+
defer l.mu.Unlock()
139+
140+
if l.closed {
141+
return nil, net.ErrClosed
142+
}
143+
144+
if l.connSent {
145+
select {}
146+
}
147+
148+
l.connSent = true
149+
return l.conn, nil
150+
}
151+
152+
func (l *PipeListener) Close() error {
153+
l.mu.Lock()
154+
defer l.mu.Unlock()
155+
156+
if !l.closed {
157+
l.closed = true
158+
}
159+
return nil
160+
}
161+
162+
func (l *PipeListener) Addr() net.Addr {
163+
return pipeAddr{}
164+
}

0 commit comments

Comments
 (0)