mirror of
https://github.com/ansible/awx.git
synced 2026-05-20 07:17:40 -02:30
Add support for cleaning up ad hoc commands.
This commit is contained in:
@@ -12,7 +12,7 @@ from django.db import transaction
|
|||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models import Job, ProjectUpdate, InventoryUpdate, SystemJob
|
from awx.main.models import Job, AdHocCommand, ProjectUpdate, InventoryUpdate, SystemJob
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(NoArgsCommand):
|
||||||
'''
|
'''
|
||||||
@@ -30,6 +30,9 @@ class Command(NoArgsCommand):
|
|||||||
make_option('--jobs', dest='only_jobs', action='store_true',
|
make_option('--jobs', dest='only_jobs', action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Only remove jobs'),
|
help='Only remove jobs'),
|
||||||
|
make_option('--ad-hoc-commands', dest='only_ad_hoc_commands',
|
||||||
|
action='store_true', default=False,
|
||||||
|
help='Only remove ad hoc commands'),
|
||||||
make_option('--project-updates', dest='only_project_updates',
|
make_option('--project-updates', dest='only_project_updates',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Only remove project updates'),
|
help='Only remove project updates'),
|
||||||
@@ -60,6 +63,23 @@ class Command(NoArgsCommand):
|
|||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
job.delete()
|
job.delete()
|
||||||
|
|
||||||
|
def cleanup_ad_hoc_commands(self):
|
||||||
|
for ad_hoc_command in AdHocCommand.objects.all():
|
||||||
|
ad_hoc_command_display = '"%s" (started %s, %d events)' % \
|
||||||
|
(unicode(ad_hoc_command), unicode(ad_hoc_command.created),
|
||||||
|
ad_hoc_command.ad_hoc_command_events.count())
|
||||||
|
if ad_hoc_command.status in ('pending', 'waiting', 'running'):
|
||||||
|
action_text = 'would skip' if self.dry_run else 'skipping'
|
||||||
|
self.logger.debug('%s %s ad hoc command %s', action_text, ad_hoc_command.status, ad_hoc_command_display)
|
||||||
|
elif ad_hoc_command.created >= self.cutoff:
|
||||||
|
action_text = 'would skip' if self.dry_run else 'skipping'
|
||||||
|
self.logger.debug('%s %s', action_text, ad_hoc_command_display)
|
||||||
|
else:
|
||||||
|
action_text = 'would delete' if self.dry_run else 'deleting'
|
||||||
|
self.logger.info('%s %s', action_text, ad_hoc_command_display)
|
||||||
|
if not self.dry_run:
|
||||||
|
ad_hoc_command.delete()
|
||||||
|
|
||||||
def cleanup_project_updates(self):
|
def cleanup_project_updates(self):
|
||||||
for pu in ProjectUpdate.objects.all():
|
for pu in ProjectUpdate.objects.all():
|
||||||
pu_display = '"%s" (started %s)' % (unicode(pu), unicode(pu.created))
|
pu_display = '"%s" (started %s)' % (unicode(pu), unicode(pu.created))
|
||||||
@@ -131,15 +151,13 @@ class Command(NoArgsCommand):
|
|||||||
self.cutoff = now() - datetime.timedelta(days=self.days)
|
self.cutoff = now() - datetime.timedelta(days=self.days)
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
raise CommandError('--days specified is too large. Try something less than 99999 (about 270 years).')
|
raise CommandError('--days specified is too large. Try something less than 99999 (about 270 years).')
|
||||||
self.only_jobs = bool(options.get('only_jobs', False))
|
model_names = ('jobs', 'ad_hoc_commands', 'project_updates', 'inventory_updates', 'management_jobs')
|
||||||
self.only_project_updates = bool(options.get('only_project_updates', False))
|
models_to_cleanup = set()
|
||||||
self.only_inventory_updates = bool(options.get('only_inventory_updates', False))
|
for m in model_names:
|
||||||
self.only_management_jobs = bool(options.get('only_management_jobs', False))
|
if options.get('only_%s' % m, False):
|
||||||
if self.only_jobs or (not self.only_jobs and not self.only_project_updates and not self.only_inventory_updates and not self.only_management_jobs):
|
models_to_cleanup.add(m)
|
||||||
self.cleanup_jobs()
|
if not models_to_cleanup:
|
||||||
if self.only_project_updates or (not self.only_jobs and not self.only_project_updates and not self.only_inventory_updates and not self.only_management_jobs):
|
models_to_cleanup.update(model_names)
|
||||||
self.cleanup_project_updates()
|
for m in model_names:
|
||||||
if self.only_inventory_updates or (not self.only_jobs and not self.only_project_updates and not self.only_inventory_updates and not self.only_management_jobs):
|
if m in models_to_cleanup:
|
||||||
self.cleanup_inventory_updates()
|
getattr(self, 'cleanup_%s' % m)()
|
||||||
if self.only_management_jobs or (not self.only_jobs and not self.only_project_updates and not self.only_inventory_updates and not self.only_management_jobs):
|
|
||||||
self.cleanup_management_jobs()
|
|
||||||
|
|||||||
@@ -362,14 +362,30 @@ class CleanupJobsTest(BaseCommandMixin, BaseLiveServerTest):
|
|||||||
self.job = Job.objects.create(**opts)
|
self.job = Job.objects.create(**opts)
|
||||||
return self.job
|
return self.job
|
||||||
|
|
||||||
|
def create_test_ad_hoc_command(self, **kwargs):
|
||||||
|
opts = {
|
||||||
|
'inventory': self.inventory,
|
||||||
|
'credential': self.credential,
|
||||||
|
'module_name': 'command',
|
||||||
|
'module_args': 'uptime',
|
||||||
|
}
|
||||||
|
opts.update(kwargs)
|
||||||
|
self.ad_hoc_command = AdHocCommand.objects.create(**opts)
|
||||||
|
return self.ad_hoc_command
|
||||||
|
|
||||||
def test_cleanup_jobs(self):
|
def test_cleanup_jobs(self):
|
||||||
# Test with no jobs to be cleaned up.
|
# Test with no jobs to be cleaned up.
|
||||||
jobs_before = Job.objects.all().count()
|
jobs_before = Job.objects.all().count()
|
||||||
self.assertFalse(jobs_before)
|
self.assertFalse(jobs_before)
|
||||||
|
ad_hoc_commands_before = AdHocCommand.objects.all().count()
|
||||||
|
self.assertFalse(ad_hoc_commands_before)
|
||||||
result, stdout, stderr = self.run_command('cleanup_jobs')
|
result, stdout, stderr = self.run_command('cleanup_jobs')
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
jobs_after = Job.objects.all().count()
|
jobs_after = Job.objects.all().count()
|
||||||
self.assertEqual(jobs_before, jobs_after)
|
self.assertEqual(jobs_before, jobs_after)
|
||||||
|
ad_hoc_commands_after = AdHocCommand.objects.all().count()
|
||||||
|
self.assertEqual(ad_hoc_commands_before, ad_hoc_commands_after)
|
||||||
|
|
||||||
# Create and run job.
|
# Create and run job.
|
||||||
self.create_test_project(TEST_PLAYBOOK)
|
self.create_test_project(TEST_PLAYBOOK)
|
||||||
job_template = self.create_test_job_template()
|
job_template = self.create_test_job_template()
|
||||||
@@ -379,29 +395,54 @@ class CleanupJobsTest(BaseCommandMixin, BaseLiveServerTest):
|
|||||||
self.assertTrue(job.signal_start())
|
self.assertTrue(job.signal_start())
|
||||||
job = Job.objects.get(pk=job.pk)
|
job = Job.objects.get(pk=job.pk)
|
||||||
self.assertEqual(job.status, 'successful')
|
self.assertEqual(job.status, 'successful')
|
||||||
|
|
||||||
|
# Create and run ad hoc command.
|
||||||
|
ad_hoc_command = self.create_test_ad_hoc_command()
|
||||||
|
self.assertEqual(ad_hoc_command.status, 'new')
|
||||||
|
self.assertFalse(ad_hoc_command.passwords_needed_to_start)
|
||||||
|
self.assertTrue(ad_hoc_command.signal_start())
|
||||||
|
ad_hoc_command = AdHocCommand.objects.get(pk=ad_hoc_command.pk)
|
||||||
|
self.assertEqual(ad_hoc_command.status, 'successful')
|
||||||
|
|
||||||
# With days=1, no jobs will be deleted.
|
# With days=1, no jobs will be deleted.
|
||||||
jobs_before = Job.objects.all().count()
|
jobs_before = Job.objects.all().count()
|
||||||
self.assertTrue(jobs_before)
|
self.assertTrue(jobs_before)
|
||||||
|
ad_hoc_commands_before = AdHocCommand.objects.all().count()
|
||||||
|
self.assertTrue(ad_hoc_commands_before)
|
||||||
result, stdout, stderr = self.run_command('cleanup_jobs', days=1)
|
result, stdout, stderr = self.run_command('cleanup_jobs', days=1)
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
jobs_after = Job.objects.all().count()
|
jobs_after = Job.objects.all().count()
|
||||||
self.assertEqual(jobs_before, jobs_after)
|
self.assertEqual(jobs_before, jobs_after)
|
||||||
|
ad_hoc_commands_after = AdHocCommand.objects.all().count()
|
||||||
|
self.assertEqual(ad_hoc_commands_before, ad_hoc_commands_after)
|
||||||
|
|
||||||
# With days=0 and dry_run=True, no jobs will be deleted.
|
# With days=0 and dry_run=True, no jobs will be deleted.
|
||||||
jobs_before = Job.objects.all().count()
|
jobs_before = Job.objects.all().count()
|
||||||
self.assertTrue(jobs_before)
|
self.assertTrue(jobs_before)
|
||||||
|
ad_hoc_commands_before = AdHocCommand.objects.all().count()
|
||||||
|
self.assertTrue(ad_hoc_commands_before)
|
||||||
result, stdout, stderr = self.run_command('cleanup_jobs', days=0,
|
result, stdout, stderr = self.run_command('cleanup_jobs', days=0,
|
||||||
dry_run=True)
|
dry_run=True)
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
jobs_after = Job.objects.all().count()
|
jobs_after = Job.objects.all().count()
|
||||||
self.assertEqual(jobs_before, jobs_after)
|
self.assertEqual(jobs_before, jobs_after)
|
||||||
# With days=0, our job will be deleted.
|
ad_hoc_commands_after = AdHocCommand.objects.all().count()
|
||||||
|
self.assertEqual(ad_hoc_commands_before, ad_hoc_commands_after)
|
||||||
|
|
||||||
|
# With days=0, our job and ad hoc command will be deleted.
|
||||||
jobs_before = Job.objects.all().count()
|
jobs_before = Job.objects.all().count()
|
||||||
self.assertTrue(jobs_before)
|
self.assertTrue(jobs_before)
|
||||||
|
ad_hoc_commands_before = AdHocCommand.objects.all().count()
|
||||||
|
self.assertTrue(ad_hoc_commands_before)
|
||||||
result, stdout, stderr = self.run_command('cleanup_jobs', days=0)
|
result, stdout, stderr = self.run_command('cleanup_jobs', days=0)
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
jobs_after = Job.objects.all().count()
|
jobs_after = Job.objects.all().count()
|
||||||
self.assertNotEqual(jobs_before, jobs_after)
|
self.assertNotEqual(jobs_before, jobs_after)
|
||||||
self.assertFalse(jobs_after)
|
self.assertFalse(jobs_after)
|
||||||
|
ad_hoc_commands_after = AdHocCommand.objects.all().count()
|
||||||
|
self.assertNotEqual(ad_hoc_commands_before, ad_hoc_commands_after)
|
||||||
|
self.assertFalse(ad_hoc_commands_after)
|
||||||
|
|
||||||
|
|
||||||
class InventoryImportTest(BaseCommandMixin, BaseLiveServerTest):
|
class InventoryImportTest(BaseCommandMixin, BaseLiveServerTest):
|
||||||
'''
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user