Skip to content

Feature: External driver plugin system and update Makefile #3694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -243,18 +243,48 @@ endif
# calls the native resolver library and not the simplistic version in the Go library.
ENVS__output/bin/limactl$(exe) = CGO_ENABLED=1 GOOS="$(GOOS)" GOARCH="$(GOARCH)" CC="$(CC)"

LIMACTL_DRIVER_TAGS :=
ifneq (,$(findstring vz,$(ADDITIONAL_DRIVERS)))
LIMACTL_DRIVER_TAGS += external_vz
endif
ifneq (,$(findstring qemu,$(ADDITIONAL_DRIVERS)))
LIMACTL_DRIVER_TAGS += external_qemu
endif
ifneq (,$(findstring wsl2,$(ADDITIONAL_DRIVERS)))
LIMACTL_DRIVER_TAGS += external_wsl2
endif

GO_BUILDTAGS ?=
GO_BUILDTAGS_LIMACTL := $(strip $(GO_BUILDTAGS) $(LIMACTL_DRIVER_TAGS))

_output/bin/limactl$(exe): $(LIMACTL_DEPS) $$(call force_build,$$@)
# If the previous cross-compilation was for GOOS=windows, limactl.exe might still be present.
ifneq ($(GOOS),windows) #
@rm -rf _output/bin/limactl.exe
else
@rm -rf _output/bin/limactl
endif
$(ENVS_$@) $(GO_BUILD) -o $@ ./cmd/limactl
$(ENVS_$@) $(GO_BUILD) -tags '$(GO_BUILDTAGS_LIMACTL)' -o $@ ./cmd/limactl
ifeq ($(GOOS),darwin)
codesign -f -v --entitlements vz.entitlements -s - $@
endif

DRIVER_INSTALL_DIR := _output/libexec/lima

.PHONY: additional-drivers
additional-drivers:
@mkdir -p $(DRIVER_INSTALL_DIR)
@for drv in $(ADDITIONAL_DRIVERS); do \
echo "Building $$drv as external"; \
if [ "$(GOOS)" = "windows" ]; then \
$(GO_BUILD) -o $(DRIVER_INSTALL_DIR)/lima-driver-$$drv.exe ./cmd/lima-driver-$$drv; \
else \
$(GO_BUILD) -o $(DRIVER_INSTALL_DIR)/lima-driver-$$drv ./cmd/lima-driver-$$drv; \
fi; \
if [ "$$drv" = "vz" ] && [ "$(GOOS)" = "darwin" ]; then \
codesign -f -v --entitlements vz.entitlements -s - $(DRIVER_INSTALL_DIR)/lima-driver-vz; \
fi; \
done

LIMA_CMDS = $(sort lima lima$(bat)) # $(sort ...) deduplicates the list
LIMA_DEPS = $(addprefix _output/bin/,$(LIMA_CMDS))
lima: $(LIMA_DEPS)
Expand Down
14 changes: 14 additions & 0 deletions cmd/lima-driver-qemu/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/lima-vm/lima/pkg/driver/external/server"
"github.com/lima-vm/lima/pkg/driver/qemu"
)

// To be used as an external driver for Lima.
func main() {
server.Serve(qemu.New())
}
14 changes: 14 additions & 0 deletions cmd/lima-driver-vz/main_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/lima-vm/lima/pkg/driver/external/server"
"github.com/lima-vm/lima/pkg/driver/vz"
)

// To be used as an external driver for Lima.
func main() {
server.Serve(vz.New())
}
14 changes: 14 additions & 0 deletions cmd/lima-driver-wsl2/main_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/lima-vm/lima/pkg/driver/external/server"
"github.com/lima-vm/lima/pkg/driver/wsl2"
)

// To be used as an external driver for Lima.
func main() {
server.Serve(wsl2.New())
}
3 changes: 3 additions & 0 deletions cmd/limactl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/spf13/cobra"

"github.com/lima-vm/lima/pkg/debugutil"
"github.com/lima-vm/lima/pkg/driver/external/server"
"github.com/lima-vm/lima/pkg/fsutil"
"github.com/lima-vm/lima/pkg/osutil"
"github.com/lima-vm/lima/pkg/store/dirnames"
Expand Down Expand Up @@ -43,6 +44,8 @@ func main() {
handleExitCoder(err)
logrus.Fatal(err)
}

server.StopAllExternalDrivers()
}

func newApp() *cobra.Command {
Expand Down
49 changes: 49 additions & 0 deletions pkg/driver/external/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package client

import (
"context"
"net"

"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

pb "github.com/lima-vm/lima/pkg/driver/external"
)

type DriverClient struct {
socketPath string
Conn *grpc.ClientConn
DriverSvc pb.DriverClient
logger *logrus.Logger
}

func NewDriverClient(socketPath string, logger *logrus.Logger) (*DriverClient, error) {
opts := []grpc.DialOption{
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(16 << 20)),
grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(16 << 20)),
grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) {
return net.Dial("unix", socketPath)
}),
grpc.WithTransportCredentials(insecure.NewCredentials()),
}

//nolint:staticcheck // grpc.Dial is used for compatibility reasons
conn, err := grpc.Dial("unix://"+socketPath, opts...)
if err != nil {
logger.Errorf("failed to dial gRPC driver client connection: %v", err)
return nil, err
}

driverSvc := pb.NewDriverClient(conn)

return &DriverClient{
socketPath: socketPath,
Conn: conn,
DriverSvc: driverSvc,
logger: logger,
}, nil
}
Loading