diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 72cfc24cdc..72c1121c39 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -4038,7 +4038,8 @@ class JobHostSummarySerializer(BaseSerializer): class Meta: model = JobHostSummary fields = ('*', '-name', '-description', 'job', 'host', 'host_name', 'changed', - 'dark', 'failures', 'ok', 'processed', 'skipped', 'failed') + 'dark', 'failures', 'ok', 'processed', 'skipped', 'failed', + 'ignored', 'rescued') def get_related(self, obj): res = super(JobHostSummarySerializer, self).get_related(obj) diff --git a/awx/lib/awx_display_callback/module.py b/awx/lib/awx_display_callback/module.py index 0bb0099bdd..b113502c6c 100644 --- a/awx/lib/awx_display_callback/module.py +++ b/awx/lib/awx_display_callback/module.py @@ -329,8 +329,10 @@ class BaseCallbackModule(CallbackBase): changed=stats.changed, dark=stats.dark, failures=stats.failures, + ignored=getattr(stats, 'ignored', 0), ok=stats.ok, processed=stats.processed, + rescued=getattr(stats, 'rescued', 0), skipped=stats.skipped ) diff --git a/awx/main/migrations/0062_v350_new_playbook_stats.py b/awx/main/migrations/0062_v350_new_playbook_stats.py new file mode 100644 index 0000000000..29ab8e7017 --- /dev/null +++ b/awx/main/migrations/0062_v350_new_playbook_stats.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.16 on 2019-02-14 00:44 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0061_v350_track_native_credentialtype_source'), + ] + + operations = [ + migrations.AddField( + model_name='jobhostsummary', + name='ignored', + field=models.PositiveIntegerField(default=0, editable=False), + ), + migrations.AddField( + model_name='jobhostsummary', + name='rescued', + field=models.PositiveIntegerField(default=0, editable=False), + ), + ] diff --git a/awx/main/models/events.py b/awx/main/models/events.py index b92866e889..f996cc123c 100644 --- a/awx/main/models/events.py +++ b/awx/main/models/events.py @@ -483,7 +483,7 @@ class JobEvent(BasePlaybookEvent): job = self.job for host in hostnames: host_stats = {} - for stat in ('changed', 'dark', 'failures', 'ok', 'processed', 'skipped'): + for stat in ('changed', 'dark', 'failures', 'ignored', 'ok', 'processed', 'rescued', 'skipped'): try: host_stats[stat] = self.event_data.get(stat, {}).get(host, 0) except AttributeError: # in case event_data[stat] isn't a dict. diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 471eaafc91..95b6dd41d5 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -1123,17 +1123,19 @@ class JobHostSummary(CreatedModifiedModel): changed = models.PositiveIntegerField(default=0, editable=False) dark = models.PositiveIntegerField(default=0, editable=False) failures = models.PositiveIntegerField(default=0, editable=False) + ignored = models.PositiveIntegerField(default=0, editable=False) ok = models.PositiveIntegerField(default=0, editable=False) processed = models.PositiveIntegerField(default=0, editable=False) + rescued = models.PositiveIntegerField(default=0, editable=False) skipped = models.PositiveIntegerField(default=0, editable=False) failed = models.BooleanField(default=False, editable=False) def __str__(self): host = getattr_dne(self, 'host') hostname = host.name if host else 'N/A' - return '%s changed=%d dark=%d failures=%d ok=%d processed=%d skipped=%s' % \ - (hostname, self.changed, self.dark, self.failures, self.ok, - self.processed, self.skipped) + return '%s changed=%d dark=%d failures=%d ignored=%d ok=%d processed=%d rescued=%d skipped=%s' % \ + (hostname, self.changed, self.dark, self.failures, self.ignored, self.ok, + self.processed, self.rescued, self.skipped) def get_absolute_url(self, request=None): return reverse('api:job_host_summary_detail', kwargs={'pk': self.pk}, request=request) diff --git a/awx/main/tests/functional/models/test_job.py b/awx/main/tests/functional/models/test_job.py index 9c2cc8ca67..385daaf915 100644 --- a/awx/main/tests/functional/models/test_job.py +++ b/awx/main/tests/functional/models/test_job.py @@ -68,14 +68,14 @@ def test_job_host_summary_representation(host): job = Job.objects.create(name='foo') jhs = JobHostSummary.objects.create( host=host, job=job, - changed=1, dark=2, failures=3, ok=4, processed=5, skipped=6 + changed=1, dark=2, failures=3, ignored=4, ok=5, processed=6, rescued=7, skipped=8 ) - assert 'single-host changed=1 dark=2 failures=3 ok=4 processed=5 skipped=6' == str(jhs) + assert 'single-host changed=1 dark=2 failures=3 ignored=4 ok=5 processed=6 rescued=7 skipped=8' == str(jhs) # Representation should be robust to deleted related items jhs = JobHostSummary.objects.get(pk=jhs.id) host.delete() - assert 'N/A changed=1 dark=2 failures=3 ok=4 processed=5 skipped=6' == str(jhs) + assert 'N/A changed=1 dark=2 failures=3 ignored=4 ok=5 processed=6 rescued=7 skipped=8' == str(jhs) @pytest.mark.django_db diff --git a/tools/docker-compose/bootstrap_development.sh b/tools/docker-compose/bootstrap_development.sh index d8e7526444..4ad7572853 100755 --- a/tools/docker-compose/bootstrap_development.sh +++ b/tools/docker-compose/bootstrap_development.sh @@ -17,8 +17,8 @@ ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=${RABBITMQ_HOST} port=5 #/etc/init.d/ssh start -ansible -i "127.0.0.1," -c local -v -m postgresql_user -U postgres -a "name=awx-dev password=AWXsome1 login_user=postgres login_host=postgres" all -ansible -i "127.0.0.1," -c local -v -m postgresql_db -U postgres -a "name=awx-dev owner=awx-dev login_user=postgres login_host=postgres" all +ansible -i "127.0.0.1," -c local -v -m postgresql_user --become-user postgres -a "name=awx-dev password=AWXsome1 login_user=postgres login_host=postgres" all +ansible -i "127.0.0.1," -c local -v -m postgresql_db --become-user postgres -a "name=awx-dev owner=awx-dev login_user=postgres login_host=postgres" all # Move to the source directory so we can bootstrap if [ -f "/awx_devel/manage.py" ]; then