4
4
package registry
5
5
6
6
import (
7
+ "bufio"
7
8
"context"
8
9
"fmt"
9
10
"io"
@@ -12,9 +13,11 @@ import (
12
13
"path/filepath"
13
14
"strings"
14
15
"sync"
16
+ "time"
15
17
16
18
"github.com/lima-vm/lima/pkg/driver"
17
19
"github.com/lima-vm/lima/pkg/driver/external/client"
20
+ "github.com/lima-vm/lima/pkg/usrlocalsharelima"
18
21
"github.com/sirupsen/logrus"
19
22
)
20
23
@@ -26,6 +29,7 @@ type ExternalDriver struct {
26
29
Client * client.DriverClient // Client is the gRPC client for the external driver
27
30
Path string
28
31
ctx context.Context
32
+ logger * logrus.Logger
29
33
cancelFunc context.CancelFunc
30
34
}
31
35
@@ -42,6 +46,64 @@ func NewRegistry() *Registry {
42
46
}
43
47
}
44
48
49
+ func (e * ExternalDriver ) Start () error {
50
+ e .logger .Infof ("Starting external driver at %s" , e .Path )
51
+
52
+ ctx , cancel := context .WithCancel (context .Background ())
53
+ cmd := exec .CommandContext (ctx , e .Path )
54
+
55
+ stdin , err := cmd .StdinPipe ()
56
+ if err != nil {
57
+ cancel ()
58
+ return fmt .Errorf ("failed to create stdin pipe: %w" , err )
59
+ }
60
+
61
+ stdout , err := cmd .StdoutPipe ()
62
+ if err != nil {
63
+ cancel ()
64
+ return fmt .Errorf ("failed to create stdout pipe: %w" , err )
65
+ }
66
+
67
+ stderr , err := cmd .StderrPipe ()
68
+ if err != nil {
69
+ cancel ()
70
+ return fmt .Errorf ("failed to create stderr pipe: %w" , err )
71
+ }
72
+
73
+ if err := cmd .Start (); err != nil {
74
+ cancel ()
75
+ return fmt .Errorf ("failed to start external driver: %w" , err )
76
+ }
77
+
78
+ driverLogger := e .logger .WithField ("driver" , e .Name )
79
+
80
+ go func () {
81
+ scanner := bufio .NewScanner (stderr )
82
+ for scanner .Scan () {
83
+ driverLogger .Info (scanner .Text ())
84
+ }
85
+ }()
86
+
87
+ time .Sleep (4 * time .Second )
88
+
89
+ driverClient , err := client .NewDriverClient (stdin , stdout , e .logger )
90
+ if err != nil {
91
+ cancel ()
92
+ cmd .Process .Kill ()
93
+ return fmt .Errorf ("failed to create driver client: %w" , err )
94
+ }
95
+
96
+ e .Command = cmd
97
+ e .Stdin = stdin
98
+ e .Stdout = stdout
99
+ e .Client = driverClient
100
+ e .ctx = ctx
101
+ e .cancelFunc = cancel
102
+
103
+ driverLogger .Infof ("External driver %s started successfully" , e .Name )
104
+ return nil
105
+ }
106
+
45
107
func (r * Registry ) List () []string {
46
108
r .mu .RLock ()
47
109
defer r .mu .RUnlock ()
@@ -51,7 +113,6 @@ func (r *Registry) List() []string {
51
113
names = append (names , name )
52
114
}
53
115
54
- r .DiscoverDrivers ()
55
116
for name := range r .externalDrivers {
56
117
names = append (names , name + " (external)" )
57
118
}
@@ -66,6 +127,11 @@ func (r *Registry) Get(name string) (driver.Driver, bool) {
66
127
if ! exists {
67
128
externalDriver , exists := r .externalDrivers [name ]
68
129
if exists {
130
+ externalDriver .logger .Debugf ("Using external driver %q" , name )
131
+ if err := externalDriver .Start (); err != nil {
132
+ externalDriver .logger .Errorf ("Failed to start external driver %q: %v" , name , err )
133
+ return nil , false
134
+ }
69
135
return externalDriver .Client , true
70
136
}
71
137
@@ -77,33 +143,38 @@ func (r *Registry) RegisterDriver(name, path string) {
77
143
r .mu .Lock ()
78
144
defer r .mu .Unlock ()
79
145
80
- if _ , exists := r .externalDrivers [name ]; exists {
146
+ if _ , exists := DefaultRegistry .externalDrivers [name ]; exists {
81
147
logrus .Debugf ("Driver %q is already registered, skipping" , name )
82
148
return
83
149
}
84
150
85
- r .externalDrivers [name ].Path = path
86
- logrus .Debugf ("Registered driver %q at %s" , name , path )
151
+ log := logrus .New ()
152
+ log .SetFormatter (& logrus.TextFormatter {
153
+ FullTimestamp : true ,
154
+ })
155
+
156
+ DefaultRegistry .externalDrivers [name ] = & ExternalDriver {
157
+ Name : name ,
158
+ Path : path ,
159
+ logger : log ,
160
+ }
87
161
}
88
162
89
163
func (r * Registry ) DiscoverDrivers () error {
90
- // limaShareDir, err := usrlocalsharelima.Dir()
91
- // if err != nil {
92
- // return fmt.Errorf("failed to determine Lima share directory: %w", err)
93
- // }
94
- // fmt.Printf("Discovering drivers in %s\n", limaShareDir)
95
- // stdDriverDir := filepath.Join(filepath.Dir(limaShareDir), "libexec", "lima", "drivers")
96
-
97
- // if _, err := os.Stat(stdDriverDir); err == nil {
98
- // if err := r.discoverDriversInDir(stdDriverDir); err != nil {
99
- // logrus.Warnf("Error discovering drivers in %s: %v", stdDriverDir, err)
100
- // }
101
- // }
164
+ limaShareDir , err := usrlocalsharelima .Dir ()
165
+ if err != nil {
166
+ return fmt .Errorf ("failed to determine Lima share directory: %w" , err )
167
+ }
168
+ stdDriverDir := filepath .Join (filepath .Dir (limaShareDir ), "libexec" , "lima" , "drivers" )
169
+
170
+ if _ , err := os .Stat (stdDriverDir ); err == nil {
171
+ if err := r .discoverDriversInDir (stdDriverDir ); err != nil {
172
+ logrus .Warnf ("Error discovering drivers in %s: %v" , stdDriverDir , err )
173
+ }
174
+ }
102
175
103
176
if driverPaths := os .Getenv ("LIMA_DRIVERS_PATH" ); driverPaths != "" {
104
- fmt .Printf ("Discovering drivers in LIMA_DRIVERS_PATH: %s\n " , driverPaths )
105
177
paths := filepath .SplitList (driverPaths )
106
- fmt .Println ("Driver paths:" , paths )
107
178
for _ , path := range paths {
108
179
if path == "" {
109
180
continue
@@ -114,9 +185,6 @@ func (r *Registry) DiscoverDrivers() error {
114
185
logrus .Warnf ("Error accessing driver path %s: %v" , path , err )
115
186
continue
116
187
}
117
- fmt .Printf ("Info for %s: %+v\n " , path , info )
118
- fmt .Printf ("IsExecutable: %v\n " , isExecutable (info .Mode ()))
119
- fmt .Printf ("IsDir: %v\n " , info .IsDir ())
120
188
121
189
if info .IsDir () {
122
190
if err := r .discoverDriversInDir (path ); err != nil {
@@ -162,18 +230,13 @@ func (r *Registry) discoverDriversInDir(dir string) error {
162
230
func (r * Registry ) registerDriverFile (path string ) {
163
231
base := filepath .Base (path )
164
232
if ! strings .HasPrefix (base , "lima-driver-" ) {
233
+ fmt .Printf ("Skipping %s: does not start with 'lima-driver-'\n " , base )
165
234
return
166
235
}
167
236
168
237
name := strings .TrimPrefix (base , "lima-driver-" )
169
238
name = strings .TrimSuffix (name , filepath .Ext (name ))
170
239
171
- cmd := exec .Command (path , "--version" )
172
- if err := cmd .Run (); err != nil {
173
- logrus .Warnf ("driver %s failed version check: %v" , path , err )
174
- return
175
- }
176
-
177
240
r .RegisterDriver (name , path )
178
241
}
179
242
@@ -185,7 +248,9 @@ var DefaultRegistry *Registry
185
248
186
249
func init () {
187
250
DefaultRegistry = NewRegistry ()
188
- DefaultRegistry .DiscoverDrivers ()
251
+ if err := DefaultRegistry .DiscoverDrivers (); err != nil {
252
+ logrus .Warnf ("Error discovering drivers: %v" , err )
253
+ }
189
254
}
190
255
191
256
func Register (driver driver.Driver ) {
0 commit comments