hypervisor: add initrd image support

If an initrd image is configured in HypervisorConfig or passed in by
annotations, append it to qemu command line arguments.

Fixes: #97

Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
Peng Tao 2018-03-22 10:55:04 +08:00
parent 991fe81dff
commit 4f57b65147
8 changed files with 63 additions and 12 deletions

View File

@ -34,6 +34,8 @@ func (t assetType) annotations() (string, string, error) {
return annotations.KernelPath, annotations.KernelHash, nil return annotations.KernelPath, annotations.KernelHash, nil
case imageAsset: case imageAsset:
return annotations.ImagePath, annotations.ImageHash, nil return annotations.ImagePath, annotations.ImageHash, nil
case initrdAsset:
return annotations.InitrdPath, annotations.InitrdHash, nil
case hypervisorAsset: case hypervisorAsset:
return annotations.HypervisorPath, annotations.HypervisorHash, nil return annotations.HypervisorPath, annotations.HypervisorHash, nil
case firmwareAsset: case firmwareAsset:
@ -46,6 +48,7 @@ func (t assetType) annotations() (string, string, error) {
const ( const (
kernelAsset assetType = "kernel" kernelAsset assetType = "kernel"
imageAsset assetType = "image" imageAsset assetType = "image"
initrdAsset assetType = "initrd"
hypervisorAsset assetType = "hypervisor" hypervisorAsset assetType = "hypervisor"
firmwareAsset assetType = "firmware" firmwareAsset assetType = "firmware"
) )
@ -66,6 +69,8 @@ func (a *asset) valid() bool {
return true return true
case imageAsset: case imageAsset:
return true return true
case initrdAsset:
return true
case hypervisorAsset: case hypervisorAsset:
return true return true
case firmwareAsset: case firmwareAsset:

View File

@ -157,6 +157,10 @@ type HypervisorConfig struct {
// ImagePath is the guest image host path. // ImagePath is the guest image host path.
ImagePath string ImagePath string
// InitrdPath is the guest initrd image host path.
// ImagePath and InitrdPath cannot be set at the same time.
InitrdPath string
// FirmwarePath is the bios host path // FirmwarePath is the bios host path
FirmwarePath string FirmwarePath string
@ -225,8 +229,8 @@ func (conf *HypervisorConfig) valid() (bool, error) {
return false, fmt.Errorf("Missing kernel path") return false, fmt.Errorf("Missing kernel path")
} }
if conf.ImagePath == "" { if conf.ImagePath == "" && conf.InitrdPath == "" {
return false, fmt.Errorf("Missing image path") return false, fmt.Errorf("Missing image and initrd path")
} }
if conf.DefaultVCPUs == 0 { if conf.DefaultVCPUs == 0 {
@ -299,6 +303,8 @@ func (conf *HypervisorConfig) assetPath(t assetType) (string, error) {
return conf.KernelPath, nil return conf.KernelPath, nil
case imageAsset: case imageAsset:
return conf.ImagePath, nil return conf.ImagePath, nil
case initrdAsset:
return conf.InitrdPath, nil
case hypervisorAsset: case hypervisorAsset:
return conf.HypervisorPath, nil return conf.HypervisorPath, nil
case firmwareAsset: case firmwareAsset:
@ -337,6 +343,16 @@ func (conf *HypervisorConfig) CustomImageAsset() bool {
return conf.isCustomAsset(imageAsset) return conf.isCustomAsset(imageAsset)
} }
// InitrdAssetPath returns the guest initrd path
func (conf *HypervisorConfig) InitrdAssetPath() (string, error) {
return conf.assetPath(initrdAsset)
}
// CustomInitrdAsset returns true if the initrd asset is a custom one, false otherwise.
func (conf *HypervisorConfig) CustomInitrdAsset() bool {
return conf.isCustomAsset(initrdAsset)
}
// HypervisorAssetPath returns the VM hypervisor path // HypervisorAssetPath returns the VM hypervisor path
func (conf *HypervisorConfig) HypervisorAssetPath() (string, error) { func (conf *HypervisorConfig) HypervisorAssetPath() (string, error) {
return conf.assetPath(hypervisorAsset) return conf.assetPath(hypervisorAsset)

View File

@ -25,6 +25,9 @@ const (
// ImagePath is a pod annotation for passing a per container path pointing at the guest image that will run in the container VM. // ImagePath is a pod annotation for passing a per container path pointing at the guest image that will run in the container VM.
ImagePath = vcAnnotationsPrefix + "ImagePath" ImagePath = vcAnnotationsPrefix + "ImagePath"
// InitrdPath is a pod annotation for passing a per container path pointing at the guest initrd image that will run in the container VM.
InitrdPath = vcAnnotationsPrefix + "InitrdPath"
// HypervisorPath is a pod annotation for passing a per container path pointing at the hypervisor that will run the container VM. // HypervisorPath is a pod annotation for passing a per container path pointing at the hypervisor that will run the container VM.
HypervisorPath = vcAnnotationsPrefix + "HypervisorPath" HypervisorPath = vcAnnotationsPrefix + "HypervisorPath"
@ -37,6 +40,9 @@ const (
// ImageHash is an pod annotation for passing a container guest image SHA-512 hash value. // ImageHash is an pod annotation for passing a container guest image SHA-512 hash value.
ImageHash = vcAnnotationsPrefix + "ImageHash" ImageHash = vcAnnotationsPrefix + "ImageHash"
// InitrdHash is an pod annotation for passing a container guest initrd SHA-512 hash value.
InitrdHash = vcAnnotationsPrefix + "InitrdHash"
// HypervisorHash is an pod annotation for passing a container hypervisor binary SHA-512 hash value. // HypervisorHash is an pod annotation for passing a container hypervisor binary SHA-512 hash value.
HypervisorHash = vcAnnotationsPrefix + "HypervisorHash" HypervisorHash = vcAnnotationsPrefix + "HypervisorHash"

View File

@ -447,6 +447,7 @@ func addAssetAnnotations(ocispec CompatOCISpec, config *vc.PodConfig) {
assetAnnotations := []string{ assetAnnotations := []string{
vcAnnotations.KernelPath, vcAnnotations.KernelPath,
vcAnnotations.ImagePath, vcAnnotations.ImagePath,
vcAnnotations.InitrdPath,
vcAnnotations.KernelHash, vcAnnotations.KernelHash,
vcAnnotations.ImageHash, vcAnnotations.ImageHash,
vcAnnotations.AssetHashType, vcAnnotations.AssetHashType,

View File

@ -551,7 +551,16 @@ func createAssets(podConfig *PodConfig) error {
return err return err
} }
for _, a := range []*asset{kernel, image} { initrd, err := newAsset(podConfig, initrdAsset)
if err != nil {
return err
}
if image != nil && initrd != nil {
return fmt.Errorf("%s and %s cannot be both set", imageAsset, initrdAsset)
}
for _, a := range []*asset{kernel, image, initrd} {
if err := podConfig.HypervisorConfig.addCustomAsset(a); err != nil { if err := podConfig.HypervisorConfig.addCustomAsset(a); err != nil {
return err return err
} }

View File

@ -284,8 +284,14 @@ func (q *qemu) createPod(podConfig PodConfig) error {
return err return err
} }
initrdPath, err := q.config.InitrdAssetPath()
if err != nil {
return err
}
kernel := govmmQemu.Kernel{ kernel := govmmQemu.Kernel{
Path: kernelPath, Path: kernelPath,
InitrdPath: initrdPath,
Params: q.kernelParameters(), Params: q.kernelParameters(),
} }
@ -336,15 +342,19 @@ func (q *qemu) createPod(podConfig PodConfig) error {
devices = q.arch.append9PVolumes(devices, podConfig.Volumes) devices = q.arch.append9PVolumes(devices, podConfig.Volumes)
devices = q.arch.appendConsole(devices, q.getPodConsole(podConfig.ID)) devices = q.arch.appendConsole(devices, q.getPodConsole(podConfig.ID))
if initrdPath == "" {
imagePath, err := q.config.ImageAssetPath() imagePath, err := q.config.ImageAssetPath()
if err != nil { if err != nil {
return err return err
} }
if imagePath != "" {
devices, err = q.arch.appendImage(devices, imagePath) devices, err = q.arch.appendImage(devices, imagePath)
if err != nil { if err != nil {
return err return err
} }
}
}
if q.config.BlockDeviceDriver == VirtioBlock { if q.config.BlockDeviceDriver == VirtioBlock {
devices = q.arch.appendBridges(devices, q.state.Bridges) devices = q.arch.appendBridges(devices, q.state.Bridges)

View File

@ -32,6 +32,7 @@ func newQemuConfig() HypervisorConfig {
return HypervisorConfig{ return HypervisorConfig{
KernelPath: testQemuKernelPath, KernelPath: testQemuKernelPath,
ImagePath: testQemuImagePath, ImagePath: testQemuImagePath,
InitrdPath: testQemuInitrdPath,
HypervisorPath: testQemuPath, HypervisorPath: testQemuPath,
DefaultVCPUs: defaultVCPUs, DefaultVCPUs: defaultVCPUs,
DefaultMemSz: defaultMemSzMiB, DefaultMemSz: defaultMemSzMiB,

View File

@ -30,6 +30,7 @@ import (
const testPodID = "7f49d00d-1995-4156-8c79-5f5ab24ce138" const testPodID = "7f49d00d-1995-4156-8c79-5f5ab24ce138"
const testContainerID = "containerID" const testContainerID = "containerID"
const testKernel = "kernel" const testKernel = "kernel"
const testInitrd = "initrd"
const testImage = "image" const testImage = "image"
const testHypervisor = "hypervisor" const testHypervisor = "hypervisor"
const testBundle = "bundle" const testBundle = "bundle"
@ -45,6 +46,7 @@ var podDirLock = ""
var podFileState = "" var podFileState = ""
var podFileLock = "" var podFileLock = ""
var testQemuKernelPath = "" var testQemuKernelPath = ""
var testQemuInitrdPath = ""
var testQemuImagePath = "" var testQemuImagePath = ""
var testQemuPath = "" var testQemuPath = ""
var testHyperstartCtlSocket = "" var testHyperstartCtlSocket = ""
@ -135,6 +137,7 @@ func TestMain(m *testing.M) {
podFileLock = filepath.Join(runStoragePath, testPodID, lockFileName) podFileLock = filepath.Join(runStoragePath, testPodID, lockFileName)
testQemuKernelPath = filepath.Join(testDir, testKernel) testQemuKernelPath = filepath.Join(testDir, testKernel)
testQemuInitrdPath = filepath.Join(testDir, testInitrd)
testQemuImagePath = filepath.Join(testDir, testImage) testQemuImagePath = filepath.Join(testDir, testImage)
testQemuPath = filepath.Join(testDir, testHypervisor) testQemuPath = filepath.Join(testDir, testHypervisor)