Skip to content

Commit 1f56101

Browse files
committed
kvm: Build kvm driver only for linux/amd64
The build fails on linux/arm64 because libvirt.org/go/libvirt is using CGO, and cross compiling CGO requires a C cross compiler. Setting GOARCH=arm64 is not enough. The issue is tracked in #19959. Previously we built the kvm driver also on arm64 as part of the docker-machine-driver-kvm2 executable, but the build was skipped on arm64. Now that we build the driver as part of minikube, we cannot skip the entire build. Change the build tag so the libvirt bits are built only on amd64. To make this possible, the generic linux bits needed by the registry moved to pkg/drivers/kvm/driver.go, and a kvm_stub.go is used for unsupported architectures. In the registry Driver.Status(), move the arm64 check to front since there is no point in checking that libvirt is installed correctly if the driver is not supported yet.
1 parent 8e37ca8 commit 1f56101

File tree

6 files changed

+178
-97
lines changed

6 files changed

+178
-97
lines changed

pkg/drivers/kvm/domain.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build linux
1+
//go:build linux && amd64
22

33
/*
44
Copyright 2016 The Kubernetes Authors All rights reserved.

pkg/drivers/kvm/driver.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//go:build linux
2+
3+
/*
4+
Copyright 2025 The Kubernetes Authors All rights reserved.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package kvm
20+
21+
import (
22+
"github.com/docker/machine/libmachine/drivers"
23+
"k8s.io/minikube/pkg/drivers/common"
24+
)
25+
26+
const (
27+
qemusystem = "qemu:///system"
28+
defaultPrivateNetworkName = "minikube-net"
29+
defaultNetworkName = "default"
30+
)
31+
32+
// Driver is the machine driver for KVM
33+
type Driver struct {
34+
*drivers.BaseDriver
35+
*common.CommonDriver
36+
37+
// How much memory, in MB, to allocate to the VM
38+
Memory int
39+
40+
// How many cpus to allocate to the VM
41+
CPU int
42+
43+
// The name of the default network
44+
Network string
45+
46+
// The name of the private network
47+
PrivateNetwork string
48+
49+
// The size of the disk to be created for the VM, in MB
50+
DiskSize int
51+
52+
// The path of the disk .img
53+
DiskPath string
54+
55+
// A file or network URI to fetch the minikube ISO
56+
Boot2DockerURL string
57+
58+
// The location of the iso to boot from
59+
ISO string
60+
61+
// The randomly generated MAC Address
62+
// If empty, a random MAC will be generated.
63+
MAC string
64+
65+
// The randomly generated MAC Address for the NIC attached to the private network
66+
// If empty, a random MAC will be generated.
67+
PrivateMAC string
68+
69+
// Whether to passthrough GPU devices from the host to the VM.
70+
GPU bool
71+
72+
// Whether to hide the KVM hypervisor signature from the guest
73+
Hidden bool
74+
75+
// XML that needs to be added to passthrough GPU devices.
76+
DevicesXML string
77+
78+
// QEMU Connection URI
79+
ConnectionURI string
80+
81+
// NUMA node count default value is 1
82+
NUMANodeCount int
83+
84+
// NUMA XML
85+
NUMANodeXML string
86+
87+
// Extra Disks
88+
ExtraDisks int
89+
90+
// Extra Disks XML
91+
ExtraDisksXML []string
92+
}
93+
94+
// NewDriver creates a new driver for a host
95+
func NewDriver(hostName, storePath string) *Driver {
96+
return &Driver{
97+
BaseDriver: &drivers.BaseDriver{
98+
MachineName: hostName,
99+
StorePath: storePath,
100+
SSHUser: "docker",
101+
},
102+
CommonDriver: &common.CommonDriver{},
103+
PrivateNetwork: defaultPrivateNetworkName,
104+
Network: defaultNetworkName,
105+
ConnectionURI: qemusystem,
106+
}
107+
}

pkg/drivers/kvm/kvm.go

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build linux
1+
//go:build linux && amd64
22

33
/*
44
Copyright 2016 The Kubernetes Authors All rights reserved.
@@ -34,89 +34,6 @@ import (
3434
"libvirt.org/go/libvirt"
3535
)
3636

37-
// Driver is the machine driver for KVM
38-
type Driver struct {
39-
*drivers.BaseDriver
40-
*common.CommonDriver
41-
42-
// How much memory, in MB, to allocate to the VM
43-
Memory int
44-
45-
// How many cpus to allocate to the VM
46-
CPU int
47-
48-
// The name of the default network
49-
Network string
50-
51-
// The name of the private network
52-
PrivateNetwork string
53-
54-
// The size of the disk to be created for the VM, in MB
55-
DiskSize int
56-
57-
// The path of the disk .img
58-
DiskPath string
59-
60-
// A file or network URI to fetch the minikube ISO
61-
Boot2DockerURL string
62-
63-
// The location of the iso to boot from
64-
ISO string
65-
66-
// The randomly generated MAC Address
67-
// If empty, a random MAC will be generated.
68-
MAC string
69-
70-
// The randomly generated MAC Address for the NIC attached to the private network
71-
// If empty, a random MAC will be generated.
72-
PrivateMAC string
73-
74-
// Whether to passthrough GPU devices from the host to the VM.
75-
GPU bool
76-
77-
// Whether to hide the KVM hypervisor signature from the guest
78-
Hidden bool
79-
80-
// XML that needs to be added to passthrough GPU devices.
81-
DevicesXML string
82-
83-
// QEMU Connection URI
84-
ConnectionURI string
85-
86-
// NUMA node count default value is 1
87-
NUMANodeCount int
88-
89-
// NUMA XML
90-
NUMANodeXML string
91-
92-
// Extra Disks
93-
ExtraDisks int
94-
95-
// Extra Disks XML
96-
ExtraDisksXML []string
97-
}
98-
99-
const (
100-
qemusystem = "qemu:///system"
101-
defaultPrivateNetworkName = "minikube-net"
102-
defaultNetworkName = "default"
103-
)
104-
105-
// NewDriver creates a new driver for a host
106-
func NewDriver(hostName, storePath string) *Driver {
107-
return &Driver{
108-
BaseDriver: &drivers.BaseDriver{
109-
MachineName: hostName,
110-
StorePath: storePath,
111-
SSHUser: "docker",
112-
},
113-
CommonDriver: &common.CommonDriver{},
114-
PrivateNetwork: defaultPrivateNetworkName,
115-
Network: defaultNetworkName,
116-
ConnectionURI: qemusystem,
117-
}
118-
}
119-
12037
// GetURL returns a Docker URL inside this host
12138
// e.g. tcp://1.2.3.4:2376
12239
// more info https://github.com/docker/machine/blob/b170508bf44c3405e079e26d5fdffe35a64c6972/libmachine/provision/utils.go#L159_L175

pkg/drivers/kvm/kvm_stub.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//go:build linux && !amd64
2+
3+
/*
4+
Copyright 2016 The Kubernetes Authors All rights reserved.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package kvm
20+
21+
import (
22+
"fmt"
23+
"runtime"
24+
25+
"github.com/docker/machine/libmachine/drivers"
26+
"github.com/docker/machine/libmachine/mcnflag"
27+
"github.com/docker/machine/libmachine/state"
28+
)
29+
30+
// This is a stub driver for unsupported architectures. All function fail with
31+
// notSupported error or return an zero value.
32+
33+
var notSupported = fmt.Errorf("the kvm driver is not supported on %q", runtime.GOARCH)
34+
35+
func (d *Driver) Create() error { return notSupported }
36+
func (d *Driver) GetCreateFlags() []mcnflag.Flag { return nil }
37+
func (d *Driver) GetIP() (string, error) { return "", notSupported }
38+
func (d *Driver) GetMachineName() string { return "" }
39+
func (d *Driver) GetSSHHostname() (string, error) { return "", notSupported }
40+
func (d *Driver) GetSSHKeyPath() string { return "" }
41+
func (d *Driver) GetSSHPort() (int, error) { return 0, notSupported }
42+
func (d *Driver) GetSSHUsername() string { return "" }
43+
func (d *Driver) GetURL() (string, error) { return "", notSupported }
44+
func (d *Driver) GetState() (state.State, error) { return state.None, notSupported }
45+
func (d *Driver) Kill() error { return notSupported }
46+
func (d *Driver) PreCreateCheck() error { return notSupported }
47+
func (d *Driver) Remove() error { return notSupported }
48+
func (d *Driver) Restart() error { return notSupported }
49+
func (d *Driver) SetConfigFromFlags(opts drivers.DriverOptions) error { return notSupported }
50+
func (d *Driver) Start() error { return notSupported }
51+
func (d *Driver) Stop() error { return notSupported }

pkg/drivers/kvm/network.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build linux
1+
//go:build linux && amd64
22

33
/*
44
Copyright 2016 The Kubernetes Authors All rights reserved.

pkg/minikube/registry/drvs/kvm2/kvm2.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os/user"
2727
"path/filepath"
2828
"runtime"
29+
"slices"
2930
"strings"
3031
"time"
3132

@@ -43,6 +44,10 @@ const (
4344
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/kvm2/"
4445
)
4546

47+
// The driver is implemented for amd64 and arm64, but we cannot build the arm64
48+
// version yet: https://github.com/kubernetes/minikube/issues/19959.
49+
var supportedArchictures = []string{"amd64"}
50+
4651
func init() {
4752
if err := registry.Register(registry.DriverDef{
4853
Name: driver.KVM2,
@@ -99,6 +104,18 @@ func defaultURI() string {
99104
}
100105

101106
func status() registry.State {
107+
if !slices.Contains(supportedArchictures, runtime.GOARCH) {
108+
rs := registry.State{
109+
Error: fmt.Errorf("KVM is not supported on %q, contributions are welcome", runtime.GOARCH),
110+
Fix: fmt.Sprintf("you can use the KVM driver on %s", strings.Join(supportedArchictures, ",")),
111+
}
112+
// The driver is implemented but we cannot build it yet.
113+
if runtime.GOARCH == "arm64" {
114+
rs.Doc = "https://github.com/kubernetes/minikube/issues/19959"
115+
}
116+
return rs
117+
}
118+
102119
// Allow no more than 6 seconds for querying state
103120
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
104121
defer cancel()
@@ -150,17 +167,6 @@ func status() registry.State {
150167
}
151168
}
152169

153-
if runtime.GOARCH == "arm64" {
154-
return registry.State{
155-
Installed: true,
156-
Running: true,
157-
Error: fmt.Errorf("KVM is not supported on arm64 due to a gcc build error, contributions are welcome"),
158-
Fix: "follow the github issue for possible fix",
159-
Doc: "https://github.com/kubernetes/minikube/issues/19959",
160-
}
161-
162-
}
163-
164170
if err != nil {
165171
return registry.State{
166172
Installed: true,

0 commit comments

Comments
 (0)