From e35c4c9b3706a99148df0818980552dbbcbdedc4 Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Fri, 3 Mar 2017 18:44:47 -0800 Subject: [PATCH] Add output types for BIOS and EFI ISOs Note that the EFI ISO is not yet automatically sized, and the kernel command lines are currently hard coded in the builders. Signed-off-by: Justin Cormack --- moby/config.go | 2 +- moby/main.go | 76 ++++++++-------- moby/moby.yaml | 4 +- moby/output.go | 101 +++++++++++++++++++++ {base => tools}/mkimage-iso-efi/Dockerfile | 0 {base => tools}/mkimage-iso-efi/Makefile | 0 {base => tools}/mkimage-iso-efi/make-efi | 2 +- 7 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 moby/output.go rename {base => tools}/mkimage-iso-efi/Dockerfile (100%) rename {base => tools}/mkimage-iso-efi/Makefile (100%) rename {base => tools}/mkimage-iso-efi/make-efi (98%) diff --git a/moby/config.go b/moby/config.go index 2d7326e65..78383e393 100644 --- a/moby/config.go +++ b/moby/config.go @@ -49,7 +49,7 @@ func NewConfig(config []byte) (*Moby, error) { func ConfigToRun(image *MobyImage) []string { // riddler arguments - args := []string{"run", "--rm", "-v", "/var/run/docker.sock:/var/run/docker.sock", riddler, image.Image, "/containers/" + image.Name} + args := []string{"-v", "/var/run/docker.sock:/var/run/docker.sock", riddler, image.Image, "/containers/" + image.Name} // docker arguments args = append(args, "--cap-drop", "all") for _, cap := range image.Capabilities { diff --git a/moby/main.go b/moby/main.go index 9d8a8c522..ec46cccc6 100644 --- a/moby/main.go +++ b/moby/main.go @@ -7,7 +7,6 @@ import ( "io" "io/ioutil" "log" - "os" "os/exec" "github.com/docker/moby/pkg/initrd" @@ -17,6 +16,37 @@ const ( docker2tar = "mobylinux/docker2tar:82a3f11f70b2959c7100dd6e184b511ebfc65908@sha256:e4fd36febc108477a2e5316d263ac257527779409891c7ac10d455a162df05c1" ) +func dockerRun(args ...string) ([]byte, error) { + // TODO switch to using Docker client API not exec - just a quick prototype + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args = append([]string{"run", "--rm"}, args...) + cmd := exec.Command(docker, args...) + out, err := cmd.Output() + if err != nil { + return []byte{}, err + } + return out, nil +} + +func dockerRunInput(input io.Reader, args ...string) ([]byte, error) { + // TODO switch to using Docker client API not exec - just a quick prototype + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args = append([]string{"run", "--rm", "-i"}, args...) + cmd := exec.Command(docker, args...) + cmd.Stdin = input + out, err := cmd.Output() + if err != nil { + return []byte{}, err + } + return out, nil +} + func untarKernel(buf *bytes.Buffer, bzimageName, ktarName string) (*bytes.Buffer, *bytes.Buffer, error) { tr := tar.NewReader(buf) @@ -80,13 +110,6 @@ func build(configfile string) { log.Fatalf("Invalid config: %v", err) } - // TODO switch to using Docker client API not exec - just a quick prototype - - docker, err := exec.LookPath("docker") - if err != nil { - log.Fatalf("Docker does not seem to be installed") - } - containers := []*bytes.Buffer{} // get kernel bzImage and initrd tarball from container @@ -95,9 +118,7 @@ func build(configfile string) { bzimageName = "bzImage" ktarName = "kernel.tar" ) - args := []string{"run", "--rm", m.Kernel, "tar", "cf", "-", bzimageName, ktarName} - cmd := exec.Command(docker, args...) - out, err := cmd.Output() + out, err := dockerRun(m.Kernel, "tar", "cf", "-", bzimageName, ktarName) if err != nil { log.Fatalf("Failed to extract kernel image and tarball") } @@ -109,9 +130,7 @@ func build(configfile string) { containers = append(containers, ktar) // convert init image to tarball - args = []string{"run", "--rm", "-v", "/var/run/docker.sock:/var/run/docker.sock", docker2tar, m.Init} - cmd = exec.Command(docker, args...) - init, err := cmd.Output() + init, err := dockerRun("-v", "/var/run/docker.sock:/var/run/docker.sock", docker2tar, m.Init) if err != nil { log.Fatalf("Failed to build init tarball: %v", err) } @@ -120,10 +139,8 @@ func build(configfile string) { for _, image := range m.System { args := ConfigToRun(&image) - cmd := exec.Command(docker, args...) - // get output tarball - out, err := cmd.Output() + out, err := dockerRun(args...) if err != nil { log.Fatalf("Failed to build container tarball: %v", err) } @@ -143,31 +160,10 @@ func build(configfile string) { log.Fatalf("Failed to make initrd %v", err) } - for _, o := range m.Outputs { - switch o.Format { - case "kernel+initrd": - err = OutputKernelInitrd(bzimage.Bytes(), initrd.Bytes()) - if err != nil { - log.Fatalf("Error writing %s output: %v", o.Format, err) - } - case "": - log.Fatalf("No format specified for output") - default: - log.Fatalf("Unknown output type %s", o.Format) - } - } -} - -func OutputKernelInitrd(bzimage []byte, initrd []byte) error { - err := ioutil.WriteFile("initrd.img", initrd, os.FileMode(0644)) + err = outputs(m, bzimage.Bytes(), initrd.Bytes()) if err != nil { - return err + log.Fatalf("Error writing outputs: %v", err) } - err = ioutil.WriteFile("bzImage", bzimage, os.FileMode(0644)) - if err != nil { - return err - } - return nil } func main() { diff --git a/moby/moby.yaml b/moby/moby.yaml index 30e77e848..3b8924fae 100644 --- a/moby/moby.yaml +++ b/moby/moby.yaml @@ -13,7 +13,7 @@ system: oom_score_adj: -800 command: [/bin/tini, /usr/sbin/rngd, -f] - name: nginx - image: "nginx" + image: "nginx:alpine" capabilities: - CAP_NET_BIND_SERVICE - CAP_CHOWN @@ -25,3 +25,5 @@ files: contents: '{"debug": true}' outputs: - format: kernel+initrd + - format: iso-bios + - format: iso-efi diff --git a/moby/output.go b/moby/output.go new file mode 100644 index 000000000..dcd5fd2ec --- /dev/null +++ b/moby/output.go @@ -0,0 +1,101 @@ +package main + +import ( + "archive/tar" + "bytes" + "fmt" + "io/ioutil" + "os" +) + +const ( + bios = "mobylinux/mkimage-iso-bios:6b3ef6d6bdcc5fdf2ee683febac99533c2268c89@sha256:2484146c4dfbd2eee83d9dd3adf84d9232e5dd739d8762275dcd50bf60a529c6" + efi = "mobylinux/mkimage-iso-efi:40f35270037dae95584324427e56f829756ff145@sha256:ae5b37ae560a5e030342f3d493d4ad611f2694bcd54eba86bf42ca069da986a7" +) + +func outputs(m *Moby, bzimage []byte, initrd []byte) error { + for _, o := range m.Outputs { + switch o.Format { + case "kernel+initrd": + err := outputKernelInitrd(bzimage, initrd) + if err != nil { + return fmt.Errorf("Error writing %s output: %v", o.Format, err) + } + case "iso-bios": + err := outputISO(bios, "mobylinux.iso", bzimage, initrd) + if err != nil { + return fmt.Errorf("Error writing %s output: %v", o.Format, err) + } + case "iso-efi": + err := outputISO(efi, "mobylinux-efi.iso", bzimage, initrd) + if err != nil { + return fmt.Errorf("Error writing %s output: %v", o.Format, err) + } + case "": + return fmt.Errorf("No format specified for output") + default: + return fmt.Errorf("Unknown output type %s", o.Format) + } + } + return nil +} + +// TODO add kernel command line +func outputISO(image, filename string, bzimage []byte, initrd []byte) error { + // first build the input tarball from kernel and initrd + buf := new(bytes.Buffer) + tw := tar.NewWriter(buf) + hdr := &tar.Header{ + Name: "bzImage", + Mode: 0600, + Size: int64(len(bzimage)), + } + err := tw.WriteHeader(hdr) + if err != nil { + return err + } + _, err = tw.Write(bzimage) + if err != nil { + return err + } + hdr = &tar.Header{ + Name: "initrd.img", + Mode: 0600, + Size: int64(len(initrd)), + } + err = tw.WriteHeader(hdr) + if err != nil { + return err + } + _, err = tw.Write(initrd) + if err != nil { + return err + } + err = tw.Close() + if err != nil { + return err + } + iso, err := dockerRunInput(buf, image) + if err != nil { + return err + } + err = ioutil.WriteFile(filename, iso, os.FileMode(0644)) + if err != nil { + return err + } + fmt.Println(filename) + return nil +} + +func outputKernelInitrd(bzimage []byte, initrd []byte) error { + err := ioutil.WriteFile("initrd.img", initrd, os.FileMode(0644)) + if err != nil { + return err + } + err = ioutil.WriteFile("bzImage", bzimage, os.FileMode(0644)) + if err != nil { + return err + } + fmt.Println("bzImage initrd.img") + return nil +} diff --git a/base/mkimage-iso-efi/Dockerfile b/tools/mkimage-iso-efi/Dockerfile similarity index 100% rename from base/mkimage-iso-efi/Dockerfile rename to tools/mkimage-iso-efi/Dockerfile diff --git a/base/mkimage-iso-efi/Makefile b/tools/mkimage-iso-efi/Makefile similarity index 100% rename from base/mkimage-iso-efi/Makefile rename to tools/mkimage-iso-efi/Makefile diff --git a/base/mkimage-iso-efi/make-efi b/tools/mkimage-iso-efi/make-efi similarity index 98% rename from base/mkimage-iso-efi/make-efi rename to tools/mkimage-iso-efi/make-efi index 9284cdaa3..d3186a6ac 100755 --- a/base/mkimage-iso-efi/make-efi +++ b/tools/mkimage-iso-efi/make-efi @@ -50,7 +50,7 @@ mcopy -i iso/efi.raw mobylinux.efi ::/EFI/BOOT/BOOTX64.EFI xorriso -as mkisofs \ -R -f -e efi.raw -no-emul-boot -o mobylinux-efi.iso iso -tar cf - mobylinux-efi.iso mobylinux.efi +cat mobylinux-efi.iso # How to build a VHDX. Commented out because we are currently not using it # Don't delete: It took too long to figure out how to do this...