Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/registry/registry.go
2609 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package registry
5
6
import (
7
"context"
8
"fmt"
9
"os"
10
"os/exec"
11
"path/filepath"
12
"runtime"
13
"strings"
14
15
"github.com/sirupsen/logrus"
16
17
"github.com/lima-vm/lima/v2/pkg/driver"
18
"github.com/lima-vm/lima/v2/pkg/driver/external/client"
19
"github.com/lima-vm/lima/v2/pkg/usrlocal"
20
)
21
22
const (
23
Internal = "internal"
24
External = "external"
25
)
26
27
type ExternalDriver struct {
28
Name string
29
InstanceName string
30
Command *exec.Cmd
31
SocketPath string
32
Client *client.DriverClient // Client is the gRPC client for the external driver
33
Path string
34
Ctx context.Context
35
Logger *logrus.Logger
36
CancelFunc context.CancelFunc
37
}
38
39
var (
40
internalDrivers = make(map[string]driver.Driver)
41
ExternalDrivers = make(map[string]*ExternalDriver)
42
)
43
44
func List() map[string]string {
45
if err := discoverDrivers(); err != nil {
46
logrus.Warnf("Error discovering drivers: %v", err)
47
}
48
49
vmTypes := make(map[string]string)
50
for name := range internalDrivers {
51
vmTypes[name] = Internal
52
}
53
for name, d := range ExternalDrivers {
54
vmTypes[name] = d.Path
55
}
56
57
return vmTypes
58
}
59
60
func CheckInternalOrExternal(name string) string {
61
extDriver, _, exists := Get(name)
62
if !exists {
63
return ""
64
}
65
if extDriver != nil {
66
return External
67
}
68
69
return Internal
70
}
71
72
func Get(name string) (*ExternalDriver, driver.Driver, bool) {
73
internalDriver, exists := internalDrivers[name]
74
if !exists {
75
if err := discoverDrivers(); err != nil {
76
logrus.Warnf("Error discovering drivers: %v", err)
77
}
78
externalDriver, exists := ExternalDrivers[name]
79
if exists {
80
return externalDriver, nil, exists
81
}
82
}
83
return nil, internalDriver, exists
84
}
85
86
func registerExternalDriver(name, path string) {
87
if _, exists := ExternalDrivers[name]; exists {
88
return
89
}
90
91
if _, exists := internalDrivers[name]; exists {
92
logrus.Debugf("Driver %q is already registered as an internal driver, skipping external registration", name)
93
return
94
}
95
96
ExternalDrivers[name] = &ExternalDriver{
97
Name: name,
98
Path: path,
99
Logger: logrus.New(),
100
}
101
}
102
103
func discoverDrivers() error {
104
if driverPaths := os.Getenv("LIMA_DRIVERS_PATH"); driverPaths != "" {
105
paths := filepath.SplitList(driverPaths)
106
for _, path := range paths {
107
if path == "" {
108
continue
109
}
110
111
info, err := os.Stat(path)
112
if err != nil {
113
logrus.Warnf("Error accessing external driver path %q: %v", path, err)
114
continue
115
}
116
117
if info.IsDir() {
118
if err := discoverDriversInDir(path); err != nil {
119
logrus.Warnf("Error discovering external drivers in %q: %v", path, err)
120
}
121
} else if isExecutable(info.Mode()) {
122
registerDriverFile(path)
123
}
124
}
125
}
126
127
stdDriverDirs, err := usrlocal.LibexecLima()
128
if err != nil {
129
return err
130
}
131
132
logrus.Debugf("Discovering external drivers in %v", stdDriverDirs)
133
for _, dir := range stdDriverDirs {
134
if _, err := os.Stat(dir); err == nil {
135
if err := discoverDriversInDir(dir); err != nil {
136
logrus.Warnf("Error discovering external drivers in %q: %v", dir, err)
137
}
138
}
139
}
140
return nil
141
}
142
143
func discoverDriversInDir(dir string) error {
144
entries, err := os.ReadDir(dir)
145
if err != nil {
146
return fmt.Errorf("failed to read driver directory %q: %w", dir, err)
147
}
148
149
for _, entry := range entries {
150
if entry.IsDir() {
151
continue
152
}
153
154
info, err := entry.Info()
155
if err != nil {
156
logrus.Warnf("Failed to get info for %q: %v", entry.Name(), err)
157
continue
158
}
159
160
if !isExecutable(info.Mode()) {
161
continue
162
}
163
164
driverPath := filepath.Join(dir, entry.Name())
165
registerDriverFile(driverPath)
166
}
167
168
return nil
169
}
170
171
func registerDriverFile(path string) {
172
base := filepath.Base(path)
173
name := ""
174
if runtime.GOOS == "windows" {
175
if strings.HasPrefix(base, "lima-driver-") && strings.HasSuffix(base, ".exe") {
176
name = strings.TrimSuffix(strings.TrimPrefix(base, "lima-driver-"), ".exe")
177
}
178
} else {
179
if strings.HasPrefix(base, "lima-driver-") && !strings.HasSuffix(base, ".exe") {
180
name = strings.TrimPrefix(base, "lima-driver-")
181
}
182
}
183
if name == "" {
184
return
185
}
186
registerExternalDriver(name, path)
187
}
188
189
func isExecutable(mode os.FileMode) bool {
190
if runtime.GOOS == "windows" {
191
return true
192
}
193
return mode&0o111 != 0
194
}
195
196
func Register(driver driver.Driver) {
197
name := driver.Info().Name
198
if _, exists := internalDrivers[name]; exists {
199
return
200
}
201
internalDrivers[name] = driver
202
}
203
204