From fed4262ee2dcd928e73b181b1095b1fb4659795d Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Thu, 19 Feb 2015 11:27:40 -0500 Subject: [PATCH] Some light implimentation details for basic fact caching and collection --- .../commands/run_callback_receiver.py | 4 +- .../commands/run_fact_cache_receiver.py | 27 ++++++++++++++ awx/main/tasks.py | 4 ++ awx/playbooks/scan_facts.yml | 5 +++ awx/plugins/fact_caching/tower.py | 27 ++++++++++++++ awx/plugins/library/scan_packages.py | 37 +++++++++++++++++++ 6 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 awx/main/management/commands/run_fact_cache_receiver.py create mode 100644 awx/playbooks/scan_facts.yml create mode 100644 awx/plugins/fact_caching/tower.py create mode 100755 awx/plugins/library/scan_packages.py diff --git a/awx/main/management/commands/run_callback_receiver.py b/awx/main/management/commands/run_callback_receiver.py index e883a1963c..6bad56ef03 100644 --- a/awx/main/management/commands/run_callback_receiver.py +++ b/awx/main/management/commands/run_callback_receiver.py @@ -89,7 +89,7 @@ class CallbackReceiver(object): queue_worker[2] = w if workers_changed: signal.signal(signal.SIGINT, shutdown_handler([p[2] for p in worker_queues] + [main_process])) - signal.signal(signal.SIGTERM, shutdown_handler([p[2] for p in worker_queues] + [main_process])) + signal.signal(signal.SIGTERM, shutdown_handler([p[2] for p in worker_queues] + [main_process])) if not main_process.is_alive(): sys.exit(1) time.sleep(0.1) @@ -241,7 +241,7 @@ class Command(NoArgsCommand): Save Job Callback receiver (see awx.plugins.callbacks.job_event_callback) Runs as a management command and receives job save events. It then hands them off to worker processors (see Worker) which writes them to the database - ''' + ''' help = 'Launch the job callback receiver' def handle_noargs(self, **options): diff --git a/awx/main/management/commands/run_fact_cache_receiver.py b/awx/main/management/commands/run_fact_cache_receiver.py new file mode 100644 index 0000000000..0ed5b1e921 --- /dev/null +++ b/awx/main/management/commands/run_fact_cache_receiver.py @@ -0,0 +1,27 @@ +# Copyright (c) 2015 Ansible, Inc. +# All Rights Reserved + +import logging + +from django.core.management.base import NoArgsCommand + +from awx.main.models import * # noqa + +logger = logging.getLogger('awx.main.commands.run_fact_cache_receiver') + +class FactCacheReceiver(object): + pass + +class Command(NoArgsCommand): + ''' + blah blah + ''' + help = 'Launch the Fact Cache Receiver' + + def handle_noargs(self, **options): + fcr = FactCacheReceiver() + try: + fcr.run_receiver() + except KeyboardInterrupt: + pass + diff --git a/awx/main/tasks.py b/awx/main/tasks.py index dde73b2159..5e3393f417 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -550,6 +550,10 @@ class RunJob(BaseTask): env['JOB_ID'] = str(job.pk) env['INVENTORY_ID'] = str(job.inventory.pk) env['ANSIBLE_CALLBACK_PLUGINS'] = plugin_dir + # TODO: env['ANSIBLE_LIBRARY'] # plugins/library + # TODO: env['ANSIBLE_CACHE_PLUGINS'] # plugins/fact_caching + # TODD: env['ANSIBLE_CACHE_PLUGIN'] # tower + # TODO: env['ANSIBLE_CACHE_PLUGIN_CONNECTION'] # connection to tower service env['REST_API_URL'] = settings.INTERNAL_API_URL env['REST_API_TOKEN'] = job.task_auth_token or '' env['CALLBACK_CONSUMER_PORT'] = str(settings.CALLBACK_CONSUMER_PORT) diff --git a/awx/playbooks/scan_facts.yml b/awx/playbooks/scan_facts.yml new file mode 100644 index 0000000000..252c284631 --- /dev/null +++ b/awx/playbooks/scan_facts.yml @@ -0,0 +1,5 @@ +- hosts: all + gather_facts: no + tasks: + - scan_packages: + diff --git a/awx/plugins/fact_caching/tower.py b/awx/plugins/fact_caching/tower.py new file mode 100644 index 0000000000..1f4122d493 --- /dev/null +++ b/awx/plugins/fact_caching/tower.py @@ -0,0 +1,27 @@ +from ansible.cache.base import BaseCacheModule + +class TowerCacheModule(BaseCacheModule): + + def __init__(self, *args, **kwargs): + pass + + def get(self, key): + pass + + def set(self, key, value): + pass + + def keys(self): + pass + + def contains(self, key): + pass + + def delete(self, key): + pass + + def flush(self): + pass + + def copy(self): + pass diff --git a/awx/plugins/library/scan_packages.py b/awx/plugins/library/scan_packages.py new file mode 100755 index 0000000000..00188d686f --- /dev/null +++ b/awx/plugins/library/scan_packages.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import os +from ansible.module_utils.basic import * + +def rpm_package_list(): + import rpm + trans_set = rpm.TransactionSet() + installed_packages = [] + for package in trans_set.dbMatch(): + installed_packages.append({'name': package['name'], + 'version': "%s" % (package['version'])}) + return installed_packages + +def deb_package_list(): + import apt + apt_cache = apt.Cache() + installed_packages = [] + apt_installed_packages = [pk for pk in apt_cache.keys() if apt_cache[pk].is_installed] + for package in apt_installed_packages: + installed_packages.append({'name': package, + 'version': apt_cache[package].installed.version}) + return installed_packages + +def main(): + module = AnsibleModule( + argument_spec = dict()) + + packages = [] + if os.path.exists("/etc/redhat-release"): + packages = rpm_package_list() + elif os.path.exists("/etc/os-release"): + packages = deb_package_list() + results = dict(ansible_facts=dict(packages=packages)) + module.exit_json(**results) + +main()