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 }