From ec1adec0296ee34f16bf2236ff136caa0ca316cc Mon Sep 17 00:00:00 2001 From: jamie brim Date: Wed, 22 Jan 2014 04:40:06 -0800 Subject: [PATCH] provisioner/ansible: configurable command / args allow users to provide a replacement command / extra args to the ansible-local provisioner. this is useful, for example, to unbuffer output when using the docker builder, or to modify ansible behavior, like enabling verbose mode, injecting variables, or changing paths. --- provisioner/ansible-local/provisioner.go | 26 ++++++++++++++++--- .../provisioners/ansible-local.html.markdown | 5 ++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/provisioner/ansible-local/provisioner.go b/provisioner/ansible-local/provisioner.go index 1347376f0..ff4e0649c 100644 --- a/provisioner/ansible-local/provisioner.go +++ b/provisioner/ansible-local/provisioner.go @@ -6,6 +6,7 @@ import ( "github.com/mitchellh/packer/packer" "os" "path/filepath" + "strings" ) const DefaultStagingDir = "/tmp/packer-provisioner-ansible-local" @@ -26,6 +27,12 @@ type Config struct { // The directory where files will be uploaded. Packer requires write // permissions in this directory. StagingDir string `mapstructure:"staging_directory"` + + // The command to run ansible + Command string + + // Extra options to pass to the ansible command + ExtraArguments []string `mapstructure:"extra_arguments"` } type Provisioner struct { @@ -48,14 +55,20 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { // Accumulate any errors errs := common.CheckUnusedConfig(md) + // Defaults if p.config.StagingDir == "" { p.config.StagingDir = DefaultStagingDir } + if p.config.Command == "" { + p.config.Command = "ansible-playbook" + } + // Templates templates := map[string]*string{ "playbook_file": &p.config.PlaybookFile, "staging_dir": &p.config.StagingDir, + "command": &p.config.Command, } for n, ptr := range templates { @@ -68,8 +81,9 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } sliceTemplates := map[string][]string{ - "playbook_paths": p.config.PlaybookPaths, - "role_paths": p.config.RolePaths, + "playbook_paths": p.config.PlaybookPaths, + "role_paths": p.config.RolePaths, + "extra_arguments": p.config.ExtraArguments, } for n, slice := range sliceTemplates { @@ -161,7 +175,13 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) err // The inventory must be set to "127.0.0.1,". The comma is important // as its the only way to override the ansible inventory when dealing // with a single host. - command := fmt.Sprintf("ansible-playbook %s -c local -i %s", playbook, `"127.0.0.1,"`) + var command string + if len(p.config.ExtraArguments) > 0 { + command = fmt.Sprintf("%s %s %s -c local -i \"127.0.0.1,\"", p.config.Command, + playbook, strings.Join(p.config.ExtraArguments, " ")) + } else { + command = fmt.Sprintf("%s %s -c local -i \"127.0.0.1,\"", p.config.Command, playbook) + } ui.Message(fmt.Sprintf("Executing Ansible: %s", command)) cmd := &packer.RemoteCmd{ diff --git a/website/source/docs/provisioners/ansible-local.html.markdown b/website/source/docs/provisioners/ansible-local.html.markdown index 6c309d7ba..a5e423509 100644 --- a/website/source/docs/provisioners/ansible-local.html.markdown +++ b/website/source/docs/provisioners/ansible-local.html.markdown @@ -34,6 +34,11 @@ Required: Optional: +* `command` (string) - The command to invoke ansible. Defaults to "ansible-playbook". + +* `extra_arguments` (array of strings) - An array of extra arguments to pass to the + ansible command. By default, this is empty. + * `playbook_paths` (array of strings) - An array of paths to playbook files on your local system. These will be uploaded to the remote machine under `staging_directory`/playbooks. By default, this is empty.