diff --git a/app_setup/templates/local_settings.py.j2 b/app_setup/templates/local_settings.py.j2 index 8957e770d2..8a95ec3b9c 100644 --- a/app_setup/templates/local_settings.py.j2 +++ b/app_setup/templates/local_settings.py.j2 @@ -36,7 +36,7 @@ DATABASES = { } } -if 'test' in sys.argv: +if 'test' in sys.argv or 'ACOM_TEST_DATABASE_NAME' in os.environ: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/lib/main/management/commands/__init__.py b/lib/main/management/commands/__init__.py index cede6997f6..cf3f1d2813 100644 --- a/lib/main/management/commands/__init__.py +++ b/lib/main/management/commands/__init__.py @@ -15,3 +15,40 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . + +import os +import sys + +def run_command_as_script(command_name): + ''' + Helper function to run the given management command directly as a script. + + Include something like the following in your management/commands/blah.py: + + if __name__ == '__main__': + from __init__ import run_command_as_script + command_name = os.path.splitext(os.path.basename(__file__))[0] + run_command_as_script(command_name) + + ''' + # The DJANGO_SETTINGS_MODULE environment variable should already be set if + # the script is called from a celery task. + settings_module_name = os.environ.setdefault('DJANGO_SETTINGS_MODULE', + 'lib.settings') + # This sys.path hack is needed when a celery task calls ansible-playbook + # and needs to execute the script directly. FIXME: Figure out if this will + # work when installed in a production environment. + try: + settings_parent_module = __import__(settings_module_name) + except ImportError: + top_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..') + sys.path.insert(0, os.path.abspath(top_dir)) + settings_parent_module = __import__(settings_module_name) + settings_module = getattr(settings_parent_module, settings_module_name.split('.')[-1]) + # Use the ACOM_TEST_DATABASE_NAME environment variable to specify the test + # database name when called from unit tests. + if os.environ.get('ACOM_TEST_DATABASE_NAME', None): + settings_module.DATABASES['default']['NAME'] = os.environ['ACOM_TEST_DATABASE_NAME'] + from django.core.management import execute_from_command_line + argv = [sys.argv[0], command_name] + sys.argv[1:] + execute_from_command_line(argv) diff --git a/lib/main/management/commands/acom_callback_event.py b/lib/main/management/commands/acom_callback_event.py new file mode 100644 index 0000000000..1c7ef33dcd --- /dev/null +++ b/lib/main/management/commands/acom_callback_event.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# Copyright (c) 2013 AnsibleWorks, Inc. +# +# This file is part of Ansible Commander +# +# Ansible Commander is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + +import json +from optparse import make_option +import os +import sys +from django.core.management.base import BaseCommand, CommandError + +class Command(BaseCommmand): + + help = 'Ansible Commander Callback Event Capture' + + option_list = BaseCommmand.option_list + ( + make_option('-i', '--launch-job-status', dest='launch_job_status_id', + type='int', default=0, + help='Inventory ID (can also be specified using ' + 'ACOM_INVENTORY_ID environment variable)'), + #make_option('--indent', dest='indent', type='int', default=None, + # help='Indentation level for pretty printing output'), + ) + + def handle(self, *args, **options): + from lib.main.models import LaunchJobStatus + try: + launch_job_status_id = int(os.getenv('ACOM_LAUNCH_JOB_STATUS_ID', + options.get('launch_job_status_id', 0))) + except ValueError: + raise CommandError('Launch job status ID must be an integer') + if not launch_job_status_id: + raise CommandError('No launch job status ID specified') + try: + launch_job_status = LaunchJobStatus.objects.get(id=launch_job_status_id) + except Inventory.DoesNotExist: + raise CommandError('Launch job status with ID %d not found' % launch_job_status_id) + # FIXME: Do stuff here. + +if __name__ == '__main__': + from __init__ import run_command_as_script + command_name = os.path.splitext(os.path.basename(__file__))[0] + run_command_as_script(command_name) diff --git a/lib/main/management/commands/acom_inventory.py b/lib/main/management/commands/acom_inventory.py index 707d0d09e7..248bc33405 100755 --- a/lib/main/management/commands/acom_inventory.py +++ b/lib/main/management/commands/acom_inventory.py @@ -75,7 +75,10 @@ class Command(NoArgsCommand): try: from lib.main.models import Inventory try: - inventory_id = int(os.getenv('ACOM_INVENTORY_ID', options.get('inventory', 0))) + # Command line argument takes precedence over environment + # variable. + inventory_id = int(options.get('inventory', 0) or \ + os.getenv('ACOM_INVENTORY_ID', 0)) except ValueError: raise CommandError('Inventory ID must be an integer') if not inventory_id: @@ -101,23 +104,6 @@ class Command(NoArgsCommand): raise if __name__ == '__main__': - # FIXME: The DJANGO_SETTINGS_MODULE environment variable *should* already - # be set if this script is called from a celery task. - settings_module_name = os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lib.settings') - # FIXME: Not particularly fond of this sys.path hack, but it is needed - # when a celery task calls ansible-playbook and needs to execute this - # script directly. - try: - settings_parent_module = __import__(settings_module_name) - except ImportError: - top_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..') - sys.path.insert(0, os.path.abspath(top_dir)) - settings_parent_module = __import__(settings_module_name) - settings_module = getattr(settings_parent_module, settings_module_name.split('.')[-1]) - # Use the ACOM_TEST_DATABASE_NAME environment variable to specify the test - # database name when called from unit tests. - if os.environ.get('ACOM_TEST_DATABASE_NAME', None): - settings_module.DATABASES['default']['NAME'] = os.environ['ACOM_TEST_DATABASE_NAME'] - from django.core.management import execute_from_command_line - argv = [sys.argv[0], 'acom_inventory'] + sys.argv[1:] - execute_from_command_line(argv) + from __init__ import run_command_as_script + command_name = os.path.splitext(os.path.basename(__file__))[0] + run_command_as_script(command_name) diff --git a/lib/main/tests/commands.py b/lib/main/tests/commands.py index 15d53a935d..72f2c566fd 100644 --- a/lib/main/tests/commands.py +++ b/lib/main/tests/commands.py @@ -139,6 +139,15 @@ class AcomInventoryTest(BaseCommandTest): group = inventory.groups.get(name=k) self.assertEqual(set(v), set(group.hosts.values_list('name', flat=True))) + # Command line argument for inventory ID should take precedence over + # environment variable. + inventory_pks = set(map(lambda x: x.pk, self.inventories)) + invalid_id = [x for x in xrange(9999) if x not in inventory_pks][0] + os.environ['ACOM_INVENTORY_ID'] = str(invalid_id) + result, stdout, stderr = self.run_command('acom_inventory', list=True, + inventory=inventory.pk) + self.assertEqual(result, None) + data = json.loads(stdout) def test_list_with_inventory_id_in_environment(self): inventory = self.inventories[1] diff --git a/lib/settings/defaults.py b/lib/settings/defaults.py index 47adaeb948..7e000efc00 100644 --- a/lib/settings/defaults.py +++ b/lib/settings/defaults.py @@ -137,12 +137,12 @@ INSTALLED_APPS = ( 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.staticfiles', - 'lib.main', 'south', 'rest_framework', 'django_extensions', 'djcelery', 'kombu.transport.django', + 'lib.main', ) INTERNAL_IPS = ('127.0.0.1',) diff --git a/requirements.txt b/requirements.txt index 4998782ca7..97580bc262 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,12 @@ -Django==1.5 +Django==1.5.1 django-celery==3.0.11 django-devserver==0.5.0 django-extensions==1.1.1 django-jsonfield==0.9.2 ipython==0.13.1 -South==0.7.6 +# psycopg2==2.4.6 python-dateutil==1.5 +South==0.7.6 requests djangorestframework markdown