From e4dc5d31d86c05a43dedcbe3b1c6ea7ad2870c84 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Sep 2014 15:48:42 -0700 Subject: [PATCH] builder/docker: support volumes --- CHANGELOG.md | 1 + builder/docker/config.go | 14 +++++++++++-- builder/docker/driver.go | 1 - builder/docker/driver_docker.go | 20 ++++++++----------- builder/docker/step_run.go | 9 ++++++--- .../source/docs/builders/docker.html.markdown | 4 ++++ 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb865606..7e9312e72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ FEATURES: binaries named `packer-TYPE-NAME`. * builder/docker: Images can now be committed instead of exported. [GH-1198] * builder/docker: Can now specify login credentials to pull images. + * builder/docker: Support mounting additional volumes. [GH-1430] * builder/virtualbox-ovf: New `import_flags` setting can be used to add new command line flags to `VBoxManage import` to allow things such as EULAs to be accepted. [GH-1383] diff --git a/builder/docker/config.go b/builder/docker/config.go index 7d52b3856..dda726225 100644 --- a/builder/docker/config.go +++ b/builder/docker/config.go @@ -14,6 +14,7 @@ type Config struct { Image string Pull bool RunCommand []string `mapstructure:"run_command"` + Volumes map[string]string Login bool LoginEmail string `mapstructure:"login_email"` @@ -41,9 +42,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { // Defaults if len(c.RunCommand) == 0 { c.RunCommand = []string{ - "run", "-d", "-i", "-t", - "-v", "{{.Volumes}}", "{{.Image}}", "/bin/bash", } @@ -82,6 +81,17 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } } + for k, v := range c.Volumes { + var err error + v, err = c.tpl.Process(v, nil) + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Error processing volumes[%s]: %s", k, err)) + } + + c.Volumes[k] = v + } + if c.Image == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("image must be specified")) diff --git a/builder/docker/driver.go b/builder/docker/driver.go index 6ecd4af02..f1f3ac368 100644 --- a/builder/docker/driver.go +++ b/builder/docker/driver.go @@ -60,5 +60,4 @@ type ContainerConfig struct { // This is the template that is used for the RunCommand in the ContainerConfig. type startContainerTemplate struct { Image string - Volumes string } diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index ab1c1637d..bfba23c14 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -185,23 +185,19 @@ func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) { // Build up the template data var tplData startContainerTemplate tplData.Image = config.Image - if len(config.Volumes) > 0 { - volumes := make([]string, 0, len(config.Volumes)) - for host, guest := range config.Volumes { - volumes = append(volumes, fmt.Sprintf("%s:%s", host, guest)) - } - - tplData.Volumes = strings.Join(volumes, ",") - } // Args that we're going to pass to Docker - args := config.RunCommand - for i, v := range args { - var err error - args[i], err = d.Tpl.Process(v, &tplData) + args := []string{"run"} + for host, guest := range config.Volumes { + args = append(args, "-v", fmt.Sprintf("%s:%s", host, guest)) + } + for _, v := range config.RunCommand { + v, err := d.Tpl.Process(v, &tplData) if err != nil { return "", err } + + args = append(args, v) } d.Ui.Message(fmt.Sprintf( "Run command: docker %s", strings.Join(args, " "))) diff --git a/builder/docker/step_run.go b/builder/docker/step_run.go index 97ec8c4cb..7a46ce0e3 100644 --- a/builder/docker/step_run.go +++ b/builder/docker/step_run.go @@ -19,11 +19,14 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { runConfig := ContainerConfig{ Image: config.Image, RunCommand: config.RunCommand, - Volumes: map[string]string{ - tempDir: "/packer-files", - }, + Volumes: make(map[string]string), } + for host, container := range config.Volumes { + runConfig.Volumes[host] = container + } + runConfig.Volumes[tempDir] = "/packer-files" + ui.Say("Starting docker container...") containerId, err := driver.StartContainer(&runConfig) if err != nil { diff --git a/website/source/docs/builders/docker.html.markdown b/website/source/docs/builders/docker.html.markdown index a72bf7606..61064a91a 100644 --- a/website/source/docs/builders/docker.html.markdown +++ b/website/source/docs/builders/docker.html.markdown @@ -95,6 +95,10 @@ described. `["run", "-d", "-i", "-t", "-v", "{{.Volumes}}", "{{.Image}}", "/bin/bash"]`. As you can see, you have a couple template variables to customize, as well. +* `volumes` (map of strings to strings) - A mapping of additional volumes + to mount into this container. The key of the object is the host path, + the value is the container path. + ## Using the Artifact: Export Once the tar artifact has been generated, you will likely want to import, tag,