mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-11-05 23:46:14 +00:00
GCP does not recognise the images, even though they appear identical to those made by libguestfs and work on qemu fine. Their validation code does not like them for some reason. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
141 lines
3.5 KiB
Go
141 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
)
|
|
|
|
var linuxkitYaml = map[string]string{"mkimage": `
|
|
kernel:
|
|
image: "linuxkit/kernel:4.9.x"
|
|
cmdline: "console=ttyS0"
|
|
init:
|
|
- linuxkit/init:1b8a7e394d2ec2f1fdb4d67645829d1b5bdca037
|
|
- linuxkit/runc:3a4e6cbf15470f62501b019b55e1caac5ee7689f
|
|
- linuxkit/containerd:b1766e4c4c09f63ac4925a6e4612852a93f7e73b
|
|
onboot:
|
|
- name: mkimage
|
|
image: "linuxkit/mkimage:5ad60299be03008f29c5caec3c5ea4ac0387aae6"
|
|
- name: poweroff
|
|
image: "linuxkit/poweroff:a8f1e4ad8d459f1fdaad9e4b007512cb3b504ae8"
|
|
trust:
|
|
org:
|
|
- linuxkit
|
|
`}
|
|
|
|
func imageFilename(name string) string {
|
|
yaml := linuxkitYaml[name]
|
|
hash := sha256.Sum256([]byte(yaml))
|
|
return filepath.Join(MobyDir, "linuxkit", name+"-"+fmt.Sprintf("%x", hash))
|
|
}
|
|
|
|
func ensureLinuxkitImage(name string) error {
|
|
filename := imageFilename(name)
|
|
_, err1 := os.Stat(filename + "-kernel")
|
|
_, err2 := os.Stat(filename + "-initrd.img")
|
|
_, err3 := os.Stat(filename + "-cmdline")
|
|
if err1 == nil && err2 == nil && err3 == nil {
|
|
return nil
|
|
}
|
|
err := os.MkdirAll(filepath.Join(MobyDir, "linuxkit"), 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// TODO clean up old files
|
|
log.Infof("Building LinuxKit image %s to generate output formats", name)
|
|
|
|
yaml := linuxkitYaml[name]
|
|
|
|
m, err := NewConfig([]byte(yaml))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// TODO pass through --pull to here
|
|
image := buildInternal(m, false)
|
|
kernel, initrd, cmdline, err := tarToInitrd(image)
|
|
if err != nil {
|
|
return fmt.Errorf("Error converting to initrd: %v", err)
|
|
}
|
|
err = writeKernelInitrd(filename, kernel, initrd, cmdline)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func writeKernelInitrd(filename string, kernel []byte, initrd []byte, cmdline string) error {
|
|
err := ioutil.WriteFile(filename+"-kernel", kernel, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = ioutil.WriteFile(filename+"-initrd.img", initrd, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = ioutil.WriteFile(filename+"-cmdline", []byte(cmdline), 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func outputLinuxKit(format string, filename string, kernel []byte, initrd []byte, cmdline string, size int, hyperkit bool) error {
|
|
log.Debugf("output linuxkit generated img: %s %s size %d", format, filename, size)
|
|
|
|
tmp, err := ioutil.TempDir(filepath.Join(MobyDir, "tmp"), "moby")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer os.RemoveAll(tmp)
|
|
|
|
buf, err := tarInitrdKernel(kernel, initrd, cmdline)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tardisk := filepath.Join(tmp, "tardisk")
|
|
f, err := os.Create(tardisk)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = io.Copy(f, buf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = f.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sizeString := fmt.Sprintf("%dM", size)
|
|
_ = os.Remove(filename)
|
|
_, err = os.Stat(filename)
|
|
if err == nil || !os.IsNotExist(err) {
|
|
return fmt.Errorf("Cannot remove existing file [%s]", filename)
|
|
}
|
|
linuxkit, err := exec.LookPath("linuxkit")
|
|
if err != nil {
|
|
return fmt.Errorf("Cannot find linuxkit executable, needed to build %s output type: %v", format, err)
|
|
}
|
|
commandLine := []string{"-q", "run", "qemu", "-disk", fmt.Sprintf("%s,size=%s,format=%s", filename, sizeString, format), "-disk", fmt.Sprintf("%s,format=raw", tardisk), "-kernel", imageFilename("mkimage")}
|
|
// if hyperkit && format == "raw" {
|
|
// TODO support hyperkit
|
|
// }
|
|
log.Debugf("run %s: %v", linuxkit, commandLine)
|
|
cmd := exec.Command(linuxkit, commandLine...)
|
|
cmd.Stderr = os.Stderr
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|