From 2e5a1d610f11a557fcf27e1445e17bcd020f8f3d Mon Sep 17 00:00:00 2001 From: Ram Lavi Date: Wed, 20 Mar 2024 08:36:06 +0200 Subject: [PATCH] checkup: Mount configmap to the realtime VMI This commit mounts the realtime configmap to the realtime VMI. The configmap is mounted to the VMI spec, then the Data on the configmap is mounted via cloudinit boot script. The configmap currently has no data. Signed-off-by: Ram Lavi --- pkg/internal/checkup/checkup.go | 28 ++++++++++++++++----- pkg/internal/checkup/vmi/vmi.go | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/pkg/internal/checkup/checkup.go b/pkg/internal/checkup/checkup.go index 434c34b..74667fc 100644 --- a/pkg/internal/checkup/checkup.go +++ b/pkg/internal/checkup/checkup.go @@ -231,12 +231,15 @@ func newVMUnderTestConfigMap(checkupConfig config.Config) *corev1.ConfigMap { func newRealtimeVMI(checkupConfig config.Config) *kvcorev1.VirtualMachineInstance { const ( - CPUSocketsCount = 1 - CPUCoresCount = 4 - CPUTreadsCount = 1 - hugePageSize = "1Gi" - guestMemory = "4Gi" - rootDiskName = "rootdisk" + CPUSocketsCount = 1 + CPUCoresCount = 4 + CPUTreadsCount = 1 + hugePageSize = "1Gi" + guestMemory = "4Gi" + rootDiskName = "rootdisk" + configDiskSerial = "DEADBEEF" + cloudInitDiskName = "cloudinitdisk" + configVolumeName = "realtime-config" ) return vmi.New(randomizeName(VMINamePrefix), @@ -253,9 +256,22 @@ func newRealtimeVMI(checkupConfig config.Config) *kvcorev1.VirtualMachineInstanc vmi.WithNodeSelector(checkupConfig.VMUnderTestTargetNodeName), vmi.WithContainerDisk(rootDiskName, checkupConfig.VMUnderTestContainerDiskImage), vmi.WithVirtIODisk(rootDiskName), + vmi.WithConfigMapVolume(configVolumeName, VMUnderTestConfigMapNamePrefix), + vmi.WithConfigMapDisk(configVolumeName, configDiskSerial), + vmi.WithCloudInitNoCloudVolume(cloudInitDiskName, + vmi.CloudInit(realtimeVMIBootCommands(configDiskSerial))), ) } +func realtimeVMIBootCommands(configDiskSerial string) []string { + const configMountDirectory = "/mnt/app-config" + + return []string{ + fmt.Sprintf("mkdir %s", configMountDirectory), + fmt.Sprintf("mount /dev/$(lsblk --nodeps -no name,serial | grep %s | cut -f1 -d' ') %s", configDiskSerial, configMountDirectory), + } +} + func randomizeName(prefix string) string { const randomStringLen = 5 diff --git a/pkg/internal/checkup/vmi/vmi.go b/pkg/internal/checkup/vmi/vmi.go index b342f88..d6d4082 100644 --- a/pkg/internal/checkup/vmi/vmi.go +++ b/pkg/internal/checkup/vmi/vmi.go @@ -20,6 +20,9 @@ package vmi import ( + "fmt" + "strings" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -199,6 +202,31 @@ func WithContainerDisk(volumeName, imageName string) Option { } } +func WithConfigMapVolume(name, configMapName string) Option { + return func(vmi *kvcorev1.VirtualMachineInstance) { + vmi.Spec.Volumes = append(vmi.Spec.Volumes, kvcorev1.Volume{ + Name: name, + VolumeSource: kvcorev1.VolumeSource{ + ConfigMap: &kvcorev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + Optional: Pointer(false), + }, + }, + }) + } +} + +func WithConfigMapDisk(name, serial string) Option { + return func(vmi *kvcorev1.VirtualMachineInstance) { + vmi.Spec.Domain.Devices.Disks = append(vmi.Spec.Domain.Devices.Disks, + kvcorev1.Disk{ + Name: name, + Serial: serial, + }, + ) + } +} + func WithCloudInitNoCloudVolume(name, userData string) Option { return func(vmi *kvcorev1.VirtualMachineInstance) { newVolume := kvcorev1.Volume{ @@ -214,6 +242,21 @@ func WithCloudInitNoCloudVolume(name, userData string) Option { } } +func CloudInit(bootCommands []string) string { + sb := strings.Builder{} + sb.WriteString("#cloud-config\n") + + if len(bootCommands) != 0 { + sb.WriteString("bootcmd:\n") + + for _, command := range bootCommands { + sb.WriteString(fmt.Sprintf(" - %q\n", command)) + } + } + + return sb.String() +} + func Pointer[T any](v T) *T { return &v }