Remove docker2tar docker image, use Docker directly from Go

Removing the left over indirect creates that use the Docker socket
and run in containers not directly.

See #1347

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
Justin Cormack 2017-03-22 22:24:14 +00:00
parent d6e50e72d0
commit b63d27d405
2 changed files with 214 additions and 5 deletions

View File

@ -12,10 +12,6 @@ import (
"github.com/docker/moby/src/initrd" "github.com/docker/moby/src/initrd"
) )
const (
docker2tar = "mobylinux/docker2tar:82a3f11f70b2959c7100dd6e184b511ebfc65908@sha256:e4fd36febc108477a2e5316d263ac257527779409891c7ac10d455a162df05c1"
)
func untarKernel(buf *bytes.Buffer, bzimageName, ktarName string) (*bytes.Buffer, *bytes.Buffer, error) { func untarKernel(buf *bytes.Buffer, bzimageName, ktarName string) (*bytes.Buffer, *bytes.Buffer, error) {
tr := tar.NewReader(buf) tr := tar.NewReader(buf)
@ -112,7 +108,7 @@ func build(name string, args []string) {
containers = append(containers, ktar) containers = append(containers, ktar)
// convert init image to tarball // convert init image to tarball
init, err := dockerRun("-v", "/var/run/docker.sock:/var/run/docker.sock", docker2tar, m.Init) init, err := imageExtract(m.Init)
if err != nil { if err != nil {
log.Fatalf("Failed to build init tarball: %v", err) log.Fatalf("Failed to build init tarball: %v", err)
} }

213
src/cmd/moby/image.go Normal file
View File

@ -0,0 +1,213 @@
package main
import (
"archive/tar"
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"os/exec"
"strings"
)
// This uses Docker to convert a Docker image into a tarball. It would be an improvement if we
// used the containerd libraries to do this instead locally direct from a local image
// cache as it would be much simpler.
func dockerCreate(image string) (string, error) {
docker, err := exec.LookPath("docker")
if err != nil {
return "", errors.New("Docker does not seem to be installed")
}
// we do not ever run the container, so /dev/null is used as command
args := []string{"create", image, "/dev/null"}
cmd := exec.Command(docker, args...)
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return "", err
}
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return "", err
}
err = cmd.Start()
if err != nil {
return "", err
}
stdout, err := ioutil.ReadAll(stdoutPipe)
if err != nil {
return "", err
}
stderr, err := ioutil.ReadAll(stderrPipe)
if err != nil {
return "", err
}
err = cmd.Wait()
if err != nil {
return "", fmt.Errorf("%s: %s", err, stderr)
}
container := strings.TrimSpace(string(stdout))
return container, nil
}
func dockerExport(container string) ([]byte, error) {
docker, err := exec.LookPath("docker")
if err != nil {
return []byte{}, errors.New("Docker does not seem to be installed")
}
args := []string{"export", container}
cmd := exec.Command(docker, args...)
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return []byte{}, err
}
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return []byte{}, err
}
err = cmd.Start()
if err != nil {
return []byte{}, err
}
stdout, err := ioutil.ReadAll(stdoutPipe)
if err != nil {
return []byte{}, err
}
stderr, err := ioutil.ReadAll(stderrPipe)
if err != nil {
return []byte{}, err
}
err = cmd.Wait()
if err != nil {
return []byte{}, fmt.Errorf("%s: %s", err, stderr)
}
return stdout, nil
}
func dockerRm(container string) error {
docker, err := exec.LookPath("docker")
if err != nil {
return errors.New("Docker does not seem to be installed")
}
args := []string{"rm", container}
cmd := exec.Command(docker, args...)
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return err
}
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
_, err = ioutil.ReadAll(stdoutPipe)
if err != nil {
return err
}
stderr, err := ioutil.ReadAll(stderrPipe)
if err != nil {
return err
}
err = cmd.Wait()
if err != nil {
return fmt.Errorf("%s: %s", err, stderr)
}
return nil
}
var exclude = map[string]bool{
".dockerenv": true,
"Dockerfile": true,
"dev/console": true,
"dev/pts": true,
"dev/shm": true,
}
var replace = map[string]string{
"etc/hosts": `127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`,
"etc/resolv.conf": `nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844
`,
"etc/hostname": "moby",
}
func imageExtract(image string) ([]byte, error) {
container, err := dockerCreate(image)
if err != nil {
return []byte{}, fmt.Errorf("Failed to docker create image %s: %v", image, err)
}
contents, err := dockerExport(container)
if err != nil {
return []byte{}, fmt.Errorf("Failed to docker export container from container %s: %v", container, err)
}
err = dockerRm(container)
if err != nil {
return []byte{}, fmt.Errorf("Failed to docker rm container %s: %v", container, err)
}
// now we need to filter out some files from the resulting tar archive
out := new(bytes.Buffer)
tw := tar.NewWriter(out)
r := bytes.NewReader(contents)
tr := tar.NewReader(r)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return []byte{}, err
}
if exclude[hdr.Name] {
io.Copy(ioutil.Discard, tr)
} else if replace[hdr.Name] != "" {
hdr.Size = int64(len(replace[hdr.Name]))
tw.WriteHeader(hdr)
buf := bytes.NewBufferString(replace[hdr.Name])
io.Copy(tw, buf)
} else {
tw.WriteHeader(hdr)
io.Copy(tw, tr)
}
}
err = tw.Close()
if err != nil {
return []byte{}, err
}
return out.Bytes(), nil
}