mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 12:20:45 -03:30
SCM inventory cancel propagation
For manually initiated inventory updates, also cancel the source project of "sync" type, like jobs do For automatic inventory updates spawned from source project update, of launch type "scm", handle contigency cases
This commit is contained in:
parent
55c2f5a2d6
commit
04d6fb1f95
@ -1393,6 +1393,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
|
||||
'''
|
||||
|
||||
@ -1391,6 +1391,15 @@ class RunProjectUpdate(BaseTask):
|
||||
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'])
|
||||
|
||||
|
||||
@ -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