From 971521502bff4d1d7ab4c03077142a379ad6c726 Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Mon, 22 Nov 2021 20:17:07 -0500 Subject: ansible_plugin.py: Extend ansible plugin parameters Add the ability to optionally configure: - The inventory group name - The Ansible tags to be executed - An Ansible configuration file - An `extra_vars` dictionary to be passed to the playbook This enables existing image-creation builds with complex Ansible playbooks to be converted to use vmdb2. --- vmdb/plugins/ansible.mdwn | 23 +++++++++++++++++--- vmdb/plugins/ansible_plugin.py | 48 ++++++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/vmdb/plugins/ansible.mdwn b/vmdb/plugins/ansible.mdwn index fa014ad..3e17f99 100644 --- a/vmdb/plugins/ansible.mdwn +++ b/vmdb/plugins/ansible.mdwn @@ -10,9 +10,20 @@ Step keys: * `ansible` — REQUIRED; value is the tag of the root filesystem. +* `config_file` — OPTIONAL; value is the filename of an Ansible + configuration file, relative to the .vmdb file. + +* `group` — OPTIONAL; the name of the Ansible inventory group. Defaults + to "image" + * `playbook` — REQUIRED; value is the filename of the Ansible playbook, relative to the .vmdb file. +* `tags` — OPTIONAL; a comma-separated list of Ansible tags to execute + +* `extra_vars` — OPTIONAL; a dictionary defining variables to pass to the + Ansible playbook. + Example (in the .vmdb file): - apt: install @@ -21,6 +32,12 @@ Example (in the .vmdb file): - ansible: root playbook: foo.yml + tags: bar + config_file: ansible.cfg + group: AwesomeGroup + extra_vars: + iface: + name: eth0 Example (`foo.yml`): @@ -38,9 +55,9 @@ Example (`foo.yml`): - name: "configure networking" copy: content: | - auto eth0 - iface eth0 inet dhcp - iface eth0 inet6 auto + auto {{ iface.name }} + iface {{ iface.name }} inet dhcp + iface {{ iface.name }} inet6 auto dest: /etc/network/interfaces.d/wired vars: diff --git a/vmdb/plugins/ansible_plugin.py b/vmdb/plugins/ansible_plugin.py index d237c5b..564a321 100644 --- a/vmdb/plugins/ansible_plugin.py +++ b/vmdb/plugins/ansible_plugin.py @@ -15,10 +15,11 @@ # # =*= License: GPL-3+ =*= - import os import tempfile +import yaml + import vmdb @@ -29,24 +30,43 @@ class AnsiblePlugin(vmdb.Plugin): class AnsibleStepRunner(vmdb.StepRunnerInterface): def get_key_spec(self): - return {"ansible": str, "playbook": str} + return { + "ansible": str, + "playbook": str, + "group": "image", + "tags": "all", + "config_file": "", + "extra_vars": {}, + } def run(self, values, settings, state): tag = values["ansible"] playbook = values["playbook"] + ansible_tags = values["tags"] + group_name = values["group"] + config_file = values["config_file"] + extra_vars = values["extra_vars"] mount_point = state.tags.get_builder_mount_point(tag) rootfs_tarball = settings["rootfs-tarball"] - state.ansible_inventory = self.create_inventory(mount_point) + state.ansible_inventory = self.create_inventory(mount_point, group_name) vmdb.progress( "Created {} for Ansible inventory".format(state.ansible_inventory) ) - vars_filename = self.create_vars(rootfs_tarball) - vmdb.progress("Created {} for Ansible variables".format(vars_filename)) + extra_vars['rootfs_tarball'] = rootfs_tarball + state.ansible_vars_file = self.create_vars_file(extra_vars) + vmdb.progress(f"Created {state.ansible_vars_file} for Ansible variables") env = dict(os.environ) env["ANSIBLE_NOCOWS"] = "1" + if config_file: + if os.path.exists(config_file): + env["ANSIBLE_CONFIG"] = config_file + vmdb.progress(f"Using Ansible config file {config_file}") + else: + raise RuntimeError( + f"Ansible config file {config_file} does not exist") vmdb.runcmd( [ "ansible-playbook", @@ -54,26 +74,32 @@ class AnsibleStepRunner(vmdb.StepRunnerInterface): "chroot", "-i", state.ansible_inventory, + "--tags", + ansible_tags, "-e", - "@{}".format(vars_filename), + f"@{state.ansible_vars_file}", playbook, ], env=env, ) def teardown(self, values, settings, state): + if hasattr(state, "ansible_vars_file"): + vmdb.progress(f"Removing {state.ansible_vars_file}") + os.remove(state.ansible_vars_file) + if hasattr(state, "ansible_inventory"): vmdb.progress("Removing {}".format(state.ansible_inventory)) os.remove(state.ansible_inventory) - def create_inventory(self, chroot): + def create_inventory(self, chroot, group_name): fd, filename = tempfile.mkstemp() - os.write(fd, "[image]\n{}\n".format(chroot).encode()) + os.write(fd, f"[{group_name}]\n{chroot}\n".encode()) os.close(fd) return filename - def create_vars(self, tarball): - fd, filename = tempfile.mkstemp() - os.write(fd, 'rootfs_tarball: "{}"\n'.format(tarball).encode()) + def create_vars_file(self, extra_vars): + fd, filename = tempfile.mkstemp(suffix=".yaml") + os.write(fd, yaml.dump(extra_vars).encode()) os.close(fd) return filename -- cgit v1.2.1