Skip to content

Commit c841df5

Browse files
authored
Merge pull request #3693 from unsuman/feature/internal-driver-system
Feature: Internal driver plugin system
2 parents 791bcd9 + 363baf5 commit c841df5

21 files changed

+297
-355
lines changed

cmd/limactl/main_darwin.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !external_vz
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package main
7+
8+
// Import vz driver to register it in the registry on darwin.
9+
import _ "github.com/lima-vm/lima/pkg/driver/vz"

cmd/limactl/main_qemu.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !external_qemu
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package main
7+
8+
// Import qemu driver to register it in the registry on all platforms.
9+
import _ "github.com/lima-vm/lima/pkg/driver/qemu"

cmd/limactl/main_windows.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !external_wsl2
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package main
7+
8+
// Import wsl2 driver to register it in the registry on windows.
9+
import _ "github.com/lima-vm/lima/pkg/driver/wsl2"

pkg/driver/driver.go

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ package driver
66
import (
77
"context"
88
"net"
9+
10+
"github.com/lima-vm/lima/pkg/store"
911
)
1012

11-
// Driver interface is used by hostagent for managing vm.
12-
type Driver interface {
13+
// Lifecycle defines basic lifecycle operations.
14+
type Lifecycle interface {
1315
// Validate returns error if the current driver isn't support for given config
1416
Validate() error
1517

@@ -29,43 +31,66 @@ type Driver interface {
2931
// The second argument may contain error occurred while starting driver
3032
Start(_ context.Context) (chan error, error)
3133

32-
// CanRunGUI returns bool to indicate if the hostagent need to run GUI synchronously
33-
CanRunGUI() bool
34-
35-
// RunGUI is for starting GUI synchronously by hostagent. This method should be wait and return only after vm terminates
36-
// It returns error if there are any failures
37-
RunGUI() error
38-
3934
// Stop will terminate the running vm instance.
4035
// It returns error if there are any errors during Stop
4136
Stop(_ context.Context) error
37+
}
4238

43-
// Register will add an instance to a registry.
44-
// It returns error if there are any errors during Register
45-
Register(_ context.Context) error
39+
// GUI defines GUI-related operations.
40+
type GUI interface {
41+
// RunGUI is for starting GUI synchronously by hostagent. This method should be wait and return only after vm terminates
42+
// It returns error if there are any failures
43+
RunGUI() error
4644

47-
// Unregister will perform any cleanup related to the vm instance.
48-
// It returns error if there are any errors during Unregister
49-
Unregister(_ context.Context) error
45+
ChangeDisplayPassword(ctx context.Context, password string) error
46+
DisplayConnection(ctx context.Context) (string, error)
47+
}
5048

51-
ChangeDisplayPassword(_ context.Context, password string) error
49+
// SnapshotManager defines operations for managing snapshots.
50+
type SnapshotManager interface {
51+
CreateSnapshot(ctx context.Context, tag string) error
52+
ApplySnapshot(ctx context.Context, tag string) error
53+
DeleteSnapshot(ctx context.Context, tag string) error
54+
ListSnapshots(ctx context.Context) (string, error)
55+
}
5256

53-
GetDisplayConnection(_ context.Context) (string, error)
57+
// Registration defines operations for registering and unregistering the driver instance.
58+
type Registration interface {
59+
Register(ctx context.Context) error
60+
Unregister(ctx context.Context) error
61+
}
5462

55-
CreateSnapshot(_ context.Context, tag string) error
63+
// GuestAgent defines operations for the guest agent.
64+
type GuestAgent interface {
65+
// ForwardGuestAgent returns if the guest agent sock needs forwarding by host agent.
66+
ForwardGuestAgent() bool
5667

57-
ApplySnapshot(_ context.Context, tag string) error
68+
// GuestAgentConn returns the guest agent connection, or nil (if forwarded by ssh).
69+
GuestAgentConn(_ context.Context) (net.Conn, string, error)
70+
}
5871

59-
DeleteSnapshot(_ context.Context, tag string) error
72+
// Driver interface is used by hostagent for managing vm.
73+
type Driver interface {
74+
Lifecycle
75+
GUI
76+
SnapshotManager
77+
Registration
78+
GuestAgent
6079

61-
ListSnapshots(_ context.Context) (string, error)
80+
Info() Info
6281

63-
// ForwardGuestAgent returns if the guest agent sock needs forwarding by host agent.
64-
ForwardGuestAgent() bool
82+
// SetConfig sets the configuration for the instance.
83+
Configure(inst *store.Instance, sshLocalPort int) *ConfiguredDriver
84+
}
6585

66-
// GuestAgentConn returns the guest agent connection, or nil (if forwarded by ssh).
67-
GuestAgentConn(_ context.Context) (net.Conn, error)
86+
type ConfiguredDriver struct {
87+
Driver
88+
}
6889

69-
VSockPort() int
70-
VirtioPort() string
90+
type Info struct {
91+
DriverName string `json:"driverName"`
92+
CanRunGUI bool `json:"canRunGui,omitempty"`
93+
VsockPort int `json:"vsockPort"`
94+
VirtioPort string `json:"virtioPort"`
95+
InstanceDir string `json:"instanceDir,omitempty"`
7196
}

pkg/driver/qemu/qemu_driver.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type LimaQemuDriver struct {
5050

5151
var _ driver.Driver = (*LimaQemuDriver)(nil)
5252

53-
func New(inst *store.Instance, sshLocalPort int) *LimaQemuDriver {
53+
func New() *LimaQemuDriver {
5454
// virtserialport doesn't seem to work reliably: https://github.com/lima-vm/lima/issues/2064
5555
// but on Windows default Unix socket forwarding is not available
5656
var virtioPort string
@@ -59,10 +59,17 @@ func New(inst *store.Instance, sshLocalPort int) *LimaQemuDriver {
5959
virtioPort = ""
6060
}
6161
return &LimaQemuDriver{
62-
Instance: inst,
63-
vSockPort: 0,
64-
virtioPort: virtioPort,
65-
SSHLocalPort: sshLocalPort,
62+
vSockPort: 0,
63+
virtioPort: virtioPort,
64+
}
65+
}
66+
67+
func (l *LimaQemuDriver) Configure(inst *store.Instance, sshLocalPort int) *driver.ConfiguredDriver {
68+
l.Instance = inst
69+
l.SSHLocalPort = sshLocalPort
70+
71+
return &driver.ConfiguredDriver{
72+
Driver: l,
6673
}
6774
}
6875

@@ -238,7 +245,7 @@ func (l *LimaQemuDriver) ChangeDisplayPassword(_ context.Context, password strin
238245
return l.changeVNCPassword(password)
239246
}
240247

241-
func (l *LimaQemuDriver) GetDisplayConnection(_ context.Context) (string, error) {
248+
func (l *LimaQemuDriver) DisplayConnection(_ context.Context) (string, error) {
242249
return l.getVNCDisplayPort()
243250
}
244251

@@ -450,10 +457,10 @@ func (l *LimaQemuDriver) ListSnapshots(_ context.Context) (string, error) {
450457
return List(qCfg, l.Instance.Status == store.StatusRunning)
451458
}
452459

453-
func (l *LimaQemuDriver) GuestAgentConn(ctx context.Context) (net.Conn, error) {
460+
func (l *LimaQemuDriver) GuestAgentConn(ctx context.Context) (net.Conn, string, error) {
454461
var d net.Dialer
455462
dialContext, err := d.DialContext(ctx, "unix", filepath.Join(l.Instance.Dir, filenames.GuestAgentSock))
456-
return dialContext, err
463+
return dialContext, "unix", err
457464
}
458465

459466
type qArgTemplateApplier struct {
@@ -508,12 +515,20 @@ func (a *qArgTemplateApplier) applyTemplate(qArg string) (string, error) {
508515
return b.String(), nil
509516
}
510517

511-
func (l *LimaQemuDriver) Initialize(_ context.Context) error {
512-
return nil
518+
func (l *LimaQemuDriver) Info() driver.Info {
519+
var info driver.Info
520+
if l.Instance != nil && l.Instance.Dir != "" {
521+
info.InstanceDir = l.Instance.Dir
522+
}
523+
info.DriverName = "qemu"
524+
info.CanRunGUI = false
525+
info.VirtioPort = l.virtioPort
526+
info.VsockPort = l.vSockPort
527+
return info
513528
}
514529

515-
func (l *LimaQemuDriver) CanRunGUI() bool {
516-
return false
530+
func (l *LimaQemuDriver) Initialize(_ context.Context) error {
531+
return nil
517532
}
518533

519534
func (l *LimaQemuDriver) RunGUI() error {
@@ -532,11 +547,3 @@ func (l *LimaQemuDriver) ForwardGuestAgent() bool {
532547
// if driver is not providing, use host agent
533548
return l.vSockPort == 0 && l.virtioPort == ""
534549
}
535-
536-
func (l *LimaQemuDriver) VSockPort() int {
537-
return l.vSockPort
538-
}
539-
540-
func (l *LimaQemuDriver) VirtioPort() string {
541-
return l.virtioPort
542-
}

pkg/driver/qemu/register.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build !external_qemu
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package qemu
7+
8+
import "github.com/lima-vm/lima/pkg/registry"
9+
10+
func init() {
11+
registry.Register(New())
12+
}

pkg/driver/vz/errors_darwin.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ package vz
88
import "errors"
99

1010
//nolint:revive,staticcheck // false positives with proper nouns
11-
var errRosettaUnsupported = errors.New("Rosetta is unsupported on non-ARM64 hosts")
11+
var (
12+
errRosettaUnsupported = errors.New("Rosetta is unsupported on non-ARM64 hosts")
13+
errUnimplemented = errors.New("unimplemented")
14+
)

pkg/driver/vz/register.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build darwin && !external_vz
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package vz
7+
8+
import "github.com/lima-vm/lima/pkg/registry"
9+
10+
func init() {
11+
registry.Register(New())
12+
}

pkg/driver/vz/vz_driver_darwin.go

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,19 @@ type LimaVzDriver struct {
8080

8181
var _ driver.Driver = (*LimaVzDriver)(nil)
8282

83-
func New(inst *store.Instance, sshLocalPort int) *LimaVzDriver {
83+
func New() *LimaVzDriver {
8484
return &LimaVzDriver{
85-
Instance: inst,
86-
vSockPort: 2222,
87-
virtioPort: "",
88-
SSHLocalPort: sshLocalPort,
85+
vSockPort: 2222,
86+
virtioPort: "",
87+
}
88+
}
89+
90+
func (l *LimaVzDriver) Configure(inst *store.Instance, sshLocalPort int) *driver.ConfiguredDriver {
91+
l.Instance = inst
92+
l.SSHLocalPort = sshLocalPort
93+
94+
return &driver.ConfiguredDriver{
95+
Driver: l,
8996
}
9097
}
9198

@@ -197,7 +204,7 @@ func (l *LimaVzDriver) Start(ctx context.Context) (chan error, error) {
197204
return errCh, nil
198205
}
199206

200-
func (l *LimaVzDriver) CanRunGUI() bool {
207+
func (l *LimaVzDriver) canRunGUI() bool {
201208
switch *l.Instance.Config.Video.Display {
202209
case "vz", "default":
203210
return true
@@ -207,7 +214,7 @@ func (l *LimaVzDriver) CanRunGUI() bool {
207214
}
208215

209216
func (l *LimaVzDriver) RunGUI() error {
210-
if l.CanRunGUI() {
217+
if l.canRunGUI() {
211218
return l.machine.StartGraphicApplication(1920, 1200)
212219
}
213220
return fmt.Errorf("RunGUI is not supported for the given driver '%s' and display '%s'", "vz", *l.Instance.Config.Video.Display)
@@ -243,14 +250,28 @@ func (l *LimaVzDriver) Stop(_ context.Context) error {
243250
return errors.New("vz: CanRequestStop is not supported")
244251
}
245252

246-
func (l *LimaVzDriver) GuestAgentConn(_ context.Context) (net.Conn, error) {
253+
func (l *LimaVzDriver) GuestAgentConn(_ context.Context) (net.Conn, string, error) {
247254
for _, socket := range l.machine.SocketDevices() {
248255
connect, err := socket.Connect(uint32(l.vSockPort))
249-
if err == nil && connect.SourcePort() != 0 {
250-
return connect, nil
251-
}
256+
return connect, "vsock", err
252257
}
253-
return nil, errors.New("unable to connect to guest agent via vsock port 2222")
258+
259+
return nil, "", errors.New("unable to connect to guest agent via vsock port 2222")
260+
}
261+
262+
func (l *LimaVzDriver) Info() driver.Info {
263+
var info driver.Info
264+
if l.Instance != nil {
265+
info.CanRunGUI = l.canRunGUI()
266+
}
267+
268+
info.DriverName = "vz"
269+
info.VsockPort = l.vSockPort
270+
info.VirtioPort = l.virtioPort
271+
if l.Instance != nil {
272+
info.InstanceDir = l.Instance.Dir
273+
}
274+
return info
254275
}
255276

256277
func (l *LimaVzDriver) Register(_ context.Context) error {
@@ -265,35 +286,27 @@ func (l *LimaVzDriver) ChangeDisplayPassword(_ context.Context, _ string) error
265286
return nil
266287
}
267288

268-
func (l *LimaVzDriver) GetDisplayConnection(_ context.Context) (string, error) {
289+
func (l *LimaVzDriver) DisplayConnection(_ context.Context) (string, error) {
269290
return "", nil
270291
}
271292

272293
func (l *LimaVzDriver) CreateSnapshot(_ context.Context, _ string) error {
273-
return errors.New("unimplemented")
294+
return errUnimplemented
274295
}
275296

276297
func (l *LimaVzDriver) ApplySnapshot(_ context.Context, _ string) error {
277-
return errors.New("unimplemented")
298+
return errUnimplemented
278299
}
279300

280301
func (l *LimaVzDriver) DeleteSnapshot(_ context.Context, _ string) error {
281-
return errors.New("unimplemented")
302+
return errUnimplemented
282303
}
283304

284305
func (l *LimaVzDriver) ListSnapshots(_ context.Context) (string, error) {
285-
return "", errors.New("unimplemented")
306+
return "", errUnimplemented
286307
}
287308

288309
func (l *LimaVzDriver) ForwardGuestAgent() bool {
289310
// If driver is not providing, use host agent
290311
return l.vSockPort == 0 && l.virtioPort == ""
291312
}
292-
293-
func (l *LimaVzDriver) VSockPort() int {
294-
return l.vSockPort
295-
}
296-
297-
func (l *LimaVzDriver) VirtioPort() string {
298-
return l.virtioPort
299-
}

0 commit comments

Comments
 (0)