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 // QemuConfig contains the config for Qemu
type QemuConfig struct { type QemuConfig struct {
Path string Path string
ISO bool ISOBoot bool
UEFI bool UEFI bool
Kernel bool Kernel bool
GUI bool GUI bool
Disks Disks Disks Disks
MetadataPath string
FWPath string FWPath string
Arch string Arch string
CPUs string CPUs string
@ -61,6 +62,7 @@ func runQemu(args []string) {
// Paths and settings for disks // Paths and settings for disks
var disks Disks var disks Disks
flags.Var(&disks, "disk", "Disk config, may be repeated. [file=]path[,size=1G][,format=qcow2]") 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 // Paths and settings for UEFI firware
fw := flags.String("fw", "/usr/share/ovmf/bios.bin", "Path to OVMF firmware for UEFI boot") 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) 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 { for i, d := range disks {
id := "" id := ""
if i != 0 { if i != 0 {
@ -144,13 +163,18 @@ func runQemu(args []string) {
disks = append(d, disks...) disks = append(d, disks...)
} }
if *isoBoot && isoPath != "" {
log.Fatalf("metadata and ISO boot currently cannot coexist")
}
config := QemuConfig{ config := QemuConfig{
Path: path, Path: path,
ISO: *isoBoot, ISOBoot: *isoBoot,
UEFI: *uefiBoot, UEFI: *uefiBoot,
Kernel: *kernelBoot, Kernel: *kernelBoot,
GUI: *enableGUI, GUI: *enableGUI,
Disks: disks, Disks: disks,
MetadataPath: isoPath,
FWPath: *fw, FWPath: *fw,
Arch: *arch, Arch: *arch,
CPUs: *cpus, CPUs: *cpus,
@ -224,19 +248,21 @@ func runQemuContainer(config QemuConfig) error {
} }
var binds []string var binds []string
if filepath.IsAbs(config.Path) { addBind := func(p string) {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(config.Path))) if filepath.IsAbs(p) {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(p)))
} else { } else {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", cwd)) 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 // also try to bind mount disk paths so the command works
for _, d := range config.Disks { for _, d := range config.Disks {
if filepath.IsAbs(d.Path) { addBind(d.Path)
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", filepath.Dir(d.Path)))
} else {
binds = append(binds, "-v", fmt.Sprintf("%[1]s:%[1]s", cwd))
}
} }
var args []string var args []string
@ -324,7 +350,7 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
for i, d := range config.Disks { for i, d := range config.Disks {
index := i index := i
// hdc is CDROM in qemu // hdc is CDROM in qemu
if i >= 2 && config.ISO { if i >= 2 && config.ISOBoot {
index++ index++
} }
if d.Format != "" { 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, "-cdrom", config.Path)
qemuArgs = append(qemuArgs, "-boot", "d") qemuArgs = append(qemuArgs, "-boot", "d")
} else if config.MetadataPath != "" {
qemuArgs = append(qemuArgs, "-cdrom", config.MetadataPath)
} }
if config.UEFI { if config.UEFI {