mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-20 09:39:08 +00:00
Use Docker API for run
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
parent
d504afe479
commit
ec6fea1d67
@ -20,91 +20,89 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func dockerRun(args ...string) ([]byte, error) {
|
||||
log.Debugf("docker run: %s", strings.Join(args, " "))
|
||||
docker, err := exec.LookPath("docker")
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("Docker does not seem to be installed")
|
||||
}
|
||||
args = append([]string{"run", "--rm", "--log-driver=none"}, args...)
|
||||
cmd := exec.Command(docker, args...)
|
||||
func dockerRunInput(input io.Reader, image string, args ...string) ([]byte, error) {
|
||||
log.Debugf("docker run (input): %s %s", image, strings.Join(args, " "))
|
||||
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
cli, err := dockerClient()
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("could not initialize Docker API client")
|
||||
}
|
||||
|
||||
origStdin := os.Stdin
|
||||
defer func() {
|
||||
os.Stdin = origStdin
|
||||
}()
|
||||
|
||||
// write input to a file
|
||||
rawInput, err := ioutil.ReadAll(input)
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("could not read input")
|
||||
}
|
||||
tmpInputFileName := "tmpInput"
|
||||
if err := ioutil.WriteFile(tmpInputFileName, rawInput, 0644); err != nil {
|
||||
return []byte{}, errors.New("could not stage input to file")
|
||||
}
|
||||
inputFile, err := os.Open(tmpInputFileName)
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("could not open input file for container stdin")
|
||||
}
|
||||
defer os.Remove(tmpInputFileName)
|
||||
|
||||
os.Stdin = inputFile
|
||||
|
||||
var resp container.ContainerCreateCreatedBody
|
||||
resp, err = cli.ContainerCreate(context.Background(), &container.Config{
|
||||
Image: image,
|
||||
Cmd: args,
|
||||
AttachStdout: true,
|
||||
AttachStdin: true,
|
||||
}, &container.HostConfig{
|
||||
AutoRemove: true,
|
||||
LogConfig: container.LogConfig{Type: "none"},
|
||||
}, nil, "")
|
||||
if err != nil {
|
||||
// if the image wasn't found, try to do a pull and another create
|
||||
if client.IsErrNotFound(err) {
|
||||
if err := dockerPull(image, false); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
resp, err = cli.ContainerCreate(context.Background(), &container.Config{
|
||||
Image: image,
|
||||
Cmd: args,
|
||||
AttachStdout: true,
|
||||
AttachStdin: true,
|
||||
}, &container.HostConfig{
|
||||
AutoRemove: true,
|
||||
LogConfig: container.LogConfig{Type: "none"},
|
||||
}, nil, "")
|
||||
// if we error again, bail
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
}
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
hijackedResp, err := cli.ContainerAttach(context.Background(), resp.ID, types.ContainerAttachOptions{
|
||||
Stdout: true,
|
||||
Stdin: true,
|
||||
Stream: true,
|
||||
})
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
if _, err = cli.ContainerWait(context.Background(), resp.ID); 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("%v: %s", err, stderr)
|
||||
}
|
||||
|
||||
log.Debugf("docker run: %s...Done", strings.Join(args, " "))
|
||||
return stdout, nil
|
||||
}
|
||||
|
||||
func dockerRunInput(input io.Reader, args ...string) ([]byte, error) {
|
||||
log.Debugf("docker run (input): %s", strings.Join(args, " "))
|
||||
docker, err := exec.LookPath("docker")
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("Docker does not seem to be installed")
|
||||
}
|
||||
args = append([]string{"run", "--rm", "-i"}, args...)
|
||||
cmd := exec.Command(docker, args...)
|
||||
cmd.Stdin = input
|
||||
|
||||
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("%v: %s", err, stderr)
|
||||
}
|
||||
|
||||
out, _ := ioutil.ReadAll(hijackedResp.Reader)
|
||||
log.Debugf("docker run (input): %s...Done", strings.Join(args, " "))
|
||||
return stdout, nil
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func dockerCreate(image string) (string, error) {
|
||||
|
@ -110,7 +110,7 @@ func outputImg(image, filename string, kernel []byte, initrd []byte, args ...str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
img, err := dockerRunInput(buf, append([]string{image}, args...)...)
|
||||
img, err := dockerRunInput(buf, image, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -128,7 +128,7 @@ func outputISO(image, filename string, kernel []byte, initrd []byte, args ...str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iso, err := dockerRunInput(buf, append([]string{image}, args...)...)
|
||||
iso, err := dockerRunInput(buf, image, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user