mirror of
https://github.com/linuxkit/linuxkit.git
synced 2026-04-03 12:43:19 +00:00
logrus offers better control over log-levels. Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
189 lines
4.3 KiB
Go
189 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
"github.com/docker/moby/src/initrd"
|
|
)
|
|
|
|
func untarKernel(buf *bytes.Buffer, bzimageName, ktarName string) (*bytes.Buffer, *bytes.Buffer, error) {
|
|
tr := tar.NewReader(buf)
|
|
|
|
var bzimage, ktar *bytes.Buffer
|
|
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
switch hdr.Name {
|
|
case bzimageName:
|
|
bzimage = new(bytes.Buffer)
|
|
_, err := io.Copy(bzimage, tr)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
case ktarName:
|
|
ktar = new(bytes.Buffer)
|
|
_, err := io.Copy(bzimage, tr)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
default:
|
|
continue
|
|
}
|
|
}
|
|
|
|
if ktar == nil || bzimage == nil {
|
|
return nil, nil, errors.New("did not find bzImage and kernel.tar in tarball")
|
|
}
|
|
|
|
return bzimage, ktar, nil
|
|
}
|
|
|
|
func containersInitrd(containers []*bytes.Buffer) (*bytes.Buffer, error) {
|
|
w := new(bytes.Buffer)
|
|
iw := initrd.NewWriter(w)
|
|
defer iw.Close()
|
|
for _, file := range containers {
|
|
_, err := initrd.Copy(iw, file)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return w, nil
|
|
}
|
|
|
|
func build(name string, pull bool, args []string) {
|
|
conf := "moby.yml"
|
|
if len(args) > 0 {
|
|
conf = args[0]
|
|
}
|
|
|
|
if name == "" {
|
|
name = filepath.Base(conf)
|
|
ext := filepath.Ext(conf)
|
|
if ext != "" {
|
|
name = name[:len(name)-len(ext)]
|
|
}
|
|
}
|
|
|
|
config, err := ioutil.ReadFile(conf)
|
|
if err != nil {
|
|
log.Fatalf("Cannot open config file: %v", err)
|
|
}
|
|
|
|
m, err := NewConfig(config)
|
|
if err != nil {
|
|
log.Fatalf("Invalid config: %v", err)
|
|
}
|
|
|
|
containers := []*bytes.Buffer{}
|
|
|
|
if pull {
|
|
err := dockerPull(m.Kernel.Image)
|
|
if err != nil {
|
|
log.Fatalf("Could not pull image %s: %v", m.Kernel.Image, err)
|
|
}
|
|
}
|
|
// get kernel bzImage and initrd tarball from container
|
|
// TODO examine contents to see what names they might have
|
|
const (
|
|
bzimageName = "bzImage"
|
|
ktarName = "kernel.tar"
|
|
)
|
|
out, err := dockerRun(m.Kernel.Image, "tar", "cf", "-", bzimageName, ktarName)
|
|
if err != nil {
|
|
log.Fatalf("Failed to extract kernel image and tarball: %v", err)
|
|
}
|
|
buf := bytes.NewBuffer(out)
|
|
bzimage, ktar, err := untarKernel(buf, bzimageName, ktarName)
|
|
if err != nil {
|
|
log.Fatalf("Could not extract bzImage and kernel filesystem from tarball. %v", err)
|
|
}
|
|
containers = append(containers, ktar)
|
|
|
|
// convert init image to tarball
|
|
if pull {
|
|
err := dockerPull(m.Init)
|
|
if err != nil {
|
|
log.Fatalf("Could not pull image %s: %v", m.Init, err)
|
|
}
|
|
}
|
|
init, err := ImageExtract(m.Init, "")
|
|
if err != nil {
|
|
log.Fatalf("Failed to build init tarball: %v", err)
|
|
}
|
|
buffer := bytes.NewBuffer(init)
|
|
containers = append(containers, buffer)
|
|
|
|
for i, image := range m.System {
|
|
if pull {
|
|
err := dockerPull(image.Image)
|
|
if err != nil {
|
|
log.Fatalf("Could not pull image %s: %v", image.Image, err)
|
|
}
|
|
}
|
|
config, err := ConfigToOCI(&image)
|
|
if err != nil {
|
|
log.Fatalf("Failed to run riddler to get config.json for %s: %v", image.Image, err)
|
|
}
|
|
so := fmt.Sprintf("%03d", i)
|
|
path := "containers/system/" + so + "-" + image.Name
|
|
out, err := ImageBundle(path, image.Image, config)
|
|
if err != nil {
|
|
log.Fatalf("Failed to extract root filesystem for %s: %v", image.Image, err)
|
|
}
|
|
buffer := bytes.NewBuffer(out)
|
|
containers = append(containers, buffer)
|
|
}
|
|
|
|
for _, image := range m.Daemon {
|
|
if pull {
|
|
err := dockerPull(image.Image)
|
|
if err != nil {
|
|
log.Fatalf("Could not pull image %s: %v", image.Image, err)
|
|
}
|
|
}
|
|
config, err := ConfigToOCI(&image)
|
|
if err != nil {
|
|
log.Fatalf("Failed to run riddler to get config.json for %s: %v", image.Image, err)
|
|
}
|
|
path := "containers/daemon/" + image.Name
|
|
out, err := ImageBundle(path, image.Image, config)
|
|
if err != nil {
|
|
log.Fatalf("Failed to extract root filesystem for %s: %v", image.Image, err)
|
|
}
|
|
buffer := bytes.NewBuffer(out)
|
|
containers = append(containers, buffer)
|
|
}
|
|
|
|
// add files
|
|
buffer, err = filesystem(m)
|
|
if err != nil {
|
|
log.Fatalf("failed to add filesystem parts: %v", err)
|
|
}
|
|
containers = append(containers, buffer)
|
|
|
|
initrd, err := containersInitrd(containers)
|
|
if err != nil {
|
|
log.Fatalf("Failed to make initrd %v", err)
|
|
}
|
|
|
|
err = outputs(m, name, bzimage.Bytes(), initrd.Bytes())
|
|
if err != nil {
|
|
log.Fatalf("Error writing outputs: %v", err)
|
|
}
|
|
}
|