Add metadata support to Qemu runner.

Based on the hyperkit runner's code.

project/kubernetes/boot.sh now works, although lack of network connectivity
between individual VMs remains an issue.

Also manually validated containerized operation with:

    rm -rf kube-node-0-state && ../../bin/linuxkit run qemu --containerized  -cpus 2 -mem 4096 -state kube-node-0-state -disk size=4G -data "foo bar" kube-node

Signed-off-by: Ian Campbell <ian.campbell@docker.com>
This commit is contained in:
Ian Campbell 2017-06-13 11:00:20 +01:00
parent a09090e6cd
commit 13a94c7a3c

View File

@ -20,11 +20,12 @@ const QemuImg = "linuxkit/qemu:c9691f5c50dd191e62b77eaa2f3dfd05ed2ed77c"
// QemuConfig contains the config for Qemu
type QemuConfig struct {
Path string
ISO bool
ISOBoot bool
UEFI bool
Kernel bool
GUI bool
Disks Disks
MetadataPath string
FWPath string
Arch string
CPUs string
@ -61,6 +62,7 @@ func runQemu(args []string) {
// Paths and settings for disks
var disks Disks
flags.Var(&disks, "disk", "Disk config, may be repeated. [file=]path[,size=1G][,format=qcow2]")
data := flags.String("data", "", "Metadata to pass to VM (either a path to a file or a string)")
// Paths and settings for UEFI firware
fw := flags.String("fw", "/usr/share/ovmf/bios.bin", "Path to OVMF firmware for UEFI boot")
@ -120,6 +122,23 @@ func runQemu(args []string) {
log.Fatalf("Could not create state directory: %v", err)
}
isoPath := ""
if *data != "" {
var d []byte
if _, err := os.Stat(*data); os.IsNotExist(err) {
d = []byte(*data)
} else {
d, err = ioutil.ReadFile(*data)
if err != nil {
log.Fatalf("Cannot read user data: %v", err)
}
}
isoPath = filepath.Join(*state, "data.iso")
if err := WriteMetadataISO(isoPath, d); err != nil {
log.Fatalf("Cannot write user data ISO: %v", err)
}
}
for i, d := range disks {
id := ""
if i != 0 {
@ -144,13 +163,18 @@ func runQemu(args []string) {
disks = append(d, disks...)
}
if *isoBoot && isoPath != "" {
log.Fatalf("metadata and ISO boot currently cannot coexist")
}
config := QemuConfig{
Path: path,
ISO: *isoBoot,
ISOBoot: *isoBoot,
UEFI: *uefiBoot,
Kernel: *kernelBoot,
GUI: *enableGUI,
Disks: disks,
MetadataPath: isoPath,
FWPath: *fw,
Arch: *arch,
CPUs: *cpus,
@ -224,20 +248,22 @@ func runQemuContainer(config QemuConfig) error {
}
var binds []string
if filepath.IsAbs(config.Path) {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(config.Path)))
} else {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", cwd))
}
// also try to bind mount disk paths so the command works
for _, d := range config.Disks {
if filepath.IsAbs(d.Path) {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(d.Path)))
addBind := func(p string) {
if filepath.IsAbs(p) {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(p)))
} else {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", cwd))
}
}
addBind(config.Path)
if config.MetadataPath != "" {
addBind(config.MetadataPath)
}
// also try to bind mount disk paths so the command works
for _, d := range config.Disks {
addBind(d.Path)
}
var args []string
config, args = buildQemuCmdline(config)
@ -324,7 +350,7 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
for i, d := range config.Disks {
index := i
// hdc is CDROM in qemu
if i >= 2 && config.ISO {
if i >= 2 && config.ISOBoot {
index++
}
if d.Format != "" {
@ -334,9 +360,11 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
}
}
if config.ISO {
if config.ISOBoot {
qemuArgs = append(qemuArgs, "-cdrom", config.Path)
qemuArgs = append(qemuArgs, "-boot", "d")
} else if config.MetadataPath != "" {
qemuArgs = append(qemuArgs, "-cdrom", config.MetadataPath)
}
if config.UEFI {