mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 10:09:07 +00:00
Rough first version of the moby tool
- terrible code - lots needs changing - can build a Moby from a config yaml that boots Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
commit
22298c7761
200
moby/main.go
Normal file
200
moby/main.go
Normal file
@ -0,0 +1,200 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/moby/pkg/initrd"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type moby struct {
|
||||
Kernel string
|
||||
Init string
|
||||
System []struct {
|
||||
Name string
|
||||
Image string
|
||||
CapDrop []string `yaml:"cap_drop"`
|
||||
CapAdd []string `yaml:"cap_add"`
|
||||
Bind string
|
||||
OomScoreAdj int64 `yaml:"oom_score_adj"`
|
||||
Command []string
|
||||
}
|
||||
Database []struct {
|
||||
File string
|
||||
Value string
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
riddler = "mobylinux/riddler:7d4545d8b8ac2700971a83f12a3446a76db28c14@sha256:11b7310df6482fc38aa52b419c2ef1065d7b9207c633d47554e13aa99f6c0b72"
|
||||
docker2tar = "mobylinux/docker2tar:82a3f11f70b2959c7100dd6e184b511ebfc65908@sha256:e4fd36febc108477a2e5316d263ac257527779409891c7ac10d455a162df05c1"
|
||||
)
|
||||
|
||||
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() {
|
||||
config, err := ioutil.ReadFile("moby.yaml")
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot open config file: %v", err)
|
||||
}
|
||||
|
||||
m := moby{}
|
||||
|
||||
err = yaml.Unmarshal(config, &m)
|
||||
if err != nil {
|
||||
log.Fatalf("Yaml parse error: %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
|
||||
// TODO examine contents to see what names they might have
|
||||
const (
|
||||
bzimageName = "bzImage"
|
||||
ktarName = "kernel.tar"
|
||||
)
|
||||
args := []string{"run", "--rm", m.Kernel, "tar", "cf", "-", bzimageName, ktarName}
|
||||
cmd := exec.Command(docker, args...)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to extract kernel image and tarball")
|
||||
}
|
||||
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")
|
||||
}
|
||||
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()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to build init tarball: %v", err)
|
||||
}
|
||||
buffer := bytes.NewBuffer(init)
|
||||
containers = append(containers, buffer)
|
||||
|
||||
for _, image := range m.System {
|
||||
// riddler arguments
|
||||
args := []string{"run", "--rm", "-v", "/var/run/docker.sock:/var/run/docker.sock", riddler, image.Image, "/containers/" + image.Name}
|
||||
// docker arguments
|
||||
for _, cap := range image.CapDrop {
|
||||
args = append(args, "--cap-drop", cap)
|
||||
}
|
||||
for _, cap := range image.CapAdd {
|
||||
args = append(args, "--cap-add", cap)
|
||||
}
|
||||
// image
|
||||
args = append(args, image.Image)
|
||||
// command
|
||||
args = append(args, image.Command...)
|
||||
cmd := exec.Command(docker, args...)
|
||||
|
||||
// get output tarball
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to build container tarball: %v", err)
|
||||
}
|
||||
buffer := bytes.NewBuffer(out)
|
||||
containers = append(containers, buffer)
|
||||
}
|
||||
|
||||
initrd, err := containersInitrd(containers)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to make initrd %v", err)
|
||||
}
|
||||
|
||||
// TODO should we tar these up? Also output to other formats
|
||||
err = ioutil.WriteFile("initrd.img", initrd.Bytes(), os.FileMode(0644))
|
||||
if err != nil {
|
||||
log.Fatalf("could not write initrd: %v", err)
|
||||
}
|
||||
err = ioutil.WriteFile("bzImage", bzimage.Bytes(), os.FileMode(0644))
|
||||
if err != nil {
|
||||
log.Fatalf("could not write kernel: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() {
|
||||
env := os.Environ()
|
||||
args := []string{}
|
||||
err := syscall.Exec("./hyperkit.sh", args, env)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not run")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) >= 2 && os.Args[1] == "run" {
|
||||
run()
|
||||
}
|
||||
build()
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user