Skip to content

Commit 68a19a3

Browse files
committed
chore: remove qemu kvm requirement
If KVM is not available, log a warning and proceed without it (instead of a hard error). This is useful for people who's machine doesn't support KVM. Signed-off-by: Orzelius <33936483+Orzelius@users.noreply.github.com>
1 parent 557faad commit 68a19a3

File tree

7 files changed

+56
-33
lines changed

7 files changed

+56
-33
lines changed

pkg/provision/options.go

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ type Options struct {
220220
JSONLogsEndpoint string
221221

222222
SiderolinkEnabled bool
223+
UseKvm bool
223224
}
224225

225226
// DefaultOptions returns default options.

pkg/provision/providers/factory.go

+24-4
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,34 @@ import (
1212
"github.com/siderolabs/talos/pkg/provision/providers/docker"
1313
)
1414

15+
const (
16+
// QemuProviderName is the name of the qemu provider.
17+
QemuProviderName = "qemu"
18+
// DockerProviderName is the name of the docker provider.
19+
DockerProviderName = "docker"
20+
)
21+
1522
// Factory instantiates provision provider by name.
1623
func Factory(ctx context.Context, name string) (provision.Provisioner, error) {
24+
if err := IsValidProvider(name); err != nil {
25+
return nil, err
26+
}
27+
1728
switch name {
18-
case "docker":
29+
case DockerProviderName:
1930
return docker.NewProvisioner(ctx)
20-
case "qemu":
31+
case QemuProviderName:
2132
return newQemu(ctx)
22-
default:
23-
return nil, fmt.Errorf("unsupported provisioner %q", name)
2433
}
34+
35+
return nil, nil
36+
}
37+
38+
// IsValidProvider returns an error if the passed provider doesn't exist.
39+
func IsValidProvider(name string) error {
40+
if name != QemuProviderName && name != DockerProviderName {
41+
return fmt.Errorf("unsupported provisioner %q", name)
42+
}
43+
44+
return nil
2545
}

pkg/provision/providers/qemu/arch.go

+9-17
Original file line numberDiff line numberDiff line change
@@ -237,27 +237,19 @@ func (arch Arch) TPMDeviceArgs(socketPath string) []string {
237237
}
238238

239239
// KVMArgs returns arguments for qemu to enable KVM.
240-
func (arch Arch) KVMArgs(kvmEnabled bool, iommu bool) []string {
241-
if !kvmEnabled {
242-
return []string{"-machine", arch.QemuMachine()}
240+
func (arch Arch) getMachineArgs(kvmEnabled bool, iommu bool) []string {
241+
args := []string{"-machine", arch.QemuMachine()}
242+
if kvmEnabled {
243+
args = append(args, ",accel=kvm")
243244
}
244-
245-
machineArg := arch.QemuMachine() + ",accel=kvm"
246-
247245
// ref: https://wiki.qemu.org/Features/VT-d
248246
if iommu {
249-
machineArg += ",kernel-irqchip=split"
247+
args = append(args, ",kernel-irqchip=split")
250248
}
251249

252-
switch arch {
253-
case ArchAmd64:
254-
machineArg += ",smm=on"
255-
256-
return []string{"-machine", machineArg}
257-
case ArchArm64:
258-
// smm is not supported on aarch64
259-
return []string{"-machine", machineArg}
260-
default:
261-
panic("unsupported architecture")
250+
if arch == ArchAmd64 {
251+
args = append(args, ",smm=on")
262252
}
253+
254+
return args
263255
}

pkg/provision/providers/qemu/create.go

+20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package qemu
77
import (
88
"context"
99
"fmt"
10+
"os"
1011
"path/filepath"
1112

1213
"github.com/siderolabs/talos/pkg/machinery/constants"
@@ -26,6 +27,16 @@ func (p *provisioner) Create(ctx context.Context, request provision.ClusterReque
2627
}
2728
}
2829

30+
kvmErr := checkKVM()
31+
if kvmErr != nil {
32+
fmt.Println(kvmErr)
33+
fmt.Println("running without KVM")
34+
35+
options.UseKvm = false
36+
} else {
37+
options.UseKvm = true
38+
}
39+
2940
arch := Arch(options.TargetArch)
3041
if !arch.Valid() {
3142
return nil, fmt.Errorf("unsupported arch: %q", options.TargetArch)
@@ -148,3 +159,12 @@ func (p *provisioner) Create(ctx context.Context, request provision.ClusterReque
148159

149160
return state, nil
150161
}
162+
163+
func checkKVM() error {
164+
f, err := os.OpenFile("/dev/kvm", os.O_RDWR, 0)
165+
if err != nil {
166+
return fmt.Errorf("error opening /dev/kvm, please make sure KVM support is enabled in Linux kernel: %w", err)
167+
}
168+
169+
return f.Close()
170+
}

pkg/provision/providers/qemu/launch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ func launchVM(config *LaunchConfig) error {
393393
}
394394
}
395395

396-
args = append(args, config.ArchitectureData.KVMArgs(config.EnableKVM, config.IOMMUEnabled)...)
396+
args = append(args, config.ArchitectureData.getMachineArgs(config.EnableKVM, config.IOMMUEnabled)...)
397397

398398
pflashArgs := make([]string, 2*len(config.PFlashImages))
399399
for i := range config.PFlashImages {

pkg/provision/providers/qemu/node.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe
169169
ExtraISOPath: extraISOPath,
170170
PFlashImages: pflashImages,
171171
MonitorPath: state.GetRelativePath(fmt.Sprintf("%s.monitor", nodeReq.Name)),
172-
EnableKVM: opts.TargetArch == runtime.GOARCH,
172+
EnableKVM: opts.TargetArch == runtime.GOARCH && opts.UseKvm,
173173
BadRTC: nodeReq.BadRTC,
174174
DefaultBootOrder: defaultBootOrder,
175175
BootloaderEnabled: opts.BootloaderEnabled,

pkg/provision/providers/qemu/preflight.go

-10
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ func (p *provisioner) preflightChecks(ctx context.Context, request provision.Clu
3131

3232
for _, check := range []func(ctx context.Context) error{
3333
checkContext.verifyRoot,
34-
checkContext.checkKVM,
3534
checkContext.qemuExecutable,
3635
checkContext.checkFlashImages,
3736
checkContext.swtpmExecutable,
@@ -61,15 +60,6 @@ func (check *preflightCheckContext) verifyRoot(context.Context) error {
6160
return nil
6261
}
6362

64-
func (check *preflightCheckContext) checkKVM(context.Context) error {
65-
f, err := os.OpenFile("/dev/kvm", os.O_RDWR, 0)
66-
if err != nil {
67-
return fmt.Errorf("error opening /dev/kvm, please make sure KVM support is enabled in Linux kernel: %w", err)
68-
}
69-
70-
return f.Close()
71-
}
72-
7363
func (check *preflightCheckContext) qemuExecutable(context.Context) error {
7464
if check.arch.QemuExecutable() == "" {
7565
return fmt.Errorf("QEMU executable (qemu-system-%s or qemu-kvm) not found, please install QEMU with package manager", check.arch.QemuArch())

0 commit comments

Comments
 (0)