diff --git a/Makefile b/Makefile index 354c05519..2200dce76 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/src/initrd/initrd.go b/src/initrd/initrd.go index 187b48d5e..acd8bde63 100644 --- a/src/initrd/initrd.go +++ b/src/initrd/initrd.go @@ -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)