Merge pull request #9903 from artis3n/ansible-collections

Ansible Galaxy Collections support in Ansible provisioner
This commit is contained in:
Megan Marsh 2020-09-08 12:34:39 -07:00 committed by GitHub
commit 26f3299fb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 112 additions and 14 deletions

View File

@ -162,8 +162,8 @@ type Config struct {
// test your playbook. this option is not used if you set an `inventory_file`.
KeepInventoryFile bool `mapstructure:"keep_inventory_file"`
// A requirements file which provides a way to
// install roles with the [ansible-galaxy
// cli](http://docs.ansible.com/ansible/galaxy.html#the-ansible-galaxy-command-line-tool)
// install roles or collections with the [ansible-galaxy
// cli](https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#the-ansible-galaxy-command-line-tool)
// on the local machine before executing `ansible-playbook`. By default, this is empty.
GalaxyFile string `mapstructure:"galaxy_file"`
// The command to invoke ansible-galaxy. By default, this is
@ -173,11 +173,16 @@ type Config struct {
// Adds `--force` option to `ansible-galaxy` command. By default, this is
// `false`.
GalaxyForceInstall bool `mapstructure:"galaxy_force_install"`
// The path to the directory on your local system to
// install the roles in. Adds `--roles-path /path/to/your/roles` to
// The path to the directory on your local system in which to
// install the roles. Adds `--roles-path /path/to/your/roles` to
// `ansible-galaxy` command. By default, this is empty, and thus `--roles-path`
// option is not added to the command.
RolesPath string `mapstructure:"roles_path"`
// The path to the directory on your local system in which to
// install the collections. Adds `--collections-path /path/to/your/collections` to
// `ansible-galaxy` command. By default, this is empty, and thus `--collections-path`
// option is not added to the command.
CollectionsPath string `mapstructure:"collections_path"`
// When `true`, set up a localhost proxy adapter
// so that Ansible has an IP address to connect to, even if your guest does not
// have an IP address. For example, the adapter is necessary for Docker builds
@ -624,16 +629,38 @@ func (p *Provisioner) executeGalaxy(ui packer.Ui, comm packer.Communicator) erro
galaxyFile := filepath.ToSlash(p.config.GalaxyFile)
// ansible-galaxy install -r requirements.yml
args := []string{"install", "-r", galaxyFile}
roleArgs := []string{"install", "-r", galaxyFile}
// Instead of modifying args depending on config values and removing or modifying values from
// the slice between role and collection installs, just use 2 slices and simplify everything
collectionArgs := []string{"collection", "install", "-r", galaxyFile}
// Add force to arguments
if p.config.GalaxyForceInstall {
args = append(args, "-f")
}
// Add roles_path argument if specified
if p.config.RolesPath != "" {
args = append(args, "-p", filepath.ToSlash(p.config.RolesPath))
roleArgs = append(roleArgs, "-f")
collectionArgs = append(collectionArgs, "-f")
}
// Add roles_path argument if specified
if p.config.RolesPath != "" {
roleArgs = append(roleArgs, "-p", filepath.ToSlash(p.config.RolesPath))
}
// Add collections_path argument if specified
if p.config.CollectionsPath != "" {
collectionArgs = append(collectionArgs, "-p", filepath.ToSlash(p.config.CollectionsPath))
}
roleInstallError := p.invokeGalaxyCommand(roleArgs, ui, comm)
// Return the error if the role installation failed before attempting the collection install
if roleInstallError != nil {
return roleInstallError
}
// If all is well, proceed with collection install
// This variable isn't strictly necessary but including for readability to match the role installation
collectionInstallError := p.invokeGalaxyCommand(collectionArgs, ui, comm)
return collectionInstallError
}
// Intended to be invoked from p.executeGalaxy depending on the Ansible Galaxy parameters passed to Packer
func (p *Provisioner) invokeGalaxyCommand(args []string, ui packer.Ui, comm packer.Communicator) error {
ui.Message(fmt.Sprintf("Executing Ansible Galaxy"))
cmd := exec.Command(p.config.GalaxyCommand, args...)

View File

@ -39,6 +39,7 @@ type FlatConfig struct {
GalaxyCommand *string `mapstructure:"galaxy_command" cty:"galaxy_command" hcl:"galaxy_command"`
GalaxyForceInstall *bool `mapstructure:"galaxy_force_install" cty:"galaxy_force_install" hcl:"galaxy_force_install"`
RolesPath *string `mapstructure:"roles_path" cty:"roles_path" hcl:"roles_path"`
CollectionsPath *string `mapstructure:"collections_path" cty:"collections_path" hcl:"collections_path"`
UseProxy *bool `mapstructure:"use_proxy" cty:"use_proxy" hcl:"use_proxy"`
}
@ -84,6 +85,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"galaxy_command": &hcldec.AttrSpec{Name: "galaxy_command", Type: cty.String, Required: false},
"galaxy_force_install": &hcldec.AttrSpec{Name: "galaxy_force_install", Type: cty.Bool, Required: false},
"roles_path": &hcldec.AttrSpec{Name: "roles_path", Type: cty.String, Required: false},
"collections_path": &hcldec.AttrSpec{Name: "collections_path", Type: cty.String, Required: false},
"use_proxy": &hcldec.AttrSpec{Name: "use_proxy", Type: cty.Bool, Required: false},
}
return s

View File

@ -0,0 +1,33 @@
---
- hosts: default:packer-test
gather_facts: no
collections:
- artis3n.github
tasks:
- name: touch
raw: touch /tmp/ansible-raw-test
- name: raw test
raw: date
- name: command test
command: echo "the command module"
- name: prepare remote directory
command: mkdir /tmp/remote-dir
args:
creates: /tmp/remote-dir
- name: transfer file.txt
copy: src=dir/file.txt dest=/tmp/remote-dir/file.txt
- name: fetch file.text
fetch: src=/tmp/remote-dir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
- name: copy contents of directory
copy: src=dir/contents-only/ dest=/tmp/remote-dir
- name: fetch contents of directory
fetch: src=/tmp/remote-dir/file.txt dest="fetched-dir/{{ inventory_hostname }}/tmp/remote-dir/contents-only/" flat=yes validate=yes fail_on_missing=yes
- name: copy directory recursively
copy: src=dir/subdir dest=/tmp/remote-dir
- name: fetch recursively copied directory
fetch: src=/tmp/remote-dir/subdir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
- copy: src=largish-file.txt dest=/tmp/largish-file.txt
- name: test collection - fetch latest repo version
set_fact:
# Ansible will fail if collection is not installed
packer_version: "{{ lookup('artis3n.github.latest_release', 'hashicorp/packer' }}"

View File

@ -0,0 +1,21 @@
{
"variables": {},
"provisioners": [
{
"type": "ansible",
"playbook_file": "./galaxy-playbook.yml",
"galaxy_file": "./requirements.yml"
}
],
"builders": [
{
"type": "googlecompute",
"account_file": "{{user `account_file`}}",
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-galaxy-{{timestamp}}",
"source_image": "debian-8-jessie-v20161027",
"zone": "us-central1-a",
"ssh_username": "debian"
}
]
}

View File

@ -0,0 +1,2 @@
collections:
- name: artis3n.github

View File

@ -65,6 +65,14 @@ teardown() {
diff -r dir fetched-dir/packer-test/tmp/remote-dir > /dev/null
}
@test "ansible provisioner: build galaxy.json" {
cd $FIXTURE_ROOT
run packer build ${USER_VARS} $FIXTURE_ROOT/galaxy.json
[ "$status" -eq 0 ]
[ "$(gc_has_image "packerbats-galaxy")" -eq 1 ]
diff -r dir fetched-dir/default/tmp/remote-dir > /dev/null
}
@test "ansible provisioner: build scp.json" {
cd $FIXTURE_ROOT
run packer build ${USER_VARS} $FIXTURE_ROOT/scp.json

View File

@ -120,8 +120,8 @@
test your playbook. this option is not used if you set an `inventory_file`.
- `galaxy_file` (string) - A requirements file which provides a way to
install roles with the [ansible-galaxy
cli](http://docs.ansible.com/ansible/galaxy.html#the-ansible-galaxy-command-line-tool)
install roles or collections with the [ansible-galaxy
cli](https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#the-ansible-galaxy-command-line-tool)
on the local machine before executing `ansible-playbook`. By default, this is empty.
- `galaxy_command` (string) - The command to invoke ansible-galaxy. By default, this is
@ -131,11 +131,16 @@
Adds `--force` option to `ansible-galaxy` command. By default, this is
`false`.
- `roles_path` (string) - The path to the directory on your local system to
install the roles in. Adds `--roles-path /path/to/your/roles` to
- `roles_path` (string) - The path to the directory on your local system in which to
install the roles. Adds `--roles-path /path/to/your/roles` to
`ansible-galaxy` command. By default, this is empty, and thus `--roles-path`
option is not added to the command.
- `collections_path` (string) - The path to the directory on your local system in which to
install the collections. Adds `--collections-path /path/to/your/collections` to
`ansible-galaxy` command. By default, this is empty, and thus `--collections-path`
option is not added to the command.
- `use_proxy` (boolean) - When `true`, set up a localhost proxy adapter
so that Ansible has an IP address to connect to, even if your guest does not
have an IP address. For example, the adapter is necessary for Docker builds