mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 04:10:44 -03:30
Merge pull request #6218 from AlanCoding/scm_inv_cancel
SCM inventory cancel propagation
This commit is contained in:
commit
2b15d04096
@ -1381,6 +1381,8 @@ class InventoryUpdate(UnifiedJob, InventorySourceOptions, JobNotificationMixin):
|
||||
res = super(InventoryUpdate, self).cancel(job_explanation=job_explanation)
|
||||
if res:
|
||||
map(lambda x: x.cancel(job_explanation=self._build_job_explanation()), self.get_dependent_jobs())
|
||||
if self.launch_type != 'scm' and self.source_project_update:
|
||||
self.source_project_update.cancel(job_explanation=job_explanation)
|
||||
return res
|
||||
|
||||
|
||||
|
||||
@ -501,6 +501,13 @@ class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin):
|
||||
update_fields.append('scm_delete_on_next_update')
|
||||
parent_instance.save(update_fields=update_fields)
|
||||
|
||||
def cancel(self, job_explanation=None):
|
||||
res = super(ProjectUpdate, self).cancel(job_explanation=job_explanation)
|
||||
if res and self.launch_type != 'sync':
|
||||
for inv_src in self.scm_inventory_updates.filter(status='running'):
|
||||
inv_src.cancel(job_explanation='Source project update `{}` was canceled.'.format(self.name))
|
||||
return res
|
||||
|
||||
'''
|
||||
JobNotificationMixin
|
||||
'''
|
||||
|
||||
@ -1361,6 +1361,7 @@ class RunProjectUpdate(BaseTask):
|
||||
def _update_dependent_inventories(self, project_update, dependent_inventory_sources):
|
||||
project_request_id = '' if self.request.id is None else self.request.id
|
||||
scm_revision = project_update.project.scm_revision
|
||||
inv_update_class = InventoryUpdate._get_task_class()
|
||||
for inv_src in dependent_inventory_sources:
|
||||
if not inv_src.update_on_project_update:
|
||||
continue
|
||||
@ -1381,15 +1382,23 @@ class RunProjectUpdate(BaseTask):
|
||||
status='running',
|
||||
celery_task_id=str(project_request_id),
|
||||
source_project_update=project_update))
|
||||
inv_update_task = local_inv_update._get_task_class()
|
||||
try:
|
||||
task_instance = inv_update_task()
|
||||
task_instance = inv_update_class()
|
||||
# Runs in the same Celery task as project update
|
||||
task_instance.request.id = project_request_id
|
||||
task_instance.run(local_inv_update.id)
|
||||
except Exception as e:
|
||||
# A failed file update does not block other actions
|
||||
logger.error('Encountered error updating project dependent inventory: {}'.format(e))
|
||||
|
||||
# Stop all dependent inventory updates if project update was canceled
|
||||
project_update.refresh_from_db()
|
||||
if project_update.cancel_flag:
|
||||
break
|
||||
# Don't update inventory scm_revision if update was canceled
|
||||
local_inv_update.refresh_from_db()
|
||||
if local_inv_update.cancel_flag:
|
||||
continue
|
||||
inv_src.scm_last_revision = scm_revision
|
||||
inv_src.save(update_fields=['scm_last_revision'])
|
||||
|
||||
@ -1433,7 +1442,6 @@ class RunProjectUpdate(BaseTask):
|
||||
if instance.launch_type == 'sync':
|
||||
self.release_lock(instance)
|
||||
p = instance.project
|
||||
dependent_inventory_sources = p.scm_inventory_sources.all()
|
||||
if instance.job_type == 'check' and status not in ('failed', 'canceled',):
|
||||
fd = open(self.revision_path, 'r')
|
||||
lines = fd.readlines()
|
||||
@ -1442,11 +1450,11 @@ class RunProjectUpdate(BaseTask):
|
||||
else:
|
||||
logger.info("Could not find scm revision in check")
|
||||
p.playbook_files = p.playbooks
|
||||
if len(dependent_inventory_sources) > 0:
|
||||
p.inventory_files = p.inventories
|
||||
p.inventory_files = p.inventories
|
||||
p.save()
|
||||
|
||||
# Update any inventories that depend on this project
|
||||
dependent_inventory_sources = p.scm_inventory_sources.filter(update_on_project_update=True)
|
||||
if len(dependent_inventory_sources) > 0:
|
||||
if status == 'successful' and instance.launch_type != 'sync':
|
||||
self._update_dependent_inventories(instance, dependent_inventory_sources)
|
||||
|
||||
@ -3,7 +3,7 @@ import mock
|
||||
import os
|
||||
|
||||
from awx.main.tasks import RunProjectUpdate, RunInventoryUpdate
|
||||
from awx.main.models import ProjectUpdate, InventoryUpdate
|
||||
from awx.main.models import ProjectUpdate, InventoryUpdate, InventorySource
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -43,3 +43,32 @@ class TestDependentInventoryUpdate:
|
||||
inv_update = InventoryUpdate.objects.first()
|
||||
iu_run_mock.assert_called_once_with(inv_update.id)
|
||||
assert inv_update.source_project_update_id == proj_update.pk
|
||||
|
||||
def test_dependent_inventory_project_cancel(self, project, inventory):
|
||||
'''
|
||||
Test that dependent inventory updates exhibit good behavior on cancel
|
||||
of the source project update
|
||||
'''
|
||||
task = RunProjectUpdate()
|
||||
proj_update = ProjectUpdate.objects.create(project=project)
|
||||
|
||||
kwargs = dict(
|
||||
source_project=project,
|
||||
source='scm',
|
||||
source_path='inventory_file',
|
||||
update_on_project_update=True,
|
||||
inventory=inventory
|
||||
)
|
||||
|
||||
is1 = InventorySource.objects.create(name="test-scm-inv", **kwargs)
|
||||
is2 = InventorySource.objects.create(name="test-scm-inv2", **kwargs)
|
||||
|
||||
def user_cancels_project(pk):
|
||||
ProjectUpdate.objects.all().update(cancel_flag=True)
|
||||
|
||||
with mock.patch.object(RunInventoryUpdate, 'run') as iu_run_mock:
|
||||
iu_run_mock.side_effect = user_cancels_project
|
||||
task._update_dependent_inventories(proj_update, [is1, is2])
|
||||
# Verify that it bails after 1st update, detecting a cancel
|
||||
assert is2.inventory_updates.count() == 0
|
||||
iu_run_mock.assert_called_once()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user