From 880341ac05a6578e8d5746354fc169dca74f3a58 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 5 Apr 2019 13:10:08 -0400 Subject: [PATCH 1/2] avoid slicing if the inventory only has 1 host --- awx/main/models/inventory.py | 2 +- awx/main/models/jobs.py | 20 ++++++++++++-------- awx/main/tests/functional/models/test_job.py | 12 +++++++++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index 6004bebba4..dab2b395dc 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -256,7 +256,7 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin, RelatedJobsMixin): if towervars: fetch_fields.append('enabled') hosts = self.hosts.filter(**hosts_kw).order_by('name').only(*fetch_fields) - if slice_count > 1: + if slice_count > 1 and slice_number > 0: offset = slice_number - 1 hosts = hosts[offset::slice_count] diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 2203b7e31a..7e8ceaf192 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -332,9 +332,19 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour ''' return self.create_unified_job(**kwargs) + def get_effective_slice_ct(self, kwargs): + actual_inventory = self.inventory + if self.ask_inventory_on_launch and 'inventory' in kwargs: + actual_inventory = kwargs['inventory'] + if actual_inventory: + return min(self.job_slice_count, actual_inventory.hosts.count()) + else: + return self.job_slice_count + def create_unified_job(self, **kwargs): prevent_slicing = kwargs.pop('_prevent_slicing', False) - slice_event = bool(self.job_slice_count > 1 and (not prevent_slicing)) + slice_ct = self.get_effective_slice_ct(kwargs) + slice_event = bool(slice_ct > 1 and (not prevent_slicing)) if slice_event: # A Slice Job Template will generate a WorkflowJob rather than a Job from awx.main.models.workflow import WorkflowJobTemplate, WorkflowJobNode @@ -347,13 +357,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour kwargs['_eager_fields'].setdefault('job_slice_count', 1) job = super(JobTemplate, self).create_unified_job(**kwargs) if slice_event: - try: - wj_config = job.launch_config - except JobLaunchConfig.DoesNotExist: - wj_config = JobLaunchConfig() - actual_inventory = wj_config.inventory if wj_config.inventory else self.inventory - for idx in range(min(self.job_slice_count, - actual_inventory.hosts.count())): + for idx in range(slice_ct): create_kwargs = dict(workflow_job=job, unified_job_template=self, ancestor_artifacts=dict(job_slice=idx + 1)) diff --git a/awx/main/tests/functional/models/test_job.py b/awx/main/tests/functional/models/test_job.py index 385daaf915..31b430d268 100644 --- a/awx/main/tests/functional/models/test_job.py +++ b/awx/main/tests/functional/models/test_job.py @@ -1,6 +1,6 @@ import pytest -from awx.main.models import JobTemplate, Job, JobHostSummary, WorkflowJob +from awx.main.models import JobTemplate, Job, JobHostSummary, WorkflowJob, Inventory @pytest.mark.django_db @@ -96,3 +96,13 @@ class TestSlicingModels: assert node.limit is None # data not saved in node prompts job = node.job assert job.limit == 'foobar' + + def test_effective_slice_count(self, job_template, inventory, organization): + job_template.inventory = inventory + assert job_template.inventory.hosts.count() == 0 + job_template.job_slice_count = 2 + job_template.inventory.hosts.create(name='foo1') + assert job_template.get_effective_slice_ct({}) + inventory2 = Inventory.objects.create(organization=organization, name='fooinv') + [inventory2.hosts.create(name='foo{}'.format(i)) for i in range(3)] + assert job_template.get_effective_slice_ct({'inventory': inventory2}) From cca9de9a3ed0bfdda07f82f6bd0af8282fe42866 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 5 Apr 2019 15:28:18 -0400 Subject: [PATCH 2/2] set default slice ct for special cases --- awx/main/models/jobs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 7e8ceaf192..88b67a7d68 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -352,6 +352,10 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour kwargs['_parent_field_name'] = "job_template" kwargs.setdefault('_eager_fields', {}) kwargs['_eager_fields']['is_sliced_job'] = True + elif self.job_slice_count > 1 and (not prevent_slicing): + # Unique case where JT was set to slice but hosts not available + kwargs.setdefault('_eager_fields', {}) + kwargs['_eager_fields']['job_slice_count'] = 1 elif prevent_slicing: kwargs.setdefault('_eager_fields', {}) kwargs['_eager_fields'].setdefault('job_slice_count', 1)