From 8635085665e6cad4fbf7c1de3c2aaed2e33bcfa4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 19 Jan 2014 19:55:01 -0800 Subject: [PATCH] builder/docker: make Import part of this Driver for reuse --- builder/docker/driver.go | 3 ++ builder/docker/driver_docker.go | 34 ++++++++++++++++++ builder/docker/driver_mock.go | 13 +++++++ .../docker-import/post-processor.go | 36 ++----------------- 4 files changed, 53 insertions(+), 33 deletions(-) diff --git a/builder/docker/driver.go b/builder/docker/driver.go index 174cc8ef2..ad9bff11f 100644 --- a/builder/docker/driver.go +++ b/builder/docker/driver.go @@ -14,6 +14,9 @@ type Driver interface { // Export exports the container with the given ID to the given writer. Export(id string, dst io.Writer) error + // Import imports a container from a tar file + Import(path, repo string) (string, error) + // Pull should pull down the given image. Pull(image string) error diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index f55adaba9..b78fc2a21 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -6,6 +6,7 @@ import ( "github.com/mitchellh/packer/packer" "io" "log" + "os" "os/exec" "strings" ) @@ -54,6 +55,39 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error { return nil } +func (d *DockerDriver) Import(path string, repo string) (string, error) { + var stdout bytes.Buffer + cmd := exec.Command("docker", "import", "-", repo) + cmd.Stdout = &stdout + stdin, err := cmd.StdinPipe() + if err != nil { + return "", err + } + + // There should be only one artifact of the Docker builder + file, err := os.Open(path) + if err != nil { + return "", err + } + defer file.Close() + + if err := cmd.Start(); err != nil { + return "", err + } + + go func() { + defer stdin.Close() + io.Copy(stdin, file) + }() + + if err := cmd.Wait(); err != nil { + err = fmt.Errorf("Error importing container: %s", err) + return "", err + } + + return strings.TrimSpace(stdout.String()), nil +} + func (d *DockerDriver) Pull(image string) error { cmd := exec.Command("docker", "pull", image) return runAndStream(cmd, d.Ui) diff --git a/builder/docker/driver_mock.go b/builder/docker/driver_mock.go index 7fa118b28..a737c3240 100644 --- a/builder/docker/driver_mock.go +++ b/builder/docker/driver_mock.go @@ -10,6 +10,12 @@ type MockDriver struct { DeleteImageId string DeleteImageErr error + ImportCalled bool + ImportPath string + ImportRepo string + ImportId string + ImportErr error + ExportReader io.Reader ExportError error PullError error @@ -49,6 +55,13 @@ func (d *MockDriver) Export(id string, dst io.Writer) error { return d.ExportError } +func (d *MockDriver) Import(path, repo string) (string, error) { + d.ImportCalled = true + d.ImportPath = path + d.ImportRepo = repo + return d.ImportId, d.ImportErr +} + func (d *MockDriver) Pull(image string) error { d.PullCalled = true d.PullImage = image diff --git a/post-processor/docker-import/post-processor.go b/post-processor/docker-import/post-processor.go index dcc9f7bac..639e2798e 100644 --- a/post-processor/docker-import/post-processor.go +++ b/post-processor/docker-import/post-processor.go @@ -1,15 +1,10 @@ package dockerimport import ( - "bytes" "fmt" "github.com/mitchellh/packer/builder/docker" "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/packer" - "io" - "os" - "os/exec" - "strings" ) const BuilderId = "packer.post-processor.docker-import" @@ -74,43 +69,18 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac importRepo += ":" + p.config.Tag } - var stdout bytes.Buffer - cmd := exec.Command("docker", "import", "-", importRepo) - cmd.Stdout = &stdout - stdin, err := cmd.StdinPipe() - if err != nil { - return nil, false, err - } - - // There should be only one artifact of the Docker builder - file, err := os.Open(artifact.Files()[0]) - if err != nil { - return nil, false, err - } - defer file.Close() + driver := &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui} ui.Message("Importing image: " + artifact.Id()) ui.Message("Repository: " + importRepo) - - if err := cmd.Start(); err != nil { + id, err := driver.Import(artifact.Files()[0], importRepo) + if err != nil { return nil, false, err } - go func() { - defer stdin.Close() - io.Copy(stdin, file) - }() - - if err := cmd.Wait(); err != nil { - err = fmt.Errorf("Error importing container: %s", err) - return nil, false, err - } - - id := strings.TrimSpace(stdout.String()) ui.Message("Imported ID: " + id) // Build the artifact - driver := &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui} artifact = &docker.ImportArtifact{ BuilderIdValue: BuilderId, Driver: driver,