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 <git@charlotteharludo.com>
This commit is contained in:
Charlotte Hartmann Paludo 2025-08-05 10:19:08 +02:00
parent c47bff6d6a
commit f058199f30
No known key found for this signature in database
6 changed files with 56 additions and 58 deletions

View File

@ -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 {

View File

@ -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
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 = ""