github.com/buildpack/pack@v0.5.0/internal/container/run.go (about)

     1  package container
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	dcontainer "github.com/docker/docker/api/types/container"
    10  	"github.com/docker/docker/client"
    11  	"github.com/docker/docker/pkg/stdcopy"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  func Run(ctx context.Context, docker *client.Client, ctrID string, out, errOut io.Writer) error {
    16  	bodyChan, errChan := docker.ContainerWait(ctx, ctrID, dcontainer.WaitConditionNextExit)
    17  
    18  	if err := docker.ContainerStart(ctx, ctrID, types.ContainerStartOptions{}); err != nil {
    19  		return errors.Wrap(err, "container start")
    20  	}
    21  	logs, err := docker.ContainerLogs(ctx, ctrID, types.ContainerLogsOptions{
    22  		ShowStdout: true,
    23  		ShowStderr: true,
    24  		Follow:     true,
    25  	})
    26  	if err != nil {
    27  		return errors.Wrap(err, "container logs stdout")
    28  	}
    29  
    30  	copyErr := make(chan error)
    31  	go func() {
    32  		_, err := stdcopy.StdCopy(out, errOut, logs)
    33  		copyErr <- err
    34  	}()
    35  
    36  	select {
    37  	case body := <-bodyChan:
    38  		if body.StatusCode != 0 {
    39  			return fmt.Errorf("failed with status code: %d", body.StatusCode)
    40  		}
    41  	case err := <-errChan:
    42  		return err
    43  	}
    44  	return <-copyErr
    45  }