Skip to content
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

Add --extra-disks capability to kvm2 driver #12351

Merged
merged 1 commit into from
Aug 30, 2021
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
4 changes: 2 additions & 2 deletions cmd/minikube/cmd/start_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func initMinikubeFlags() {
startCmd.Flags().StringP(network, "", "", "network to run minikube with. Now it is used by docker/podman and KVM drivers. If left empty, minikube will create a new network.")
startCmd.Flags().StringVarP(&outputFormat, "output", "o", "text", "Format to print stdout in. Options include: [text,json]")
startCmd.Flags().StringP(trace, "", "", "Send trace events. Options include: [gcp]")
startCmd.Flags().Int(extraDisks, 0, "Number of extra disks created and attached to the minikube VM (currently only implemented for hyperkit driver)")
startCmd.Flags().Int(extraDisks, 0, "Number of extra disks created and attached to the minikube VM (currently only implemented for hyperkit and kvm2 drivers)")
}

// initKubernetesFlags inits the commandline flags for Kubernetes related options
Expand Down Expand Up @@ -730,7 +730,7 @@ func interpretWaitFlag(cmd cobra.Command) map[string]bool {
}

func checkExtraDiskOptions(cmd *cobra.Command, driverName string) {
supportedDrivers := []string{driver.HyperKit}
supportedDrivers := []string{driver.HyperKit, driver.KVM2}

if cmd.Flags().Changed(extraDisks) {
supported := false
Expand Down
80 changes: 80 additions & 0 deletions pkg/drivers/kvm/disks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// +build linux

/*
Copyright 2018 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kvm

import (
"bytes"
"fmt"
"os"
"text/template"

"github.com/docker/machine/libmachine/log"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/drivers"
"k8s.io/minikube/pkg/util"
)

// extraDisksTmpl ExtraDisks XML Template
const extraDisksTmpl = `
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='default' io='threads' />
<source file='{{.DiskPath}}'/>
<target dev='{{.DiskLogicalName}}' bus='virtio'/>
</disk>
`

// ExtraDisks holds the extra disks configuration
type ExtraDisks struct {
DiskPath string
DiskLogicalName string
}

// getExtraDiskXML returns the XML that can be added to the libvirt domain XML
// for additional disks
func getExtraDiskXML(diskpath string, logicalName string) (string, error) {
var extraDisk ExtraDisks
extraDisk.DiskLogicalName = logicalName
extraDisk.DiskPath = diskpath
tmpl := template.Must(template.New("").Parse(extraDisksTmpl))
var extraDisksXML bytes.Buffer
if err := tmpl.Execute(&extraDisksXML, extraDisk); err != nil {
return "", fmt.Errorf("couldn't generate extra disks XML: %v", err)
}
return extraDisksXML.String(), nil
}

// createExtraDisks creates the extra disk files
func createExtraDisk(d *Driver, index int) (string, error) {
diskPath := drivers.ExtraDiskPath(d.BaseDriver, index)
log.Infof("Creating raw disk image: %s of size %v", diskPath, d.DiskSize)

if _, err := os.Stat(diskPath); os.IsNotExist(err) {
file, err := os.OpenFile(diskPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
if err != nil {
return "", errors.Wrap(err, "open")
}
defer file.Close()

if err := file.Truncate(util.ConvertMBToBytes(d.DiskSize)); err != nil {
return "", errors.Wrap(err, "truncate")
}
}
return diskPath, nil

}
3 changes: 3 additions & 0 deletions pkg/drivers/kvm/domain_definition_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ const domainTmpl = `
{{if .GPU}}
{{.DevicesXML}}
{{end}}
{{if gt .ExtraDisks 0}}
{{.ExtraDisksXML}}
{{end}}
</devices>
</domain>
`
3 changes: 3 additions & 0 deletions pkg/drivers/kvm/domain_definition_x86.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ const domainTmpl = `
{{if .GPU}}
{{.DevicesXML}}
{{end}}
{{if gt .ExtraDisks 0}}
{{.ExtraDisksXML}}
{{end}}
</devices>
</domain>
`
26 changes: 26 additions & 0 deletions pkg/drivers/kvm/kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ type Driver struct {

// NUMA XML
NUMANodeXML string

// Extra Disks
ExtraDisks int

// Extra Disks XML
ExtraDisksXML []string
}

const (
Expand Down Expand Up @@ -352,6 +358,26 @@ func (d *Driver) Create() (err error) {
return errors.Wrap(err, "error creating disk")
}

if d.ExtraDisks > 20 {
// Limiting the number of disks to 20 arbitrarily. If more disks are
// needed, the logical name generation has to changed to create them if
// the form hdaa, hdab, etc
return errors.Wrap(err, "cannot create more than 20 extra disks")
}
for i := 0; i < d.ExtraDisks; i++ {
diskpath, err := createExtraDisk(d, i)
if err != nil {
return errors.Wrap(err, "creating extra disks")
}
// Starting the logical names for the extra disks from hdd as the cdrom device is set to hdc.
// TODO: Enhance the domain template to use variable for the logical name of the main disk and the cdrom disk.
extraDisksXML, err := getExtraDiskXML(diskpath, fmt.Sprintf("hd%v", string(rune('d'+i))))
if err != nil {
return errors.Wrap(err, "creating extraDisk XML")
}
d.ExtraDisksXML = append(d.ExtraDisksXML, extraDisksXML)
}

if err := ensureDirPermissions(store); err != nil {
log.Errorf("unable to ensure permissions on %s: %v", store, err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type ClusterConfig struct {
ListenAddress string // Only used by the docker and podman driver
Network string // only used by docker driver
MultiNodeRequested bool
ExtraDisks int // currently only implemented for hyperkit
ExtraDisks int // currently only implemented for hyperkit and kvm2
}

// KubernetesConfig contains the parameters used to configure the VM Kubernetes.
Expand Down
2 changes: 2 additions & 0 deletions pkg/minikube/registry/drvs/kvm2/kvm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type kvmDriver struct {
Hidden bool
ConnectionURI string
NUMANodeCount int
ExtraDisks int
}

func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
Expand All @@ -92,6 +93,7 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
Hidden: cc.KVMHidden,
ConnectionURI: cc.KVMQemuURI,
NUMANodeCount: cc.KVMNUMACount,
ExtraDisks: cc.ExtraDisks,
}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion site/content/en/docs/commands/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ minikube start [flags]
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
Valid components are: kubelet, kubeadm, apiserver, controller-manager, etcd, proxy, scheduler
Valid kubeadm parameters: ignore-preflight-errors, dry-run, kubeconfig, kubeconfig-dir, node-name, cri-socket, experimental-upload-certs, certificate-key, rootfs, skip-phases, pod-network-cidr
--extra-disks int Number of extra disks created and attached to the minikube VM (currently only implemented for hyperkit driver)
--extra-disks int Number of extra disks created and attached to the minikube VM (currently only implemented for hyperkit and kvm2 drivers)
--feature-gates string A set of key=value pairs that describe feature gates for alpha/experimental features.
--force Force minikube to perform possibly dangerous operations
--force-systemd If set, force the container runtime to use systemd as cgroup manager. Defaults to false.
Expand Down