mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
Fixes AC-361. Host last_job is updated whenever job is marked inactive or deleted.
This commit is contained in:
@@ -134,3 +134,43 @@ def migrate_children_from_inactive_group_to_parent_groups(sender, **kwargs):
|
|||||||
child_group, parent_group, instance)
|
child_group, parent_group, instance)
|
||||||
parent_group.children.add(child_group)
|
parent_group.children.add(child_group)
|
||||||
parent_group.children.remove(instance)
|
parent_group.children.remove(instance)
|
||||||
|
|
||||||
|
# Update host pointers to last_job and last_job_host_summary when a job is
|
||||||
|
# marked inactive or deleted.
|
||||||
|
|
||||||
|
def _update_host_last_jhs(host):
|
||||||
|
jhs_qs = JobHostSummary.objects.filter(job__active=True, host__pk=host.pk)
|
||||||
|
try:
|
||||||
|
jhs = jhs_qs.order_by('-job__pk')[0]
|
||||||
|
except IndexError:
|
||||||
|
jhs = None
|
||||||
|
update_fields = []
|
||||||
|
last_job = jhs.job if jhs else None
|
||||||
|
if host.last_job != last_job:
|
||||||
|
host.last_job = last_job
|
||||||
|
update_fields.append('last_job')
|
||||||
|
if host.last_job_host_summary != jhs:
|
||||||
|
host.last_job_host_summary = jhs
|
||||||
|
update_fields.append('last_job_host_summary')
|
||||||
|
if update_fields:
|
||||||
|
host.save(update_fields=update_fields)
|
||||||
|
|
||||||
|
@receiver(post_save, sender=Job)
|
||||||
|
def update_host_last_job_when_job_marked_inactive(sender, **kwargs):
|
||||||
|
instance = kwargs['instance']
|
||||||
|
hosts_qs = Host.objects.filter(active=True, last_job__pk=instance.pk)
|
||||||
|
for host in hosts_qs:
|
||||||
|
_update_host_last_jhs(host)
|
||||||
|
|
||||||
|
@receiver(pre_delete, sender=Job)
|
||||||
|
def save_host_pks_before_job_delete(sender, **kwargs):
|
||||||
|
instance = kwargs['instance']
|
||||||
|
hosts_qs = Host.objects.filter(active=True, last_job__pk=instance.pk)
|
||||||
|
instance._saved_hosts_pks = set(hosts_qs.values_list('pk', flat=True))
|
||||||
|
|
||||||
|
@receiver(post_delete, sender=Job)
|
||||||
|
def update_host_last_job_after_job_deleted(sender, **kwargs):
|
||||||
|
instance = kwargs['instance']
|
||||||
|
hosts_pks = getattr(instance, '_saved_hosts_pks', [])
|
||||||
|
for host in Host.objects.filter(pk__in=hosts_pks):
|
||||||
|
_update_host_last_jhs(host)
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
# Copyright (c) 2013 AnsibleWorks, Inc.
|
# Copyright (c) 2013 AnsibleWorks, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
# Python
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
from django.utils.timezone import now
|
||||||
|
|
||||||
|
# AWX
|
||||||
from awx.main.models import *
|
from awx.main.models import *
|
||||||
from awx.main.tests.base import BaseLiveServerTest
|
from awx.main.tests.base import BaseLiveServerTest
|
||||||
from awx.main.tasks import RunJob
|
from awx.main.tasks import RunJob
|
||||||
@@ -203,7 +209,7 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
|
|
||||||
def create_test_job_template(self, **kwargs):
|
def create_test_job_template(self, **kwargs):
|
||||||
opts = {
|
opts = {
|
||||||
'name': 'test-job-template',
|
'name': 'test-job-template %s' % str(now()),
|
||||||
'inventory': self.inventory,
|
'inventory': self.inventory,
|
||||||
'project': self.project,
|
'project': self.project,
|
||||||
'credential': self.credential,
|
'credential': self.credential,
|
||||||
@@ -223,7 +229,7 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
self.job = job_template.create_job(**kwargs)
|
self.job = job_template.create_job(**kwargs)
|
||||||
else:
|
else:
|
||||||
opts = {
|
opts = {
|
||||||
'name': 'test-job',
|
'name': 'test-job %s' % str(now()),
|
||||||
'inventory': self.inventory,
|
'inventory': self.inventory,
|
||||||
'project': self.project,
|
'project': self.project,
|
||||||
'credential': self.credential,
|
'credential': self.credential,
|
||||||
@@ -397,6 +403,7 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
self.assertEqual(job.unreachable_hosts.count(), 0)
|
self.assertEqual(job.unreachable_hosts.count(), 0)
|
||||||
self.assertEqual(job.skipped_hosts.count(), 0)
|
self.assertEqual(job.skipped_hosts.count(), 0)
|
||||||
self.assertEqual(job.processed_hosts.count(), 1)
|
self.assertEqual(job.processed_hosts.count(), 1)
|
||||||
|
return job
|
||||||
|
|
||||||
def test_check_job(self):
|
def test_check_job(self):
|
||||||
self.create_test_project(TEST_PLAYBOOK)
|
self.create_test_project(TEST_PLAYBOOK)
|
||||||
@@ -424,6 +431,7 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
self.assertEqual(job.unreachable_hosts.count(), 0)
|
self.assertEqual(job.unreachable_hosts.count(), 0)
|
||||||
self.assertEqual(job.skipped_hosts.count(), 1)
|
self.assertEqual(job.skipped_hosts.count(), 1)
|
||||||
self.assertEqual(job.processed_hosts.count(), 1)
|
self.assertEqual(job.processed_hosts.count(), 1)
|
||||||
|
return job
|
||||||
|
|
||||||
def test_run_job_that_fails(self):
|
def test_run_job_that_fails(self):
|
||||||
self.create_test_project(TEST_PLAYBOOK2)
|
self.create_test_project(TEST_PLAYBOOK2)
|
||||||
@@ -539,6 +547,11 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
job.name = '_'.join(job.name.split('_')[3:]) or 'undeleted job'
|
job.name = '_'.join(job.name.split('_')[3:]) or 'undeleted job'
|
||||||
job.active = True
|
job.active = True
|
||||||
job.save()
|
job.save()
|
||||||
|
# Need to manually update last_job on host...
|
||||||
|
host = Host.objects.get(pk=self.host.pk)
|
||||||
|
host.last_job = job
|
||||||
|
host.last_job_host_summary = JobHostSummary.objects.get(job=job, host=host)
|
||||||
|
host.save()
|
||||||
job.inventory.update_has_active_failures()
|
job.inventory.update_has_active_failures()
|
||||||
self.host = Host.objects.get(pk=self.host.pk)
|
self.host = Host.objects.get(pk=self.host.pk)
|
||||||
self.assertTrue(self.host.has_active_failures)
|
self.assertTrue(self.host.has_active_failures)
|
||||||
@@ -555,6 +568,23 @@ class RunJobTest(BaseCeleryTest):
|
|||||||
self.inventory = Inventory.objects.get(pk=self.inventory.pk)
|
self.inventory = Inventory.objects.get(pk=self.inventory.pk)
|
||||||
self.assertFalse(self.inventory.has_active_failures)
|
self.assertFalse(self.inventory.has_active_failures)
|
||||||
|
|
||||||
|
def test_update_host_last_job_when_job_removed(self):
|
||||||
|
job1 = self.test_run_job()
|
||||||
|
job2 = self.test_run_job()
|
||||||
|
self.host = Host.objects.get(pk=self.host.pk)
|
||||||
|
self.assertEqual(self.host.last_job, job2)
|
||||||
|
self.assertEqual(self.host.last_job_host_summary.job, job2)
|
||||||
|
# Delete job2 (should update host to point to job1).
|
||||||
|
job2.delete()
|
||||||
|
self.host = Host.objects.get(pk=self.host.pk)
|
||||||
|
self.assertEqual(self.host.last_job, job1)
|
||||||
|
self.assertEqual(self.host.last_job_host_summary.job, job1)
|
||||||
|
# Mark job1 inactive (should update host.last_job to None).
|
||||||
|
job1.mark_inactive()
|
||||||
|
self.host = Host.objects.get(pk=self.host.pk)
|
||||||
|
self.assertEqual(self.host.last_job, None)
|
||||||
|
self.assertEqual(self.host.last_job_host_summary, None)
|
||||||
|
|
||||||
def test_check_job_where_task_would_fail(self):
|
def test_check_job_where_task_would_fail(self):
|
||||||
self.create_test_project(TEST_PLAYBOOK2)
|
self.create_test_project(TEST_PLAYBOOK2)
|
||||||
job_template = self.create_test_job_template()
|
job_template = self.create_test_job_template()
|
||||||
|
|||||||
Reference in New Issue
Block a user