Skip to content

Commit ed4ecef

Browse files
committed
driver(external): add discovery of external drivers
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent d7ccaf8 commit ed4ecef

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

pkg/registry/registry.go

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44
package registry
55

66
import (
7+
"fmt"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
"strings"
712
"sync"
813

914
"github.com/lima-vm/lima/pkg/driver"
15+
"github.com/lima-vm/lima/pkg/usrlocalsharelima"
1016
"github.com/sirupsen/logrus"
1117
)
1218

@@ -68,10 +74,94 @@ func (r *Registry) RegisterPlugin(name, path string) {
6874
}
6975

7076
func (r *Registry) DiscoverPlugins() error {
71-
// TODO: Implement plugin discovery logic
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)
91+
for _, path := range paths {
92+
if path == "" {
93+
continue
94+
}
95+
96+
info, err := os.Stat(path)
97+
if err != nil {
98+
logrus.Warnf("Error accessing plugin path %s: %v", path, err)
99+
continue
100+
}
101+
102+
if info.IsDir() {
103+
if err := r.discoverPluginsInDir(path); err != nil {
104+
logrus.Warnf("Error discovering plugins in %s: %v", path, err)
105+
}
106+
} else if isExecutable(info.Mode()) {
107+
r.registerPluginFile(path)
108+
}
109+
}
110+
}
111+
112+
return nil
113+
}
114+
115+
func (r *Registry) discoverPluginsInDir(dir string) error {
116+
entries, err := os.ReadDir(dir)
117+
if err != nil {
118+
return fmt.Errorf("failed to read plugin directory %s: %w", dir, err)
119+
}
120+
121+
for _, entry := range entries {
122+
if entry.IsDir() {
123+
continue
124+
}
125+
126+
info, err := entry.Info()
127+
if err != nil {
128+
logrus.Warnf("Failed to get info for %s: %v", entry.Name(), err)
129+
continue
130+
}
131+
132+
if !isExecutable(info.Mode()) {
133+
continue
134+
}
135+
136+
pluginPath := filepath.Join(dir, entry.Name())
137+
r.registerPluginFile(pluginPath)
138+
}
139+
72140
return nil
73141
}
74142

143+
func (r *Registry) registerPluginFile(path string) {
144+
base := filepath.Base(path)
145+
if !strings.HasPrefix(base, "lima-plugin-") {
146+
return
147+
}
148+
149+
name := strings.TrimPrefix(base, "lima-plugin-")
150+
name = strings.TrimSuffix(name, filepath.Ext(name))
151+
152+
cmd := exec.Command(path, "--version")
153+
if err := cmd.Run(); err != nil {
154+
logrus.Warnf("Plugin %s failed version check: %v", path, err)
155+
return
156+
}
157+
158+
r.RegisterPlugin(name, path)
159+
}
160+
161+
func isExecutable(mode os.FileMode) bool {
162+
return mode&0111 != 0
163+
}
164+
75165
var DefaultRegistry *Registry
76166

77167
func init() {

0 commit comments

Comments
 (0)