Code in the initrd generator to split a single tarball

In the WIP code in `moby` we now have a standard base tarball format,
that includes the kernel and cmdline as files in `/boot` so that the
entire output of the yaml file can default to a single tarball. Then
this can be split back up by LinuxKit into initrd, kernel and cmdline
as needed. This will probably become the only output of the `moby build`
stage, with a `moby package` stage dealing with output formats.

We may remove the output format specification from the yaml file as well,
and just have it in the command.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
Justin Cormack 2017-05-08 16:15:50 +01:00
parent 405309741c
commit fb3dab399d
2 changed files with 64 additions and 1 deletions

View File

@ -65,5 +65,5 @@ ci-pr:
.PHONY: clean
clean:
rm -rf bin *.log *-kernel *-cmdline *.img *.iso *.tar.gz *.qcow2 *.vhd *.vmx *.vmdk
rm -rf bin *.log *-kernel *-cmdline *.img *.iso *.tar.gz *.qcow2 *.vhd *.vmx *.vmdk *.tar
$(MAKE) -C test clean

View File

@ -6,6 +6,7 @@ import (
"compress/gzip"
"errors"
"io"
"io/ioutil"
"github.com/linuxkit/linuxkit/src/pad4"
"github.com/surma/gocpio"
@ -92,6 +93,68 @@ func CopyTar(w *Writer, r *tar.Reader) (written int64, err error) {
}
}
// CopySplitTar copies a tar stream into an initrd, but splits out kernel and cmdline
func CopySplitTar(w *Writer, r *tar.Reader) (kernel []byte, cmdline string, err error) {
for {
var thdr *tar.Header
thdr, err = r.Next()
if err == io.EOF {
return kernel, cmdline, nil
}
if err != nil {
return
}
tp := typeconv(thdr)
if tp == -1 {
return kernel, cmdline, errors.New("cannot convert tar file")
}
switch thdr.Name {
case "boot/kernel":
kernel, err = ioutil.ReadAll(r)
if err != nil {
return
}
case "boot/cmdline":
var buf []byte
buf, err = ioutil.ReadAll(r)
if err != nil {
return
}
cmdline = string(buf)
case "boot":
default:
size := thdr.Size
if tp == cpio.TYPE_SYMLINK {
size = int64(len(thdr.Linkname))
}
chdr := cpio.Header{
Mode: thdr.Mode,
Uid: thdr.Uid,
Gid: thdr.Gid,
Mtime: thdr.ModTime.Unix(),
Size: size,
Devmajor: thdr.Devmajor,
Devminor: thdr.Devminor,
Type: tp,
Name: thdr.Name,
}
err = w.WriteHeader(&chdr)
if err != nil {
return
}
if tp == cpio.TYPE_SYMLINK {
buffer := bytes.NewBufferString(thdr.Linkname)
_, err = io.Copy(w, buffer)
} else {
_, err = io.Copy(w, r)
}
if err != nil {
return
}
}
}
}
// NewWriter creates a writer that will output an initrd stream
func NewWriter(w io.Writer) *Writer {
initrd := new(Writer)