4
4
package registry
5
5
6
6
import (
7
+ "context"
7
8
"fmt"
9
+ "io"
8
10
"os"
9
11
"os/exec"
10
12
"path/filepath"
11
13
"strings"
12
14
"sync"
13
15
14
16
"github.com/lima-vm/lima/pkg/driver"
15
- "github.com/lima-vm/lima/pkg/usrlocalsharelima "
17
+ "github.com/lima-vm/lima/pkg/driver/external/client "
16
18
"github.com/sirupsen/logrus"
17
19
)
18
20
21
+ type ExternalDriver struct {
22
+ Name string
23
+ Command * exec.Cmd
24
+ Stdin io.WriteCloser
25
+ Stdout io.ReadCloser
26
+ Client * client.DriverClient // Client is the gRPC client for the external driver
27
+ Path string
28
+ ctx context.Context
29
+ cancelFunc context.CancelFunc
30
+ }
31
+
19
32
type Registry struct {
20
- drivers map [string ]driver.Driver
21
- externalDrivers map [string ]string // For now mapping external driver names to paths
33
+ internalDrivers map [string ]driver.Driver
34
+ externalDrivers map [string ]* ExternalDriver
22
35
mu sync.RWMutex
23
36
}
24
37
25
38
func NewRegistry () * Registry {
26
39
return & Registry {
27
- drivers : make (map [string ]driver.Driver ),
28
- externalDrivers : make (map [string ]string ),
40
+ internalDrivers : make (map [string ]driver.Driver ),
41
+ externalDrivers : make (map [string ]* ExternalDriver ),
29
42
}
30
43
}
31
44
@@ -34,10 +47,11 @@ func (r *Registry) List() []string {
34
47
defer r .mu .RUnlock ()
35
48
36
49
var names []string
37
- for name := range r .drivers {
50
+ for name := range r .internalDrivers {
38
51
names = append (names , name )
39
52
}
40
53
54
+ r .DiscoverDrivers ()
41
55
for name := range r .externalDrivers {
42
56
names = append (names , name + " (external)" )
43
57
}
@@ -48,74 +62,79 @@ func (r *Registry) Get(name string) (driver.Driver, bool) {
48
62
r .mu .RLock ()
49
63
defer r .mu .RUnlock ()
50
64
51
- driver , exists := r .drivers [name ]
52
- return driver , exists
53
- }
54
-
55
- func (r * Registry ) GetExternalDriver (name string ) (string , bool ) {
56
- r .mu .RLock ()
57
- defer r .mu .RUnlock ()
65
+ driver , exists := r .internalDrivers [name ]
66
+ if ! exists {
67
+ externalDriver , exists := r .externalDrivers [name ]
68
+ if exists {
69
+ return externalDriver .Client , true
70
+ }
58
71
59
- plugin , exists := r . externalDrivers [ name ]
60
- return plugin , exists
72
+ }
73
+ return driver , exists
61
74
}
62
75
63
- func (r * Registry ) RegisterPlugin (name , path string ) {
76
+ func (r * Registry ) RegisterDriver (name , path string ) {
64
77
r .mu .Lock ()
65
78
defer r .mu .Unlock ()
66
79
67
80
if _ , exists := r .externalDrivers [name ]; exists {
68
- logrus .Debugf ("Plugin %q is already registered, skipping" , name )
81
+ logrus .Debugf ("Driver %q is already registered, skipping" , name )
69
82
return
70
83
}
71
84
72
- r .externalDrivers [name ] = path
73
- logrus .Debugf ("Registered plugin %q at %s" , name , path )
85
+ r .externalDrivers [name ]. Path = path
86
+ logrus .Debugf ("Registered driver %q at %s" , name , path )
74
87
}
75
88
76
- func (r * Registry ) DiscoverPlugins () error {
77
- limaShareDir , err := usrlocalsharelima .Dir ()
78
- if err != nil {
79
- return fmt .Errorf ("failed to determine Lima share directory: %w" , err )
80
- }
81
- stdPluginDir := filepath .Join (filepath .Dir (limaShareDir ), "libexec" , "lima" , "drivers" )
82
-
83
- if _ , err := os .Stat (stdPluginDir ); err == nil {
84
- if err := r .discoverPluginsInDir (stdPluginDir ); err != nil {
85
- logrus .Warnf ("Error discovering plugins in %s: %v" , stdPluginDir , err )
86
- }
87
- }
88
-
89
- if pluginPaths := os .Getenv ("LIMA_DRIVERS_PATH" ); pluginPaths != "" {
90
- paths := filepath .SplitList (pluginPaths )
89
+ 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
+ // }
102
+
103
+ if driverPaths := os .Getenv ("LIMA_DRIVERS_PATH" ); driverPaths != "" {
104
+ fmt .Printf ("Discovering drivers in LIMA_DRIVERS_PATH: %s\n " , driverPaths )
105
+ paths := filepath .SplitList (driverPaths )
106
+ fmt .Println ("Driver paths:" , paths )
91
107
for _ , path := range paths {
92
108
if path == "" {
93
109
continue
94
110
}
95
111
96
112
info , err := os .Stat (path )
97
113
if err != nil {
98
- logrus .Warnf ("Error accessing plugin path %s: %v" , path , err )
114
+ logrus .Warnf ("Error accessing driver path %s: %v" , path , err )
99
115
continue
100
116
}
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 ())
101
120
102
121
if info .IsDir () {
103
- if err := r .discoverPluginsInDir (path ); err != nil {
104
- logrus .Warnf ("Error discovering plugins in %s: %v" , path , err )
122
+ if err := r .discoverDriversInDir (path ); err != nil {
123
+ logrus .Warnf ("Error discovering drivers in %s: %v" , path , err )
105
124
}
106
125
} else if isExecutable (info .Mode ()) {
107
- r .registerPluginFile (path )
126
+ r .registerDriverFile (path )
108
127
}
109
128
}
110
129
}
111
130
112
131
return nil
113
132
}
114
133
115
- func (r * Registry ) discoverPluginsInDir (dir string ) error {
134
+ func (r * Registry ) discoverDriversInDir (dir string ) error {
116
135
entries , err := os .ReadDir (dir )
117
136
if err != nil {
118
- return fmt .Errorf ("failed to read plugin directory %s: %w" , dir , err )
137
+ return fmt .Errorf ("failed to read driver directory %s: %w" , dir , err )
119
138
}
120
139
121
140
for _ , entry := range entries {
@@ -133,29 +152,29 @@ func (r *Registry) discoverPluginsInDir(dir string) error {
133
152
continue
134
153
}
135
154
136
- pluginPath := filepath .Join (dir , entry .Name ())
137
- r .registerPluginFile ( pluginPath )
155
+ driverPath := filepath .Join (dir , entry .Name ())
156
+ r .registerDriverFile ( driverPath )
138
157
}
139
158
140
159
return nil
141
160
}
142
161
143
- func (r * Registry ) registerPluginFile (path string ) {
162
+ func (r * Registry ) registerDriverFile (path string ) {
144
163
base := filepath .Base (path )
145
- if ! strings .HasPrefix (base , "lima-plugin -" ) {
164
+ if ! strings .HasPrefix (base , "lima-driver -" ) {
146
165
return
147
166
}
148
167
149
- name := strings .TrimPrefix (base , "lima-plugin -" )
168
+ name := strings .TrimPrefix (base , "lima-driver -" )
150
169
name = strings .TrimSuffix (name , filepath .Ext (name ))
151
170
152
171
cmd := exec .Command (path , "--version" )
153
172
if err := cmd .Run (); err != nil {
154
- logrus .Warnf ("Plugin %s failed version check: %v" , path , err )
173
+ logrus .Warnf ("driver %s failed version check: %v" , path , err )
155
174
return
156
175
}
157
176
158
- r .RegisterPlugin (name , path )
177
+ r .RegisterDriver (name , path )
159
178
}
160
179
161
180
func isExecutable (mode os.FileMode ) bool {
@@ -166,15 +185,16 @@ var DefaultRegistry *Registry
166
185
167
186
func init () {
168
187
DefaultRegistry = NewRegistry ()
188
+ DefaultRegistry .DiscoverDrivers ()
169
189
}
170
190
171
191
func Register (driver driver.Driver ) {
172
192
if DefaultRegistry != nil {
173
193
name := driver .GetInfo ().DriverName
174
- if _ , exists := DefaultRegistry .drivers [name ]; exists {
194
+ if _ , exists := DefaultRegistry .internalDrivers [name ]; exists {
175
195
return
176
196
}
177
197
178
- DefaultRegistry .drivers [name ] = driver
198
+ DefaultRegistry .internalDrivers [name ] = driver
179
199
}
180
200
}
0 commit comments