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

View File

@ -157,6 +157,10 @@ type HypervisorConfig struct {
// ImagePath is the guest image host path.
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 string
@ -225,8 +229,8 @@ func (conf *HypervisorConfig) valid() (bool, error) {
return false, fmt.Errorf("Missing kernel path")
}
if conf.ImagePath == "" {
return false, fmt.Errorf("Missing image path")
if conf.ImagePath == "" && conf.InitrdPath == "" {
return false, fmt.Errorf("Missing image and initrd path")
}
if conf.DefaultVCPUs == 0 {
@ -299,6 +303,8 @@ func (conf *HypervisorConfig) assetPath(t assetType) (string, error) {
return conf.KernelPath, nil
case imageAsset:
return conf.ImagePath, nil
case initrdAsset:
return conf.InitrdPath, nil
case hypervisorAsset:
return conf.HypervisorPath, nil
case firmwareAsset:
@ -337,6 +343,16 @@ func (conf *HypervisorConfig) CustomImageAsset() bool {
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
func (conf *HypervisorConfig) HypervisorAssetPath() (string, error) {
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 = 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 = vcAnnotationsPrefix + "HypervisorPath"
@ -37,6 +40,9 @@ const (
// ImageHash is an pod annotation for passing a container guest image SHA-512 hash value.
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 = vcAnnotationsPrefix + "HypervisorHash"

View File

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

View File

@ -551,7 +551,16 @@ func createAssets(podConfig *PodConfig) error {
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 {
return err
}

View File

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

View File

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

View File

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