Commit 86350856 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/docker: make Import part of this Driver for reuse

parent 34dbf721
...@@ -14,6 +14,9 @@ type Driver interface { ...@@ -14,6 +14,9 @@ type Driver interface {
// Export exports the container with the given ID to the given writer. // Export exports the container with the given ID to the given writer.
Export(id string, dst io.Writer) error 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 should pull down the given image.
Pull(image string) error Pull(image string) error
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io" "io"
"log" "log"
"os"
"os/exec" "os/exec"
"strings" "strings"
) )
...@@ -54,6 +55,39 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error { ...@@ -54,6 +55,39 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error {
return nil 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 { func (d *DockerDriver) Pull(image string) error {
cmd := exec.Command("docker", "pull", image) cmd := exec.Command("docker", "pull", image)
return runAndStream(cmd, d.Ui) return runAndStream(cmd, d.Ui)
......
...@@ -10,6 +10,12 @@ type MockDriver struct { ...@@ -10,6 +10,12 @@ type MockDriver struct {
DeleteImageId string DeleteImageId string
DeleteImageErr error DeleteImageErr error
ImportCalled bool
ImportPath string
ImportRepo string
ImportId string
ImportErr error
ExportReader io.Reader ExportReader io.Reader
ExportError error ExportError error
PullError error PullError error
...@@ -49,6 +55,13 @@ func (d *MockDriver) Export(id string, dst io.Writer) error { ...@@ -49,6 +55,13 @@ func (d *MockDriver) Export(id string, dst io.Writer) error {
return d.ExportError 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 { func (d *MockDriver) Pull(image string) error {
d.PullCalled = true d.PullCalled = true
d.PullImage = image d.PullImage = image
......
package dockerimport package dockerimport
import ( import (
"bytes"
"fmt" "fmt"
"github.com/mitchellh/packer/builder/docker" "github.com/mitchellh/packer/builder/docker"
"github.com/mitchellh/packer/common" "github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io"
"os"
"os/exec"
"strings"
) )
const BuilderId = "packer.post-processor.docker-import" const BuilderId = "packer.post-processor.docker-import"
...@@ -74,43 +69,18 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ...@@ -74,43 +69,18 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
importRepo += ":" + p.config.Tag importRepo += ":" + p.config.Tag
} }
var stdout bytes.Buffer driver := &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui}
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()
ui.Message("Importing image: " + artifact.Id()) ui.Message("Importing image: " + artifact.Id())
ui.Message("Repository: " + importRepo) ui.Message("Repository: " + importRepo)
id, err := driver.Import(artifact.Files()[0], importRepo)
if err := cmd.Start(); err != nil { 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 return nil, false, err
} }
id := strings.TrimSpace(stdout.String())
ui.Message("Imported ID: " + id) ui.Message("Imported ID: " + id)
// Build the artifact // Build the artifact
driver := &docker.DockerDriver{Tpl: p.config.tpl, Ui: ui}
artifact = &docker.ImportArtifact{ artifact = &docker.ImportArtifact{
BuilderIdValue: BuilderId, BuilderIdValue: BuilderId,
Driver: driver, Driver: driver,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment