Commit 4f186fbd authored by Ross Smith II's avatar Ross Smith II

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

parents fe3131f6 6d56def1
......@@ -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:
......
......@@ -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,
......
......@@ -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()
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment