From f058199f30f2deba7ea81c4186751d9018665a69 Mon Sep 17 00:00:00 2001 From: Charlotte Hartmann Paludo Date: Tue, 5 Aug 2025 10:19:08 +0200 Subject: [PATCH] runtime: allow initrd AND image to be set Currently, only an image OR initrd can be set. This commit changes that, allowing both to be set at the same time. Signed-off-by: charludo --- src/runtime/virtcontainers/clh.go | 19 +++--- src/runtime/virtcontainers/fc.go | 2 +- src/runtime/virtcontainers/hypervisor.go | 67 +++++++++---------- .../hypervisor_config_darwin.go | 2 - .../virtcontainers/hypervisor_config_linux.go | 2 - src/runtime/virtcontainers/qemu.go | 22 +++--- 6 files changed, 56 insertions(+), 58 deletions(-) diff --git a/src/runtime/virtcontainers/clh.go b/src/runtime/virtcontainers/clh.go index 8714794d98..91d9bdf8c0 100644 --- a/src/runtime/virtcontainers/clh.go +++ b/src/runtime/virtcontainers/clh.go @@ -587,15 +587,14 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net clh.vmconfig.Rng.SetIommu(clh.config.IOMMU) // set the initial root/boot disk of hypervisor - assetPath, assetType, err := clh.config.ImageOrInitrdAssetPath() + imagePath, err := clh.config.ImageAssetPath() if err != nil { return err } - - if assetType == types.ImageAsset { + if imagePath != "" { if clh.config.DisableImageNvdimm || clh.config.ConfidentialGuest { disk := chclient.NewDiskConfig() - disk.Path = &assetPath + disk.Path = &imagePath disk.SetReadonly(true) diskRateLimiterConfig := clh.getDiskRateLimiterConfig() @@ -609,7 +608,7 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net clh.vmconfig.Disks = &[]chclient.DiskConfig{*disk} } } else { - pmem := chclient.NewPmemConfig(assetPath) + pmem := chclient.NewPmemConfig(imagePath) *pmem.DiscardWrites = true pmem.SetIommu(clh.config.IOMMU) @@ -619,9 +618,13 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net clh.vmconfig.Pmem = &[]chclient.PmemConfig{*pmem} } } - } else { - // assetType == types.InitrdAsset - clh.vmconfig.Payload.SetInitramfs(assetPath) + } + initrdPath, err := clh.config.ImageAssetPath() + if err != nil { + return err + } + if initrdPath != "" { + clh.vmconfig.Payload.SetInitramfs(initrdPath) } if clh.config.ConfidentialGuest { diff --git a/src/runtime/virtcontainers/fc.go b/src/runtime/virtcontainers/fc.go index 3442edadbc..f49248ca63 100644 --- a/src/runtime/virtcontainers/fc.go +++ b/src/runtime/virtcontainers/fc.go @@ -721,7 +721,7 @@ func (fc *firecracker) fcInitConfiguration(ctx context.Context) error { return err } - assetPath, _, err := fc.config.ImageOrInitrdAssetPath() + assetPath, err := fc.config.ImageOrInitrdAssetPath() if err != nil { return err } diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 22423ab122..b05acb474f 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -332,7 +332,6 @@ type HypervisorConfig struct { ImagePath string // InitrdPath is the guest initrd image host path. - // ImagePath and InitrdPath cannot be set at the same time. InitrdPath string // RootfsType is filesystem type of rootfs. @@ -760,50 +759,44 @@ func (conf *HypervisorConfig) AddCustomAsset(a *types.Asset) error { return nil } -// ImageOrInitrdAssetPath returns an image or an initrd path, along with the corresponding asset type -// Annotation path is preferred to config path. -func (conf *HypervisorConfig) ImageOrInitrdAssetPath() (string, types.AssetType, error) { - var image, initrd string - - checkAndReturn := func(image string, initrd string) (string, types.AssetType, error) { - if image != "" && initrd != "" { - return "", types.UnkownAsset, conflictingAssets - } - - if image != "" { - return image, types.ImageAsset, nil - } - - if initrd != "" { - return initrd, types.InitrdAsset, nil - } - - // Even if neither image nor initrd are set, we still need to return - // if we are running a confidential guest on QemuCCWVirtio. (IBM Z Secure Execution) - if conf.ConfidentialGuest && conf.HypervisorMachineType == QemuCCWVirtio { - return "", types.SecureBootAsset, nil - } - - return "", types.UnkownAsset, fmt.Errorf("one of image and initrd must be set") +func (conf *HypervisorConfig) ImageOrInitrdAssetPath() (string, error) { + imagePath, err := conf.ImageAssetPath() + if err != nil { + return "", err + } + initrdPath, err := conf.InitrdAssetPath() + if err != nil { + return "", err } - if a, ok := conf.customAssets[types.ImageAsset]; ok { - image = a.Path() + if imagePath == "" && initrdPath == "" { + return "", fmt.Errorf("one of image and initrd must be set") + } + if imagePath != "" && initrdPath != "" { + return "", conflictingAssets } - if a, ok := conf.customAssets[types.InitrdAsset]; ok { - initrd = a.Path() + if imagePath != "" { + return imagePath, nil + } else { + return initrdPath, nil + } +} + +func (conf *HypervisorConfig) UseSecureBootAssets() bool { + imagePath, _ := conf.ImageAssetPath() + initrdPath, _ := conf.InitrdAssetPath() + if imagePath != "" || initrdPath != "" { + return false } - path, assetType, err := checkAndReturn(image, initrd) - if assetType != types.UnkownAsset { - return path, assetType, nil - } - if err == conflictingAssets { - return "", types.UnkownAsset, errors.Wrapf(err, "conflicting annotations") + // Even if neither image nor initrd are set, we still need to return + // if we are running a confidential guest on QemuCCWVirtio. (IBM Z Secure Execution) + if conf.ConfidentialGuest && conf.HypervisorMachineType == QemuCCWVirtio { + return true } - return checkAndReturn(conf.ImagePath, conf.InitrdPath) + return false } func (conf *HypervisorConfig) assetPath(t types.AssetType) (string, error) { diff --git a/src/runtime/virtcontainers/hypervisor_config_darwin.go b/src/runtime/virtcontainers/hypervisor_config_darwin.go index 1225271a2a..a3398bcf6f 100644 --- a/src/runtime/virtcontainers/hypervisor_config_darwin.go +++ b/src/runtime/virtcontainers/hypervisor_config_darwin.go @@ -21,8 +21,6 @@ func validateHypervisorConfig(conf *HypervisorConfig) error { if conf.ImagePath == "" && conf.InitrdPath == "" { return fmt.Errorf("Missing image and initrd path") - } else if conf.ImagePath != "" && conf.InitrdPath != "" { - return fmt.Errorf("Image and initrd path cannot be both set") } if conf.NumVCPUs == 0 { diff --git a/src/runtime/virtcontainers/hypervisor_config_linux.go b/src/runtime/virtcontainers/hypervisor_config_linux.go index 1bcd47218c..e695aa52f2 100644 --- a/src/runtime/virtcontainers/hypervisor_config_linux.go +++ b/src/runtime/virtcontainers/hypervisor_config_linux.go @@ -28,8 +28,6 @@ func validateHypervisorConfig(conf *HypervisorConfig) error { } } else if conf.ImagePath == "" && conf.InitrdPath == "" { return fmt.Errorf("Missing image and initrd path") - } else if conf.ImagePath != "" && conf.InitrdPath != "" { - return fmt.Errorf("Image and initrd path cannot be both set") } if err := conf.CheckTemplateConfig(); err != nil { diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 51a46d2729..2bfaf95bb2 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -435,20 +435,26 @@ func (q *qemu) buildDevices(ctx context.Context, kernelPath string) ([]govmmQemu return nil, nil, nil, err } - assetPath, assetType, err := q.config.ImageOrInitrdAssetPath() + imagePath, err := q.config.ImageAssetPath() if err != nil { return nil, nil, nil, err } - - if assetType == types.ImageAsset { - devices, err = q.arch.appendImage(ctx, devices, assetPath) + if imagePath != "" { + devices, err = q.arch.appendImage(ctx, devices, imagePath) if err != nil { return nil, nil, nil, err } - } else if assetType == types.InitrdAsset { - // InitrdAsset, need to set kernel initrd path - kernel.InitrdPath = assetPath - } else if assetType == types.SecureBootAsset { + } + + initrdPath, err := q.config.InitrdAssetPath() + if err != nil { + return nil, nil, nil, err + } + if initrdPath != "" { + kernel.InitrdPath = initrdPath + } + + if q.config.UseSecureBootAssets() { // SecureBootAsset, no need to set image or initrd path q.Logger().Info("For IBM Z Secure Execution, initrd path should not be set") kernel.InitrdPath = ""