Skip to content

Instantly share code, notes, and snippets.

@unconfigured
Last active July 2, 2018 17:48
Show Gist options
  • Save unconfigured/7322099b6d0380db81a6 to your computer and use it in GitHub Desktop.
Save unconfigured/7322099b6d0380db81a6 to your computer and use it in GitHub Desktop.
cobbler post install trigger to start ansible after provisioning
#!/usr/bin/python
#
# Post install trigger for cobbler to
# kick of an ansible run on the target system.
# You can place an ansible.cfg in the same
# directory as your main playbook, so all
# stuff like inventory file etc. will be
# found the same way as if you run
# ansible-playbook in this directory
#
# Installation: This file goes to
# /usr/lib/python-x.y/site-packages/cobbler/modules/install_post_ansible.py
#
# To test, you can use the following url:
# http://<host>/cblr/svc/op/trig/mode/firstboot/system/<sysname>
#
# Please extend your cobblers settings with
# the following options:
#
# # Enable Ansible runs
# run_ansible: 1
# # Where to find the main playbook
# run_ansible_playbook: /path/to/site.yml
__requires__ = ['ansible']
import sys
import os
import traceback
import distutils.sysconfig
plib = distutils.sysconfig.get_python_lib()
mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
import utils
from ansible.playbook import PlayBook
import ansible.constants as C
import ansible.callbacks
from ansible.errors import AnsibleError
def register():
return "/var/lib/cobbler/triggers/install/firstboot/*"
def run(api, args, logger):
logger.debug("ansible trigger entered")
objtype = args[0] # "target" or "profile"
name = args[1] # name of target or profile
boot_ip = args[2] # ip or "?"
# Only run on systems
if objtype != "system":
logger.debug("ansible trigger called, but objtype is not a system")
return 0
# Should we run?
settings = api.settings()
if not str(settings.run_ansible).lower() in [ "1", "yes", "y", "true"]:
logger.debug("ansible trigger called, but deaktivated")
return 0
# Which playbook to run?
playbook = str(settings.run_ansible_playbook)
if not playbook:
logger.error("Please specify run_ansible_playbook when enabling ansible")
return 0
if not os.path.exists(playbook):
logger.error("the given playbook does not exists")
return 0
target = api.find_system(name)
target = utils.blender(api, False, target)
if target == {}:
logger.error("failure looking up target")
raise CX("failure looking up target")
# Get the systems dns name
hostname = target['hostname']
old_cwd = os.getcwd()
os.chdir(os.path.dirname(playbook))
if not os.path.exists(os.getcwd() + "/ansible.cfg"):
logger.debug("No ansible.cfg in playbook dir %s" % os.getcwd())
# Reload the constants module, as it does the initialization
# of the ansible environment based on cwd
reload(C)
logger.debug("Using inventory file %s" % C.DEFAULT_HOST_LIST )
inventory = ansible.inventory.Inventory(C.DEFAULT_HOST_LIST)
inventory.subset(hostname)
if inventory.list_hosts() == []:
logger.error("Host %s is not in inventory" % hostname)
return 0
stats = ansible.callbacks.AggregateStats()
playbook_cb = ansible.callbacks.PlaybookCallbacks()
runner_cb = ansible.callbacks.PlaybookRunnerCallbacks(stats)
pb = PlayBook(
playbook=playbook,
inventory=inventory,
callbacks=playbook_cb,
runner_callbacks=runner_cb,
stats=stats
)
pb.SETUP_CACHE.flush() # Flush facts, this is a new install
try:
pb.run()
os.chdir(old_cwd)
logger.debug("running playbook")
for h in pb.stats.processed.keys():
t = pb.stats.summarize(h)
logger.info("OK: %i, Changed: %i, Failed: %i Unreachable: %i" % ( t['ok'], t['changed'], t['failures'], t['unreachable'] ) )
except AnsibleError, e:
logger.error("Ansible returned an error: %s" % e)
return 0
return 0
@SeanThomasWilliams
Copy link

The logger is provided from whatever calls run()

@lamb84
Copy link

lamb84 commented May 26, 2016

Hi,

I am running ansible version 2.0.2.0
I cannot import PlayBook, callbacks or AnsibleError

Can you please update it for the newer version?

Thanks,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment