github.com/kaixiang/packer@v0.5.2-0.20140114230416-1f5786b0d7f1/builder/docker/driver_docker.go (about)

     1  package docker
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/mitchellh/packer/packer"
     7  	"io"
     8  	"log"
     9  	"os/exec"
    10  	"strings"
    11  )
    12  
    13  type DockerDriver struct {
    14  	Ui  packer.Ui
    15  	Tpl *packer.ConfigTemplate
    16  }
    17  
    18  func (d *DockerDriver) Export(id string, dst io.Writer) error {
    19  	var stderr bytes.Buffer
    20  	cmd := exec.Command("docker", "export", id)
    21  	cmd.Stdout = dst
    22  	cmd.Stderr = &stderr
    23  
    24  	log.Printf("Exporting container: %s", id)
    25  	if err := cmd.Start(); err != nil {
    26  		return err
    27  	}
    28  
    29  	if err := cmd.Wait(); err != nil {
    30  		err = fmt.Errorf("Error exporting: %s\nStderr: %s",
    31  			err, stderr.String())
    32  		return err
    33  	}
    34  
    35  	return nil
    36  }
    37  
    38  func (d *DockerDriver) Pull(image string) error {
    39  	cmd := exec.Command("docker", "pull", image)
    40  	return runAndStream(cmd, d.Ui)
    41  }
    42  
    43  func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) {
    44  	// Build up the template data
    45  	var tplData startContainerTemplate
    46  	tplData.Image = config.Image
    47  	if len(config.Volumes) > 0 {
    48  		volumes := make([]string, 0, len(config.Volumes))
    49  		for host, guest := range config.Volumes {
    50  			volumes = append(volumes, fmt.Sprintf("%s:%s", host, guest))
    51  		}
    52  
    53  		tplData.Volumes = strings.Join(volumes, ",")
    54  	}
    55  
    56  	// Args that we're going to pass to Docker
    57  	args := config.RunCommand
    58  	for i, v := range args {
    59  		var err error
    60  		args[i], err = d.Tpl.Process(v, &tplData)
    61  		if err != nil {
    62  			return "", err
    63  		}
    64  	}
    65  	d.Ui.Message(fmt.Sprintf(
    66  		"Run command: docker %s", strings.Join(args, " ")))
    67  
    68  	// Start the container
    69  	var stdout, stderr bytes.Buffer
    70  	cmd := exec.Command("docker", args...)
    71  	cmd.Stdout = &stdout
    72  	cmd.Stderr = &stderr
    73  
    74  	log.Printf("Starting container with args: %v", args)
    75  	if err := cmd.Start(); err != nil {
    76  		return "", err
    77  	}
    78  
    79  	log.Println("Waiting for container to finish starting")
    80  	if err := cmd.Wait(); err != nil {
    81  		if _, ok := err.(*exec.ExitError); ok {
    82  			err = fmt.Errorf("Docker exited with a non-zero exit status.\nStderr: %s",
    83  				stderr.String())
    84  		}
    85  
    86  		return "", err
    87  	}
    88  
    89  	// Capture the container ID, which is alone on stdout
    90  	return strings.TrimSpace(stdout.String()), nil
    91  }
    92  
    93  func (d *DockerDriver) StopContainer(id string) error {
    94  	return exec.Command("docker", "kill", id).Run()
    95  }
    96  
    97  func (d *DockerDriver) Verify() error {
    98  	if _, err := exec.LookPath("docker"); err != nil {
    99  		return err
   100  	}
   101  
   102  	return nil
   103  }