Merge pull request #842 from strcrzy/ansible_config_options

provisioner/ansible: more configuration options
This commit is contained in:
Mitchell Hashimoto 2014-02-21 15:24:50 -08:00
commit 4b9a9f5911
3 changed files with 94 additions and 3 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"os" "os"
"path/filepath" "path/filepath"
"strings"
) )
const DefaultStagingDir = "/tmp/packer-provisioner-ansible-local" const DefaultStagingDir = "/tmp/packer-provisioner-ansible-local"
@ -23,9 +24,21 @@ type Config struct {
// An array of local paths of roles to upload. // An array of local paths of roles to upload.
RolePaths []string `mapstructure:"role_paths"` RolePaths []string `mapstructure:"role_paths"`
// Path to group_vars directory
GroupVars string `mapstructure:"group_vars"`
// Path to host_vars directory
HostVars string `mapstructure:"host_vars"`
// The directory where files will be uploaded. Packer requires write // The directory where files will be uploaded. Packer requires write
// permissions in this directory. // permissions in this directory.
StagingDir string `mapstructure:"staging_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 { type Provisioner struct {
@ -48,14 +61,22 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
// Accumulate any errors // Accumulate any errors
errs := common.CheckUnusedConfig(md) errs := common.CheckUnusedConfig(md)
// Defaults
if p.config.StagingDir == "" { if p.config.StagingDir == "" {
p.config.StagingDir = DefaultStagingDir p.config.StagingDir = DefaultStagingDir
} }
if p.config.Command == "" {
p.config.Command = "ansible-playbook"
}
// Templates // Templates
templates := map[string]*string{ templates := map[string]*string{
"playbook_file": &p.config.PlaybookFile, "playbook_file": &p.config.PlaybookFile,
"staging_dir": &p.config.StagingDir, "staging_dir": &p.config.StagingDir,
"command": &p.config.Command,
"group_vars": &p.config.GroupVars,
"host_vars": &p.config.HostVars,
} }
for n, ptr := range templates { for n, ptr := range templates {
@ -68,8 +89,9 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
} }
sliceTemplates := map[string][]string{ sliceTemplates := map[string][]string{
"playbook_paths": p.config.PlaybookPaths, "playbook_paths": p.config.PlaybookPaths,
"role_paths": p.config.RolePaths, "role_paths": p.config.RolePaths,
"extra_arguments": p.config.ExtraArguments,
} }
for n, slice := range sliceTemplates { for n, slice := range sliceTemplates {
@ -99,6 +121,20 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs = packer.MultiErrorAppend(errs, err) errs = packer.MultiErrorAppend(errs, err)
} }
} }
// Check that the group_vars directory exists, if configured
if len(p.config.GroupVars) > 0 {
if err := validateDirConfig(p.config.GroupVars, "group_vars"); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
}
// Check that the host_vars directory exists, if configured
if len(p.config.HostVars) > 0 {
if err := validateDirConfig(p.config.HostVars, "host_vars"); err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
}
if errs != nil && len(errs.Errors) > 0 { if errs != nil && len(errs.Errors) > 0 {
return errs return errs
} }
@ -120,6 +156,26 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return fmt.Errorf("Error uploading main playbook: %s", err) return fmt.Errorf("Error uploading main playbook: %s", err)
} }
// Upload group_vars
if len(p.config.GroupVars) > 0 {
ui.Message("Uploading group_vars directory...")
src := p.config.GroupVars
dst := filepath.Join(p.config.StagingDir, "group_vars")
if err := p.uploadDir(ui, comm, dst, src); err != nil {
return fmt.Errorf("Error uploading group_vars directory: %s", err)
}
}
// Upload host_vars
if len(p.config.HostVars) > 0 {
ui.Message("Uploading host_vars directory...")
src := p.config.HostVars
dst := filepath.Join(p.config.StagingDir, "host_vars")
if err := p.uploadDir(ui, comm, dst, src); err != nil {
return fmt.Errorf("Error uploading host_vars directory: %s", err)
}
}
if len(p.config.RolePaths) > 0 { if len(p.config.RolePaths) > 0 {
ui.Message("Uploading role directories...") ui.Message("Uploading role directories...")
for _, src := range p.config.RolePaths { for _, src := range p.config.RolePaths {
@ -161,7 +217,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 // 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 // as its the only way to override the ansible inventory when dealing
// with a single host. // 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)) ui.Message(fmt.Sprintf("Executing Ansible: %s", command))
cmd := &packer.RemoteCmd{ cmd := &packer.RemoteCmd{

View File

@ -120,4 +120,28 @@ func TestProvisionerPrepare_Dirs(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
config["group_vars"] = playbook_file.Name()
err = p.Prepare(config)
if err == nil {
t.Fatalf("should error if group_vars path is not a dir")
}
config["group_vars"] = os.TempDir()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
config["host_vars"] = playbook_file.Name()
err = p.Prepare(config)
if err == nil {
t.Fatalf("should error if host_vars path is not a dir")
}
config["host_vars"] = os.TempDir()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
} }

View File

@ -34,6 +34,11 @@ Required:
Optional: 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 * `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 your local system. These will be uploaded to the remote machine under
`staging_directory`/playbooks. By default, this is empty. `staging_directory`/playbooks. By default, this is empty.