builder/docker: customize run command [GH-648]

This commit is contained in:
Mitchell Hashimoto 2013-12-27 10:17:45 -07:00
parent be7861080b
commit 037a744be5
7 changed files with 49 additions and 11 deletions

View File

@ -45,6 +45,8 @@ IMPROVEMENTS:
"Packer Builder" so that they are easily recognizable. [GH-642]
* builder/amazon/all: Copying AMIs to multiple regions now happens
in parallel. [GH-495]
* builder/docker: A "run\_command" can be specified, configuring how
the container is started. [GH-648]
* builder/openstack: In debug mode, the generated SSH keypair is saved
so you can SSH into the machine. [GH-746]
* builder/qemu: Floppy files are supported. [GH-686]

View File

@ -25,7 +25,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
driver := &DockerDriver{Ui: ui}
driver := &DockerDriver{Tpl: b.config.tpl, Ui: ui}
if err := driver.Verify(); err != nil {
return nil, err
}

View File

@ -12,6 +12,7 @@ type Config struct {
ExportPath string `mapstructure:"export_path"`
Image string
Pull bool
RunCommand []string `mapstructure:"run_command"`
tpl *packer.ConfigTemplate
}
@ -28,6 +29,17 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
return nil, nil, err
}
// Defaults
if len(c.RunCommand) == 0 {
c.RunCommand = []string{
"run",
"-d", "-i", "-t",
"-v", "{{.Volumes}}",
"{{.Image}}",
"/bin/bash",
}
}
// Default Pull if it wasn't set
hasPull := false
for _, k := range md.Keys {

View File

@ -27,6 +27,13 @@ type Driver interface {
// ContainerConfig is the configuration used to start a container.
type ContainerConfig struct {
Image string
Volumes map[string]string
Image string
RunCommand []string
Volumes map[string]string
}
// This is the template that is used for the RunCommand in the ContainerConfig.
type startContainerTemplate struct {
Image string
Volumes string
}

View File

@ -11,7 +11,8 @@ import (
)
type DockerDriver struct {
Ui packer.Ui
Ui packer.Ui
Tpl *packer.ConfigTemplate
}
func (d *DockerDriver) Export(id string, dst io.Writer) error {
@ -40,19 +41,29 @@ func (d *DockerDriver) Pull(image string) error {
}
func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) {
// Args that we're going to pass to Docker
args := []string{"run", "-d", "-i", "-t"}
// 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))
}
args = append(args, "-v", strings.Join(volumes, ","))
tplData.Volumes = strings.Join(volumes, ",")
}
args = append(args, config.Image, "/bin/bash")
// 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)
if err != nil {
return "", err
}
}
d.Ui.Message(fmt.Sprintf(
"Run command: docker %s", strings.Join(args, " ")))
// Start the container
var stdout, stderr bytes.Buffer

View File

@ -17,13 +17,14 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
runConfig := ContainerConfig{
Image: config.Image,
Image: config.Image,
RunCommand: config.RunCommand,
Volumes: map[string]string{
tempDir: "/packer-files",
},
}
ui.Say("Starting docker container with /bin/bash")
ui.Say("Starting docker container...")
containerId, err := driver.StartContainer(&runConfig)
if err != nil {
err := fmt.Errorf("Error running container: %s", err)

View File

@ -59,6 +59,11 @@ Optional:
`docker pull` prior to use. Otherwise, it is assumed the image already
exists and can be used. This defaults to true if not set.
* `run_command` (array of strings) - An array of arguments to pass to
`docker` in order to run the container. By default this is set to
`["run", "-d", "-i", "-t", "-v", "{{.Volumes}}", "{{.Image}}", "/bin/bash"]`.
As you can see, you have a couple template variables to customize, as well.
## Using the generated artifact
Once the tar artifact has been generated, you will likely want to import, tag,