From 13a94c7a3c2a5777e9bc48764f2f67e9109f999d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 13 Jun 2017 11:00:20 +0100 Subject: [PATCH] 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 --- src/cmd/linuxkit/run_qemu.go | 56 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/src/cmd/linuxkit/run_qemu.go b/src/cmd/linuxkit/run_qemu.go index 8bb7f4acb..22102afe2 100644 --- a/src/cmd/linuxkit/run_qemu.go +++ b/src/cmd/linuxkit/run_qemu.go @@ -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 {