Merge pull request #1006 from jgornick/add-ansible-inventory-file (manually)

This commit is contained in:
Ross Smith II 2014-04-21 07:57:24 -07:00
commit 4f186fbd6e
4 changed files with 103 additions and 7 deletions

View File

@ -14,6 +14,7 @@ IMPROVEMENTS:
* builder/vmware: add cloning support on Windows [GH-824]
* command/build: Added '-parallel' flag so you can disable parallelization
with `-no-parallel`. [GH-924]
* provisioner/ansible: Add inventory_file option [GH-1006]
BUG FIXES:

View File

@ -39,6 +39,9 @@ type Config struct {
// The directory where files will be uploaded. Packer requires write
// permissions in this directory.
StagingDir string `mapstructure:"staging_directory"`
// The optional inventory file
InventoryFile string `mapstructure:"inventory_file"`
}
type Provisioner struct {
@ -72,11 +75,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
// Templates
templates := map[string]*string{
"command": &p.config.Command,
"group_vars": &p.config.GroupVars,
"host_vars": &p.config.HostVars,
"playbook_file": &p.config.PlaybookFile,
"staging_dir": &p.config.StagingDir,
"command": &p.config.Command,
"group_vars": &p.config.GroupVars,
"host_vars": &p.config.HostVars,
"playbook_file": &p.config.PlaybookFile,
"staging_dir": &p.config.StagingDir,
"inventory_file": &p.config.InventoryFile,
}
for n, ptr := range templates {
@ -111,6 +115,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs = packer.MultiErrorAppend(errs, err)
}
// Check that the inventory file exists, if configured
if len(p.config.InventoryFile) > 0 {
err = validateFileConfig(p.config.InventoryFile, "inventory_file", true)
if err != nil {
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 {
@ -158,6 +170,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return fmt.Errorf("Error uploading main playbook: %s", err)
}
if len(p.config.InventoryFile) > 0 {
ui.Message("Uploading inventory file...")
src := p.config.InventoryFile
dst := filepath.Join(p.config.StagingDir, filepath.Base(src))
if err := p.uploadFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Error uploading inventory file: %s", err)
}
}
if len(p.config.GroupVars) > 0 {
ui.Message("Uploading group_vars directory...")
src := p.config.GroupVars
@ -217,13 +238,18 @@ 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.
inventory := "\"127.0.0.1,\""
if len(p.config.InventoryFile) > 0 {
inventory = filepath.Join(p.config.StagingDir, filepath.Base(p.config.InventoryFile))
}
extraArgs := ""
if len(p.config.ExtraArguments) > 0 {
extraArgs = " " + strings.Join(p.config.ExtraArguments, " ")
}
command := fmt.Sprintf("cd %s && %s %s%s -c local -i \"127.0.0.1,\"",
p.config.StagingDir, p.config.Command, playbook, extraArgs)
command := fmt.Sprintf("cd %s && %s %s%s -c local -i %s",
p.config.StagingDir, p.config.Command, playbook, extraArgs, inventory)
ui.Message(fmt.Sprintf("Executing Ansible: %s", command))
cmd := &packer.RemoteCmd{
Command: command,

View File

@ -70,6 +70,46 @@ func TestProvisionerPrepare_PlaybookFile(t *testing.T) {
}
}
func TestProvisionerPrepare_InventoryFile(t *testing.T) {
var p Provisioner
config := testConfig()
err := p.Prepare(config)
if err == nil {
t.Fatal("should have error")
}
config["playbook_file"] = ""
err = p.Prepare(config)
if err == nil {
t.Fatal("should have error")
}
playbook_file, err := ioutil.TempFile("", "playbook")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(playbook_file.Name())
config["playbook_file"] = playbook_file.Name()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
inventory_file, err := ioutil.TempFile("", "inventory")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(inventory_file.Name())
config["inventory_file"] = inventory_file.Name()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
}
func TestProvisionerPrepare_Dirs(t *testing.T) {
var p Provisioner
config := testConfig()

View File

@ -39,6 +39,35 @@ Optional:
* `extra_arguments` (array of strings) - An array of extra arguments to pass to the
ansible command. By default, this is empty.
* `inventory_file` (string) - The inventory file to be used by ansible.
This file must exist on your local system and will be uploaded to the
remote machine.
When using an inventory file, it's also required to `--limit` the hosts to
the specified host you're buiding. The `--limit` argument can be provided in
the `extra_arguments` option.
An example inventory file may look like:
<pre class="prettyprint">
[chi-dbservers]
db-01 ansible_connection=local
db-02 ansible_connection=local
[chi-appservers]
app-01 ansible_connection=local
app-02 ansible_connection=local
[chi:children]
chi-dbservers
chi-appservers
[dbservers:children]
chi-dbservers
[appservers:children]
chi-appservers
</pre>
* `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.