Skip to content

Commit

Permalink
Merge pull request #2159 from kubevirt/machine-type-across-cluster
Browse files Browse the repository at this point in the history
possibility to set machine type from kubevirt-config
  • Loading branch information
stu-gott committed Apr 5, 2019
2 parents 115b1f0 + d553693 commit ebe9902
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 11 deletions.
3 changes: 0 additions & 3 deletions pkg/api/v1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ func SetDefaults_VirtualMachineInstance(obj *VirtualMachineInstance) {
if obj.Spec.Domain.Features == nil {
obj.Spec.Domain.Features = &Features{}
}
if obj.Spec.Domain.Machine.Type == "" {
obj.Spec.Domain.Machine.Type = "q35"
}

setDefaults_Disk(obj)
SetDefaults_NetworkInterface(obj)
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/v1/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var exampleJSON = `{
"dedicatedCpuPlacement": true
},
"machine": {
"type": "q35"
"type": ""
},
"firmware": {
"uuid": "28a42a60-44ef-4428-9c10-1a6aee94627f"
Expand Down
1 change: 1 addition & 0 deletions pkg/virt-api/webhooks/mutating-webhook/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ go_library(
"//pkg/log:go_default_library",
"//pkg/util:go_default_library",
"//pkg/virt-api/webhooks:go_default_library",
"//pkg/virt-config:go_default_library",
"//vendor/k8s.io/api/admission/v1beta1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
Expand Down
10 changes: 10 additions & 0 deletions pkg/virt-api/webhooks/mutating-webhook/mutating-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ import (
kubev1 "kubevirt.io/kubevirt/pkg/api/v1"
v1 "kubevirt.io/kubevirt/pkg/api/v1"
"kubevirt.io/kubevirt/pkg/log"
"kubevirt.io/kubevirt/pkg/util"
"kubevirt.io/kubevirt/pkg/virt-api/webhooks"
virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
)

type patchOperation struct {
Expand Down Expand Up @@ -94,6 +96,11 @@ func mutateVMIs(ar *v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {
}

informers := webhooks.GetInformers()
namespace, err := util.GetNamespace()
if err != nil {
return webhooks.ToAdmissionResponseError(err)
}
config := virtconfig.NewClusterConfig(informers.ConfigMapInformer.GetStore(), namespace)

// Apply presets
err = applyPresets(&vmi, informers.VMIPresetInformer)
Expand All @@ -113,6 +120,9 @@ func mutateVMIs(ar *v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {

// Set VMI defaults
log.Log.Object(&vmi).V(4).Info("Apply defaults")
if vmi.Spec.Domain.Machine.Type == "" {
vmi.Spec.Domain.Machine.Type = config.GetMachineType()
}
kubev1.SetObjectDefaults_VirtualMachineInstance(&vmi)

// Add foreground finalizer
Expand Down
2 changes: 1 addition & 1 deletion pkg/virt-api/webhooks/mutating-webhook/preset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ var _ = Describe("Mutating Webhook Presets", func() {
Expect(vmi.Spec.Domain.CPU.Model).To(Equal(vmCPUModel))
})

It("Should has empty cpu model when cpu model is not set", func() {
It("Should have empty cpu model when cpu model is not set", func() {
cfgMap = k8sv1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: "kubevirt",
Expand Down
13 changes: 13 additions & 0 deletions pkg/virt-config/config-map.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
FeatureGatesKey = "feature-gates"
emulatedMachinesEnvVar = "VIRT_EMULATED_MACHINES"
emulatedMachinesKey = "emulated-machines"
machineTypeKey = "machine-type"
useEmulationKey = "debug.useEmulation"
imagePullPolicyKey = "dev.imagePullPolicy"
migrationsConfigKey = "migrations"
Expand All @@ -54,6 +55,7 @@ const (
BandwithPerMigrationDefault = "64Mi"
MigrationProgressTimeout int64 = 150
MigrationCompletionTimeoutPerGiB int64 = 800
DefaultMachineType = "q35"

NodeDrainTaintDefaultKey = "kubevirt.io/drain"
)
Expand Down Expand Up @@ -150,6 +152,7 @@ func defaultClusterConfig() *Config {
ProgressTimeout: &progressTimeout,
CompletionTimeoutPerGiB: &completionTimeoutPerGiB,
},
MachineType: DefaultMachineType,
}
}

Expand All @@ -158,6 +161,7 @@ type Config struct {
UseEmulation bool
MigrationConfig *MigrationConfig
ImagePullPolicy k8sv1.PullPolicy
MachineType string
}

type MigrationConfig struct {
Expand Down Expand Up @@ -190,6 +194,10 @@ func (c *ClusterConfig) GetImagePullPolicy() (policy k8sv1.PullPolicy) {
return c.getConfig().ImagePullPolicy
}

func (c *ClusterConfig) GetMachineType() string {
return c.getConfig().MachineType
}

// setConfig parses the provided config map and updates the provided config.
// Default values in the provided config stay in tact.
func setConfig(config *Config, configMap *k8sv1.ConfigMap) error {
Expand Down Expand Up @@ -235,6 +243,11 @@ func setConfig(config *Config, configMap *k8sv1.ConfigMap) error {
return fmt.Errorf("invalid debug.useEmulation in config: %v", useEmulation)
}

// set machine type
if machineType := strings.TrimSpace(configMap.Data[machineTypeKey]); machineType != "" {
config.MachineType = machineType
}

return nil
}

Expand Down
16 changes: 16 additions & 0 deletions pkg/virt-config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ var _ = Describe("ConfigMap", func() {
table.Entry("when invalid, it should return the default", "invalid", kubev1.PullIfNotPresent),
)

table.DescribeTable(" when machineType", func(value string, result string) {
cfgMap := kubev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1234",
Namespace: "kubevirt",
Name: "kubevirt-config",
},
Data: map[string]string{machineTypeKey: value},
}
clusterConfig, _ := MakeClusterConfig([]kubev1.ConfigMap{cfgMap}, stopChan)
Expect(clusterConfig.GetMachineType()).To(Equal(result))
},
table.Entry("when set, it should return the value", "pc-q35-3.0", "pc-q35-3.0"),
table.Entry("when unset, it should return the default", "", DefaultMachineType),
)

It("Should return migration config values if specified as json", func() {
cfgMap := kubev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Expand Down
1 change: 1 addition & 0 deletions tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ go_library(
"//pkg/util/net/dns:go_default_library",
"//pkg/virt-config:go_default_library",
"//pkg/virt-controller/services:go_default_library",
"//pkg/virt-launcher/virtwrap/api:go_default_library",
"//pkg/virtctl:go_default_library",
"//tools/vms-generator/utils:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
Expand Down
18 changes: 18 additions & 0 deletions tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"bytes"
"encoding/base64"
"encoding/json"
"encoding/xml"
goerrors "errors"
"flag"
"fmt"
Expand Down Expand Up @@ -71,6 +72,7 @@ import (
"kubevirt.io/kubevirt/pkg/util/net/dns"
virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
"kubevirt.io/kubevirt/pkg/virt-controller/services"
launcherApi "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
"kubevirt.io/kubevirt/pkg/virtctl"
vmsgen "kubevirt.io/kubevirt/tools/vms-generator/utils"
)
Expand Down Expand Up @@ -3338,3 +3340,19 @@ func AppendEmptyDisk(vmi *v1.VirtualMachineInstance, diskName, busName, diskSize
},
})
}

func GetRunningVMISpec(vmi *v1.VirtualMachineInstance) (*launcherApi.DomainSpec, error) {
runningVMISpec := launcherApi.DomainSpec{}
cli, err := kubecli.GetKubevirtClient()
if err != nil {
return nil, err
}

domXML, err := GetRunningVirtualMachineInstanceDomainXML(cli, vmi)
if err != nil {
return nil, err
}

err = xml.Unmarshal([]byte(domXML), &runningVMISpec)
return &runningVMISpec, err
}
57 changes: 51 additions & 6 deletions tests/vmi_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package tests_test

import (
"encoding/xml"
"flag"
"fmt"
"regexp"
Expand All @@ -43,7 +42,6 @@ import (
"kubevirt.io/kubevirt/pkg/kubecli"
"kubevirt.io/kubevirt/pkg/log"
hw_utils "kubevirt.io/kubevirt/pkg/util/hardware"
launcherApi "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
"kubevirt.io/kubevirt/tests"
)

Expand Down Expand Up @@ -1076,6 +1074,56 @@ var _ = Describe("Configurations", func() {
})
})

Context("with machine type settings", func() {
defaultMachineTypeKey := "machine-type"

AfterEach(func() {
cfgMap, err := virtClient.CoreV1().ConfigMaps(namespaceKubevirt).Get(kubevirtConfig, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())

cfgMap.Data[defaultMachineTypeKey] = ""

_, err = virtClient.CoreV1().ConfigMaps(namespaceKubevirt).Update(cfgMap)
Expect(err).ToNot(HaveOccurred())
})

It("should set machine type from VMI spec", func() {
vmi := tests.NewRandomVMI()
vmi.Spec.Domain.Machine.Type = "pc-q35-3.0"
tests.RunVMIAndExpectLaunch(vmi, false, 30)
runningVMISpec, err := tests.GetRunningVMISpec(vmi)

Expect(err).ToNot(HaveOccurred())
Expect(runningVMISpec.OS.Type.Machine).To(Equal("pc-q35-3.0"))
})

It("should set default machine type when it is not provided", func() {
vmi := tests.NewRandomVMI()
vmi.Spec.Domain.Machine.Type = ""
tests.RunVMIAndExpectLaunch(vmi, false, 30)
runningVMISpec, err := tests.GetRunningVMISpec(vmi)

Expect(err).ToNot(HaveOccurred())
Expect(runningVMISpec.OS.Type.Machine).To(ContainSubstring("q35"))
})

It("should set machine type from kubevirt-confg", func() {
cfgMap, err := virtClient.CoreV1().ConfigMaps(namespaceKubevirt).Get(kubevirtConfig, metav1.GetOptions{})
Expect(err).To(BeNil())
cfgMap.Data[defaultMachineTypeKey] = "pc-q35-3.0"
_, err = virtClient.CoreV1().ConfigMaps(namespaceKubevirt).Update(cfgMap)
Expect(err).ToNot(HaveOccurred())

vmi := tests.NewRandomVMI()
vmi.Spec.Domain.Machine.Type = ""
tests.RunVMIAndExpectLaunch(vmi, false, 30)
runningVMISpec, err := tests.GetRunningVMISpec(vmi)

Expect(err).ToNot(HaveOccurred())
Expect(runningVMISpec.OS.Type.Machine).To(Equal("pc-q35-3.0"))
})
})

Context("[rfe_id:904][crit:medium][vendor:cnv-qe@redhat.com][level:component]with driver cache settings", func() {
blockPVName := "block-pv-" + rand.String(48)

Expand Down Expand Up @@ -1106,10 +1154,7 @@ var _ = Describe("Configurations", func() {
tests.AddHostDisk(vmi, "/run/kubevirt-private/vm-disks/test-disk.img", v1.HostDiskExistsOrCreate, "hostdisk")
tests.RunVMIAndExpectLaunch(vmi, false, 60)

runningVMISpec := launcherApi.DomainSpec{}
domXml, err := tests.GetRunningVirtualMachineInstanceDomainXML(virtClient, vmi)
Expect(err).ToNot(HaveOccurred())
err = xml.Unmarshal([]byte(domXml), &runningVMISpec)
runningVMISpec, err := tests.GetRunningVMISpec(vmi)
Expect(err).ToNot(HaveOccurred())

disks := runningVMISpec.Devices.Disks
Expand Down

0 comments on commit ebe9902

Please sign in to comment.