From 52cb0e1cfe87dad0c3c8b8289c39bdb7e62b3b46 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Mon, 16 Apr 2018 11:39:15 +0100 Subject: [PATCH 1/3] moby: Improve debug output for 'docker run' Signed-off-by: Rolf Neugebauer --- src/moby/docker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/moby/docker.go b/src/moby/docker.go index 296a61108..18520387a 100644 --- a/src/moby/docker.go +++ b/src/moby/docker.go @@ -22,7 +22,7 @@ import ( ) func dockerRun(input io.Reader, output io.Writer, trust bool, img string, args ...string) error { - log.Debugf("docker run (input): %s", strings.Join(args, " ")) + log.Debugf("docker run %s (trust=%t) (input): %s", img, trust, strings.Join(args, " ")) docker, err := exec.LookPath("docker") if err != nil { return errors.New("Docker does not seem to be installed") @@ -38,7 +38,7 @@ func dockerRun(input io.Reader, output io.Writer, trust bool, img string, args . pull.Env = env if err := pull.Run(); err != nil { if exitError, ok := err.(*exec.ExitError); ok { - return fmt.Errorf("docker pull failed: %v output:\n%s", err, exitError.Stderr) + return fmt.Errorf("docker pull %s failed: %v output:\n%s", img, err, exitError.Stderr) } return err } @@ -51,12 +51,12 @@ func dockerRun(input io.Reader, output io.Writer, trust bool, img string, args . if err := cmd.Run(); err != nil { if exitError, ok := err.(*exec.ExitError); ok { - return fmt.Errorf("docker run failed: %v output:\n%s", err, exitError.Stderr) + return fmt.Errorf("docker run %s failed: %v output:\n%s", img, err, exitError.Stderr) } return err } - log.Debugf("docker run (input): %s...Done", strings.Join(args, " ")) + log.Debugf("docker run %s (input): %s...Done", img, strings.Join(args, " ")) return nil } From ad11be6b8331aee1d0c2bbb98a1c5e068376978c Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Sun, 15 Apr 2018 19:27:48 +0100 Subject: [PATCH 2/3] moby: Add 'kernel+squashfs' output This output produces a kernel and a root filesystem in squashfs format. squashfs is a read-only, compressed filesystem. The 'kernel+squashfs' output can be used in a similar way as the default 'kernel+initrd' output format with the benefit that the rootfs does not consume any memory. Signed-off-by: Rolf Neugebauer --- src/moby/output.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/moby/output.go b/src/moby/output.go index 5ca663cf7..a5427c2a7 100644 --- a/src/moby/output.go +++ b/src/moby/output.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "os" "runtime" + "strings" "github.com/moby/tool/src/initrd" log "github.com/sirupsen/logrus" @@ -19,6 +20,7 @@ var ( "iso-efi": "linuxkit/mkimage-iso-efi:343cf1a8ac0aba7d8a1f13b7f45fa0b57ab897dc", "raw-bios": "linuxkit/mkimage-raw-bios:d90713b2dd610cf9a0f5f9d9095f8bf86f40d5c6", "raw-efi": "linuxkit/mkimage-raw-efi:8938ffb6014543e557b624a40cce1714f30ce4b6", + "squashfs": "linuxkit/mkimage-squashfs:b44d00b0a336fd32c122ff32bd2b39c36a965135", "gcp": "linuxkit/mkimage-gcp:e6cdcf859ab06134c0c37a64ed5f886ec8dae1a1", "qcow2-efi": "linuxkit/mkimage-qcow2-efi:787b54906e14a56b9f1da35dcc8e46bd58435285", "vhd": "linuxkit/mkimage-vhd:3820219e5c350fe8ab2ec6a217272ae82f4b9242", @@ -99,6 +101,13 @@ var outFuns = map[string]func(string, io.Reader, int) error{ } return nil }, + "kernel+squashfs": func(base string, image io.Reader, size int) error { + err := outputKernelSquashFS(outputImages["squashfs"], base, image) + if err != nil { + return fmt.Errorf("Error writing kernel+squashfs output: %v", err) + } + return nil + }, "aws": func(base string, image io.Reader, size int) error { filename := base + ".raw" log.Infof(" %s", filename) @@ -427,3 +436,57 @@ func outputKernelInitrdTarball(base string, kernel []byte, initrd []byte, cmdlin } return tw.Close() } + +func outputKernelSquashFS(image, base string, filesystem io.Reader) error { + log.Debugf("output kernel/squashfs: %s %s", image, base) + log.Infof(" %s-squashfs.img", base) + + tr := tar.NewReader(filesystem) + buf := new(bytes.Buffer) + rootfs := tar.NewWriter(buf) + + for { + var thdr *tar.Header + thdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + switch { + case thdr.Name == "boot/kernel": + kernel, err := ioutil.ReadAll(tr) + if err != nil { + return err + } + if err := ioutil.WriteFile(base+"-kernel", kernel, os.FileMode(0644)); err != nil { + return err + } + case thdr.Name == "boot/cmdline": + cmdline, err := ioutil.ReadAll(tr) + if err != nil { + return err + } + if err := ioutil.WriteFile(base+"-cmdline", cmdline, os.FileMode(0644)); err != nil { + return err + } + case strings.HasPrefix(thdr.Name, "boot/"): + // skip the rest of boot/ + default: + rootfs.WriteHeader(thdr) + if _, err := io.Copy(rootfs, tr); err != nil { + return err + } + } + } + rootfs.Close() + + output, err := os.Create(base + "-squashfs.img") + if err != nil { + return err + } + defer output.Close() + + return dockerRun(buf, output, true, image) +} From a39cee3f18b26442b7be872d426932961c007c86 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Mon, 16 Apr 2018 14:38:03 +0100 Subject: [PATCH 3/3] initrd: Skip rest of ./boot For the initrd we only want to extract kernel, cmdline, and the ucode CPIO archive. Skip whatever is left in ./boot Signed-off-by: Rolf Neugebauer --- src/initrd/initrd.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/initrd/initrd.go b/src/initrd/initrd.go index 2a4a27a06..6575cdf85 100644 --- a/src/initrd/initrd.go +++ b/src/initrd/initrd.go @@ -8,6 +8,7 @@ import ( "io" "io/ioutil" "path/filepath" + "strings" "github.com/moby/tool/src/pad4" "github.com/surma/gocpio" @@ -121,26 +122,26 @@ func CopySplitTar(w *Writer, r *tar.Reader) (kernel []byte, cmdline string, ucod if err != nil { return } - switch thdr.Name { - case "boot/kernel": + switch { + case thdr.Name == "boot/kernel": kernel, err = ioutil.ReadAll(r) if err != nil { return } - case "boot/cmdline": + case thdr.Name == "boot/cmdline": var buf []byte buf, err = ioutil.ReadAll(r) if err != nil { return } cmdline = string(buf) - case "boot/ucode.cpio": + case thdr.Name == "boot/ucode.cpio": ucode, err = ioutil.ReadAll(r) if err != nil { return } - case "boot": - // skip this entry + case strings.HasPrefix(thdr.Name, "boot/"): + // skip the rest of ./boot default: _, err = copyTarEntry(w, thdr, r) if err != nil {