From 27d771e0fe355f54079bde5566c56143b027431a Mon Sep 17 00:00:00 2001 From: Orzelius <33936483+Orzelius@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:55:04 +0900 Subject: [PATCH] feat: add with-kvm flag to the create cluster command Allow enabling or disabling kvm via the cli. This is useful for testing in/for environments where kvm is not available. Signed-off-by: Orzelius <33936483+Orzelius@users.noreply.github.com> --- cmd/talosctl/cmd/mgmt/cluster/create.go | 3 +++ pkg/provision/options.go | 10 ++++++++++ pkg/provision/providers/qemu/arch.go | 9 ++++++--- pkg/provision/providers/qemu/launch.go | 4 ++-- pkg/provision/providers/qemu/node.go | 2 +- pkg/provision/providers/qemu/preflight.go | 4 ++-- website/content/v1.9/reference/cli.md | 1 + .../v1.9/talos-guides/install/local-platforms/qemu.md | 4 ++-- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/cmd/talosctl/cmd/mgmt/cluster/create.go b/cmd/talosctl/cmd/mgmt/cluster/create.go index 92f608331c..ecf9ce7c18 100644 --- a/cmd/talosctl/cmd/mgmt/cluster/create.go +++ b/cmd/talosctl/cmd/mgmt/cluster/create.go @@ -124,6 +124,7 @@ var ( applyConfigEnabled bool bootloaderEnabled bool uefiEnabled bool + kvmEnabled bool tpm2Enabled bool extraUEFISearchPaths []string configDebug bool @@ -475,6 +476,7 @@ func create(ctx context.Context) error { provision.WithBootlader(bootloaderEnabled), provision.WithUEFI(uefiEnabled), provision.WithTPM2(tpm2Enabled), + provision.WithKvm(kvmEnabled), provision.WithDebugShell(debugShellEnabled), provision.WithExtraUEFISearchPaths(extraUEFISearchPaths), provision.WithTargetArch(targetArch), @@ -1248,6 +1250,7 @@ func init() { createCmd.Flags().BoolVar(&applyConfigEnabled, "with-apply-config", false, "enable apply config when the VM is starting in maintenance mode") createCmd.Flags().BoolVar(&bootloaderEnabled, bootloaderEnabledFlag, true, "enable bootloader to load kernel and initramfs from disk image after install") createCmd.Flags().BoolVar(&uefiEnabled, "with-uefi", true, "enable UEFI on x86_64 architecture") + createCmd.Flags().BoolVar(&kvmEnabled, "with-kvm", true, "enable kvm (QEMU provisioner only)") createCmd.Flags().BoolVar(&tpm2Enabled, tpm2EnabledFlag, false, "enable TPM2 emulation support using swtpm") createCmd.Flags().BoolVar(&debugShellEnabled, withDebugShellFlag, false, "drop talos into a maintenance shell on boot, this is for advanced debugging for developers only") createCmd.Flags().MarkHidden("with-debug-shell") //nolint:errcheck diff --git a/pkg/provision/options.go b/pkg/provision/options.go index 31893fa6d7..a92b6b4003 100644 --- a/pkg/provision/options.go +++ b/pkg/provision/options.go @@ -79,6 +79,15 @@ func WithTPM2(enabled bool) Option { } } +// WithKvm enables or disables KVM with qemu. +func WithKvm(enabled bool) Option { + return func(o *Options) error { + o.KvmEnabled = enabled + + return nil + } +} + // WithDebugShell drops into debug shell in initramfs. func WithDebugShell(enabled bool) Option { return func(o *Options) error { @@ -199,6 +208,7 @@ type Options struct { JSONLogsEndpoint string SiderolinkEnabled bool + KvmEnabled bool } // DefaultOptions returns default options. diff --git a/pkg/provision/providers/qemu/arch.go b/pkg/provision/providers/qemu/arch.go index 3eb95a2f6f..ea95ea139a 100644 --- a/pkg/provision/providers/qemu/arch.go +++ b/pkg/provision/providers/qemu/arch.go @@ -200,11 +200,14 @@ func generateUEFIPFlashList(uefiSourcePathPrefixes, uefiSourceFiles, uefiVarsFil } // QemuExecutable returns name of qemu executable for the arch. -func (arch Arch) QemuExecutable() string { +func (arch Arch) QemuExecutable(kvmEnabled bool) string { binaries := []string{ "qemu-system-" + arch.QemuArch(), - "qemu-kvm", - "/usr/libexec/qemu-kvm", + } + if kvmEnabled { + binaries = append(binaries, + "qemu-kvm", + "/usr/libexec/qemu-kvm") } for _, binary := range binaries { diff --git a/pkg/provision/providers/qemu/launch.go b/pkg/provision/providers/qemu/launch.go index efe9aa0554..72e6672e83 100644 --- a/pkg/provision/providers/qemu/launch.go +++ b/pkg/provision/providers/qemu/launch.go @@ -455,9 +455,9 @@ func launchVM(config *LaunchConfig) error { ) } - fmt.Fprintf(os.Stderr, "starting %s with args:\n%s\n", config.ArchitectureData.QemuExecutable(), strings.Join(args, " ")) + fmt.Fprintf(os.Stderr, "starting %s with args:\n%s\n", config.ArchitectureData.QemuExecutable(config.EnableKVM), strings.Join(args, " ")) cmd := exec.Command( - config.ArchitectureData.QemuExecutable(), + config.ArchitectureData.QemuExecutable(config.EnableKVM), args..., ) diff --git a/pkg/provision/providers/qemu/node.go b/pkg/provision/providers/qemu/node.go index 75493376b1..fcca8371f9 100644 --- a/pkg/provision/providers/qemu/node.go +++ b/pkg/provision/providers/qemu/node.go @@ -165,7 +165,7 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe ExtraISOPath: extraISOPath, PFlashImages: pflashImages, MonitorPath: state.GetRelativePath(fmt.Sprintf("%s.monitor", nodeReq.Name)), - EnableKVM: opts.TargetArch == runtime.GOARCH, + EnableKVM: opts.TargetArch == runtime.GOARCH && opts.KvmEnabled, BadRTC: nodeReq.BadRTC, DefaultBootOrder: defaultBootOrder, BootloaderEnabled: opts.BootloaderEnabled, diff --git a/pkg/provision/providers/qemu/preflight.go b/pkg/provision/providers/qemu/preflight.go index 4c6fddac93..a55c97be71 100644 --- a/pkg/provision/providers/qemu/preflight.go +++ b/pkg/provision/providers/qemu/preflight.go @@ -64,14 +64,14 @@ func (check *preflightCheckContext) verifyRoot(context.Context) error { func (check *preflightCheckContext) checkKVM(context.Context) error { f, err := os.OpenFile("/dev/kvm", os.O_RDWR, 0) if err != nil { - return fmt.Errorf("error opening /dev/kvm, please make sure KVM support is enabled in Linux kernel: %w", err) + return fmt.Errorf("error opening /dev/kvm, please make sure KVM support is enabled in Linux kernel: %w\nOr disable kvm with --with-kvm=false", err) } return f.Close() } func (check *preflightCheckContext) qemuExecutable(context.Context) error { - if check.arch.QemuExecutable() == "" { + if check.arch.QemuExecutable(check.options.KvmEnabled) == "" { return fmt.Errorf("QEMU executable (qemu-system-%s or qemu-kvm) not found, please install QEMU with package manager", check.arch.QemuArch()) } diff --git a/website/content/v1.9/reference/cli.md b/website/content/v1.9/reference/cli.md index 48c39584cb..bb1a08ee81 100644 --- a/website/content/v1.9/reference/cli.md +++ b/website/content/v1.9/reference/cli.md @@ -213,6 +213,7 @@ talosctl cluster create [flags] --with-init-node create the cluster with an init node --with-json-logs enable JSON logs receiver and configure Talos to send logs there --with-kubespan enable KubeSpan system + --with-kvm enable kvm (QEMU provisioner only) (default true) --with-network-bandwidth int specify bandwidth restriction (in kbps) on the bridge interface when creating a qemu cluster --with-network-chaos enable to use network chaos parameters when creating a qemu cluster --with-network-jitter duration specify jitter on the bridge interface when creating a qemu cluster diff --git a/website/content/v1.9/talos-guides/install/local-platforms/qemu.md b/website/content/v1.9/talos-guides/install/local-platforms/qemu.md index dd39af069b..89ab086e7f 100644 --- a/website/content/v1.9/talos-guides/install/local-platforms/qemu.md +++ b/website/content/v1.9/talos-guides/install/local-platforms/qemu.md @@ -19,9 +19,9 @@ To see a live demo of this writeup, see the video below: - Linux - a kernel with - - KVM enabled (`/dev/kvm` must exist) - `CONFIG_NET_SCH_NETEM` enabled - `CONFIG_NET_SCH_INGRESS` enabled + - KVM enabled (`/dev/kvm` must exist) if you wish to use KVM - at least `CAP_SYS_ADMIN` and `CAP_NET_ADMIN` capabilities - QEMU - `bridge`, `static` and `firewall` CNI plugins from the [standard CNI plugins](https://github.com/containernetworking/cni), and `tc-redirect-tap` CNI plugin from the [awslabs tc-redirect-tap](https://github.com/awslabs/tc-redirect-tap) installed to `/opt/cni/bin` (installed automatically by `talosctl`) @@ -33,7 +33,7 @@ To see a live demo of this writeup, see the video below: ### How to get QEMU Install QEMU with your operating system package manager. -For example, on Ubuntu for x86: +For example, on Ubuntu for x86 with kvm: ```bash apt install qemu-system-x86 qemu-kvm