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 <justin.cormack@docker.com>
This commit is contained in:
Justin Cormack 2017-03-03 18:44:47 -08:00
parent 3b838896b0
commit e35c4c9b37
7 changed files with 142 additions and 43 deletions

View File

@ -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 {

View File

@ -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() {

View File

@ -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

101
moby/output.go Normal file
View File

@ -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
}

View File

@ -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...