Skip to content

Instantly share code, notes, and snippets.

@mgedmin
Last active August 29, 2015 14:27
Show Gist options
  • Save mgedmin/02642faeb6d78c38e42b to your computer and use it in GitHub Desktop.
Save mgedmin/02642faeb6d78c38e42b to your computer and use it in GitHub Desktop.

Given tasks like

- command: foo
  when: foo_condition
  register: foo_result
  
- changelog: msg="ran foo"
  when: foo_result|changed
  
- command: bar
  when: bar_condition
  register: bar_result
  
- changelog: msg="ran bar"
  when: bar_result|changed

I want the changelog action to run

  • if both foo_condition and bar_condition were true:
new-changelog-entry "ran foo"
new-changelog-entry -a "ran bar"
  • if foo_condition was true and bar_condition was false:
new-changelog-entry "ran foo"
  • if foo_condition was false and bar_condition was true:
new-changelog-entry "ran bar"

It should, of course, work with more than just two entries.

# action_plugins/changelog.py
from ansible.runner.action_plugins import normal
from ansible.runner.return_data import ReturnData
class ActionModule(normal.ActionModule):
'''Add entries to /root/Changelog'''
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
if self.runner.noop_on_check(inject):
return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module'))
host = inject['inventory_hostname']
changelog_started = inject['hostvars'][host].get('changelog_started', False)
complex_args.setdefault('append', changelog_started)
return super(ActionModule, self).run(conn, tmp, module_name, module_args, inject, complex_args=complex_args, **kwargs)
#!/usr/bin/python
# library/changelog.py
import os
import subprocess
from ansible.module_utils.basic import * # noqa
DOCUMENTATION = '''
---
module: changelog
short_description: appends a message to /root/Changelog
description:
- The M(changelog) module takes single a string message and appends it
to /root/Changelog on the remote host, with a date and time header.
- This requires pov-admin-tools to be installed on the remote.
options:
msg:
description:
- the message
required: true
default: null
append:
description:
- append the message to the existing entry instead of starting a new entry
required: false
default: false for the 1st invocation on each host, true for all subsequent invocations
author:
- Marius Gedminas <[email protected]>
'''
EXAMPLES = '''
# Prerequisite: install pov-admin-tools from ppa:pov
- apt_repository: repo='ppa:pov' state=present
- apt: name=pov-admin-tools state=present
# Record new installed package iff it was installed
- apt: name=postfix state=present
record: apt_result
- changelog: msg="apt-get install postfix"
when: apt_result|changed
'''
def main():
module = AnsibleModule(
argument_spec=dict(
msg=dict(),
append=dict(type='bool', default=False)
),
)
msg = module.params['msg']
append = module.params['append']
if msg in ('-a', '-e', '/root/Changelog') or os.path.exists(msg):
module.fail_json(msg="message cannot be '{}' due to the way new-changelog-message parses its arguments".format(msg))
args = ['new-changelog-entry']
if append:
args += ['-a']
args += [msg]
try:
cmd = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = cmd.communicate()
rc = cmd.returncode
except (OSError, IOError) as e:
module.fail_json(rc=e.errno, msg=str(e), cmd=args)
module.exit_json(
message=msg,
rc=rc,
out=out,
err=err,
changed=True,
ansible_facts=dict(
changelog_started=True,
)
)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment