github.com/sneal/packer@v0.5.2/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"
    10  	"os/exec"
    11  	"strings"
    12  )
    13  
    14  type DockerDriver struct {
    15  	Ui  packer.Ui
    16  	Tpl *packer.ConfigTemplate
    17  }
    18  
    19  func (d *DockerDriver) DeleteImage(id string) error {
    20  	var stderr bytes.Buffer
    21  	cmd := exec.Command("docker", "rmi", id)
    22  	cmd.Stderr = &stderr
    23  
    24  	log.Printf("Deleting image: %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 deleting image: %s\nStderr: %s",
    31  			err, stderr.String())
    32  		return err
    33  	}
    34  
    35  	return nil
    36  }
    37  
    38  func (d *DockerDriver) Export(id string, dst io.Writer) error {
    39  	var stderr bytes.Buffer
    40  	cmd := exec.Command("docker", "export", id)
    41  	cmd.Stdout = dst
    42  	cmd.Stderr = &stderr
    43  
    44  	log.Printf("Exporting container: %s", id)
    45  	if err := cmd.Start(); err != nil {
    46  		return err
    47  	}
    48  
    49  	if err := cmd.Wait(); err != nil {
    50  		err = fmt.Errorf("Error exporting: %s\nStderr: %s",
    51  			err, stderr.String())
    52  		return err
    53  	}
    54  
    55  	return nil
    56  }
    57  
    58  func (d *DockerDriver) Import(path string, repo string) (string, error) {
    59  	var stdout bytes.Buffer
    60  	cmd := exec.Command("docker", "import", "-", repo)
    61  	cmd.Stdout = &stdout
    62  	stdin, err := cmd.StdinPipe()
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  
    67  	// There should be only one artifact of the Docker builder
    68  	file, err := os.Open(path)
    69  	if err != nil {
    70  		return "", err
    71  	}
    72  	defer file.Close()
    73  
    74  	if err := cmd.Start(); err != nil {
    75  		return "", err
    76  	}
    77  
    78  	go func() {
    79  		defer stdin.Close()
    80  		io.Copy(stdin, file)
    81  	}()
    82  
    83  	if err := cmd.Wait(); err != nil {
    84  		err = fmt.Errorf("Error importing container: %s", err)
    85  		return "", err
    86  	}
    87  
    88  	return strings.TrimSpace(stdout.String()), nil
    89  }
    90  
    91  func (d *DockerDriver) Pull(image string) error {
    92  	cmd := exec.Command("docker", "pull", image)
    93  	return runAndStream(cmd, d.Ui)
    94  }
    95  
    96  func (d *DockerDriver) Push(name string) error {
    97  	cmd := exec.Command("docker", "push", name)
    98  	return runAndStream(cmd, d.Ui)
    99  }
   100  
   101  func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) {
   102  	// Build up the template data
   103  	var tplData startContainerTemplate
   104  	tplData.Image = config.Image
   105  	if len(config.Volumes) > 0 {
   106  		volumes := make([]string, 0, len(config.Volumes))
   107  		for host, guest := range config.Volumes {
   108  			volumes = append(volumes, fmt.Sprintf("%s:%s", host, guest))
   109  		}
   110  
   111  		tplData.Volumes = strings.Join(volumes, ",")
   112  	}
   113  
   114  	// Args that we're going to pass to Docker
   115  	args := config.RunCommand
   116  	for i, v := range args {
   117  		var err error
   118  		args[i], err = d.Tpl.Process(v, &tplData)
   119  		if err != nil {
   120  			return "", err
   121  		}
   122  	}
   123  	d.Ui.Message(fmt.Sprintf(
   124  		"Run command: docker %s", strings.Join(args, " ")))
   125  
   126  	// Start the container
   127  	var stdout, stderr bytes.Buffer
   128  	cmd := exec.Command("docker", args...)
   129  	cmd.Stdout = &stdout
   130  	cmd.Stderr = &stderr
   131  
   132  	log.Printf("Starting container with args: %v", args)
   133  	if err := cmd.Start(); err != nil {
   134  		return "", err
   135  	}
   136  
   137  	log.Println("Waiting for container to finish starting")
   138  	if err := cmd.Wait(); err != nil {
   139  		if _, ok := err.(*exec.ExitError); ok {
   140  			err = fmt.Errorf("Docker exited with a non-zero exit status.\nStderr: %s",
   141  				stderr.String())
   142  		}
   143  
   144  		return "", err
   145  	}
   146  
   147  	// Capture the container ID, which is alone on stdout
   148  	return strings.TrimSpace(stdout.String()), nil
   149  }
   150  
   151  func (d *DockerDriver) StopContainer(id string) error {
   152  	return exec.Command("docker", "kill", id).Run()
   153  }
   154  
   155  func (d *DockerDriver) Verify() error {
   156  	if _, err := exec.LookPath("docker"); err != nil {
   157  		return err
   158  	}
   159  
   160  	return nil
   161  }