예제 #1
0
    def _get_instance_end_text(self, instance_data, jobs_data):
        """Format text version of the workflow instance completion message.

        Args:
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.

        Returns:
            Text message describing the workflow instance.
        """
        TEXT_TEMPLATE = """\
Workflow %(workflow)s instance %(instance)s started at %(start_time)s \
finished after %(run_time)s at %(end_time)s with status %(status)s.

Details are available at  http://%(ui_host)s:%(ui_port)s/jobs/?\
workflow=%(workflow)s&instance=%(instance)s

Jobs:

Name | Last start | Last end | Run time | Status | Url
%(jobs)s
"""
        jobs = ''
        for job_data in jobs_data:
            jobs += '%s | ' % job_data.job
            if not job_data.last_start_time:
                jobs += '| | '
            else:
                jobs += '%s | ' % timestamp_to_str(job_data.last_start_time)
                if not job_data.last_end_time:
                    jobs += '| | '
                else:
                    jobs += '%s | ' % timestamp_to_str(job_data.last_end_time)
                    delta = int(job_data.last_end_time -
                                job_data.last_start_time)
                    jobs += '%s | ' % datetime.timedelta(seconds=delta)
            jobs += '%s | ' % Status.to_string(job_data.status)
            jobs += ('http://%s:%s/executions/?workflow=%s&instance=%s&'
                     'job=%s\n' % (self._ui_host,
                                   self._ui_port,
                                   job_data.workflow,
                                   job_data.instance,
                                   job_data.job))
        start_time = timestamp_to_str(instance_data.start_time)
        end_time = timestamp_to_str(instance_data.end_time)
        delta = int(instance_data.end_time - instance_data.start_time)
        run_time = datetime.timedelta(seconds=delta)
        status = Status.to_string(instance_data.status)
        return TEXT_TEMPLATE % {'workflow': instance_data.workflow,
                                'instance': instance_data.instance,
                                'start_time': start_time,
                                'end_time': end_time,
                                'run_time': run_time,
                                'status': status,
                                'ui_host': self._ui_host,
                                'ui_port': self._ui_port,
                                'jobs': jobs}
예제 #2
0
    def _get_instance_end_text(self, instance_data, jobs_data):
        """Format text version of the workflow instance completion message.

        Args:
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.

        Returns:
            Text message describing the workflow instance.
        """
        TEXT_TEMPLATE = """\
Workflow %(workflow)s instance %(instance)s started at %(start_time)s \
finished after %(run_time)s at %(end_time)s with status %(status)s.

Details are available at  http://%(ui_host)s:%(ui_port)s/jobs/?\
workflow=%(workflow)s&instance=%(instance)s

Jobs:

Name | Last start | Last end | Run time | Status | Url
%(jobs)s
"""
        jobs = ''
        for job_data in jobs_data:
            jobs += '%s | ' % job_data.job
            if not job_data.last_start_time:
                jobs += '| | '
            else:
                jobs += '%s | ' % timestamp_to_str(job_data.last_start_time)
                if not job_data.last_end_time:
                    jobs += '| | '
                else:
                    jobs += '%s | ' % timestamp_to_str(job_data.last_end_time)
                    delta = int(job_data.last_end_time -
                                job_data.last_start_time)
                    jobs += '%s | ' % datetime.timedelta(seconds=delta)
            jobs += '%s | ' % Status.to_string(job_data.status)
            jobs += ('http://%s:%s/executions/?workflow=%s&instance=%s&'
                     'job=%s\n' %
                     (self._ui_host, self._ui_port, job_data.workflow,
                      job_data.instance, job_data.job))
        start_time = timestamp_to_str(instance_data.start_time)
        end_time = timestamp_to_str(instance_data.end_time)
        delta = int(instance_data.end_time - instance_data.start_time)
        run_time = datetime.timedelta(seconds=delta)
        status = Status.to_string(instance_data.status)
        return TEXT_TEMPLATE % {
            'workflow': instance_data.workflow,
            'instance': instance_data.instance,
            'start_time': start_time,
            'end_time': end_time,
            'run_time': run_time,
            'status': status,
            'ui_host': self._ui_host,
            'ui_port': self._ui_port,
            'jobs': jobs
        }
예제 #3
0
    def _get_progress(execution_history, instance_start_time,
                      instance_end_time):
        """Extract info required to construct job execution progress bar.

        Args:
            execution_history: The list of execution records describing runs of
                this job.
            instance_start_time: The start time of the workflow instance that
                this job belongs to.
            instance_end_time: The end time of the workflow instance that this
                job belongs to or the current time if the instance did not yet
                finish.
        Returns:
            The list of (percentage, status) tuples where status describes
            the state that the job was in on the timeline of the instance,
            while the percentage tells for how long this status lasted as a
            percentage of the total instance run time.  Ordering of the tuples
            on the list follows the job state transitions so the job execution
            timeline can be reconstructed from its contents.
        """
        result = []
        instance_duration = instance_end_time - instance_start_time
        if instance_duration == 0:
            return result
        still_running = False
        first_start_time = None
        for record in execution_history:
            assert record.start_time, record
            if not first_start_time:
                first_start_time = record.start_time
            if record.end_time:
                execution_duration = record.end_time - record.start_time
                status = (Status.to_string(Status.SUCCESS) if
                          record.exit_code == 0 else
                          Status.to_string(Status.FAILURE))
            else:
                assert not still_running
                still_running = True
                execution_duration = instance_end_time - record.start_time
                status = Status.to_string(Status.RUNNING)
            percentage = int(100. * execution_duration / instance_duration)
            percentage = max(1, percentage)
            result.append((percentage, status))

        if first_start_time:
            duration = first_start_time - instance_start_time
        else:
            duration = instance_duration
        result.insert(0, (int(100. * duration / instance_duration), ''))
        return result
예제 #4
0
    def _get_progress(execution_history, instance_start_time,
                      instance_end_time):
        """Extract info required to construct job execution progress bar.

        Args:
            execution_history: The list of execution records describing runs of
                this job.
            instance_start_time: The start time of the workflow instance that
                this job belongs to.
            instance_end_time: The end time of the workflow instance that this
                job belongs to or the current time if the instance did not yet
                finish.
        Returns:
            The list of (percentage, status) tuples where status describes
            the state that the job was in on the timeline of the instance,
            while the percentage tells for how long this status lasted as a
            percentage of the total instance run time.  Ordering of the tuples
            on the list follows the job state transitions so the job execution
            timeline can be reconstructed from its contents.
        """
        result = []
        instance_duration = instance_end_time - instance_start_time
        if instance_duration == 0:
            return result
        still_running = False
        first_start_time = None
        for record in execution_history:
            assert record.start_time, record
            if not first_start_time:
                first_start_time = record.start_time
            if record.end_time:
                execution_duration = record.end_time - record.start_time
                status = (Status.to_string(Status.SUCCESS) if record.exit_code
                          == 0 else Status.to_string(Status.FAILURE))
            else:
                assert not still_running
                still_running = True
                execution_duration = instance_end_time - record.start_time
                status = Status.to_string(Status.RUNNING)
            percentage = int(100. * execution_duration / instance_duration)
            percentage = max(1, percentage)
            result.append((percentage, status))

        if first_start_time:
            duration = first_start_time - instance_start_time
        else:
            duration = instance_duration
        result.insert(0, (int(100. * duration / instance_duration), ''))
        return result
예제 #5
0
    def send_instance_end_message(self, to, instance_data, jobs_data):
        """Send a message describing workflow instance run.

        Args:
            to: The list of recipient email addresses.
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.
        """
        jobs_data = Emailer._sort_jobs(jobs_data)
        text = self._get_instance_end_text(instance_data, jobs_data)
        html = self._get_instance_end_html(instance_data, jobs_data)
        status = Status.to_string(instance_data.status)
        subject = '%s for workflow %s' % (status, instance_data.workflow)
        self._send_message(subject, to, text, html)
예제 #6
0
    def send_instance_end_message(self, to, instance_data, jobs_data):
        """Send a message describing workflow instance run.

        Args:
            to: The list of recipient email addresses.
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.
        """
        jobs_data = Emailer._sort_jobs(jobs_data)
        text = self._get_instance_end_text(instance_data, jobs_data)
        html = self._get_instance_end_html(instance_data, jobs_data)
        status = Status.to_string(instance_data.status)
        subject = '%s for workflow %s' % (status, instance_data.workflow)
        self._send_message(subject, to, text, html)
예제 #7
0
    def _get_instance_end_html(self, instance_data, jobs_data):
        """Format html version of the workflow instance completion message.

        Args:
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.

        Returns:
            Html message describing the workflow instance.
        """
        HTML_TEMPLATE = """\
<html>
    <head></head>
    <body>
        <p>
            Workflow %(workflow)s instance %(instance)s started at
            %(start_time)s finished after %(run_time)s at %(end_time)s
            with status <span
style="background-color:%(instance_status_color)s;">%(status)s</span>.
            Click
            <a href="http://%(ui_host)s:%(ui_port)s/jobs/?\
workflow=%(workflow)s&instance=%(instance)s">here</a> for details.
        </p>
        <p>Jobs:<br/>
            <table style="border-collapse:collapse;">
                <tr>
                    <th style="border:1px dotted grey;">Name</th>
                    <th style="border:1px dotted grey;">Last start</th>
                    <th style="border:1px dotted grey;">Last end</th>
                    <th style="border:1px dotted grey;">Run time</th>
                    <th style="border:1px dotted grey;">Status</th>
                </tr>
                %(jobs)s
            </table>
        </p>
    </body>
</html>
"""
        jobs = ''
        for job_data in jobs_data:
            jobs += '<tr>'
            jobs += ('<td style="border:1px dotted grey;">'
                     '<a href="http://%s:%s/executions/?workflow=%s&'
                     'instance=%s&job=%s">%s</a></td>' %
                     (self._ui_host, self._ui_port, job_data.workflow,
                      job_data.instance, job_data.job, job_data.job))
            if not job_data.last_start_time:
                jobs += ('<td style="border:1px dotted grey;"></td>'
                         '<td style="border:1px dotted grey;"></td>'
                         '<td style="border:1px dotted grey;"></td>')
            else:
                jobs += ('<td style="border:1px dotted grey;">%s</td>' %
                         timestamp_to_str(job_data.last_start_time))
                if not job_data.last_end_time:
                    jobs += ('<td style="border:1px dotted grey;"></td>'
                             '<td style="border:1px dotted grey;"></td>')
                else:
                    delta = int(job_data.last_end_time -
                                job_data.last_start_time)
                    jobs += ('<td style="border:1px dotted grey;">%s</td>'
                             '<td style="border:1px dotted grey;">%s</td>' %
                             (timestamp_to_str(job_data.last_end_time),
                              datetime.timedelta(seconds=delta)))
            jobs += ('<td style="border:1px dotted grey;background-color:%s;'
                     'text-align: center;">%s</td>\n' %
                     (Status.COLORS[job_data.status],
                      Status.to_string(job_data.status)))
            jobs += '</tr>'
        start_time = timestamp_to_str(instance_data.start_time)
        end_time = timestamp_to_str(instance_data.end_time)
        delta = int(instance_data.end_time - instance_data.start_time)
        run_time = datetime.timedelta(seconds=delta)
        instance_status_color = Status.COLORS[instance_data.status]
        status = Status.to_string(instance_data.status)
        return HTML_TEMPLATE % {
            'workflow': instance_data.workflow,
            'instance': instance_data.instance,
            'start_time': start_time,
            'end_time': end_time,
            'run_time': run_time,
            'instance_status_color': instance_status_color,
            'status': status,
            'ui_host': self._ui_host,
            'ui_port': self._ui_port,
            'jobs': jobs
        }
예제 #8
0
    def _get_instance_end_html(self, instance_data, jobs_data):
        """Format html version of the workflow instance completion message.

        Args:
            instance_data: The data of the completed workflow instance.
            jobs_data: The list of data describing jobs in the workflow
                instance.

        Returns:
            Html message describing the workflow instance.
        """
        HTML_TEMPLATE = """\
<html>
    <head></head>
    <body>
        <p>
            Workflow %(workflow)s instance %(instance)s started at
            %(start_time)s finished after %(run_time)s at %(end_time)s
            with status <span
style="background-color:%(instance_status_color)s;">%(status)s</span>.
            Click
            <a href="http://%(ui_host)s:%(ui_port)s/jobs/?\
workflow=%(workflow)s&instance=%(instance)s">here</a> for details.
        </p>
        <p>Jobs:<br/>
            <table style="border-collapse:collapse;">
                <tr>
                    <th style="border:1px dotted grey;">Name</th>
                    <th style="border:1px dotted grey;">Last start</th>
                    <th style="border:1px dotted grey;">Last end</th>
                    <th style="border:1px dotted grey;">Run time</th>
                    <th style="border:1px dotted grey;">Status</th>
                </tr>
                %(jobs)s
            </table>
        </p>
    </body>
</html>
"""
        jobs = ''
        for job_data in jobs_data:
            jobs += '<tr>'
            jobs += ('<td style="border:1px dotted grey;">'
                     '<a href="http://%s:%s/executions/?workflow=%s&'
                     'instance=%s&job=%s">%s</a></td>' % (self._ui_host,
                                                          self._ui_port,
                                                          job_data.workflow,
                                                          job_data.instance,
                                                          job_data.job,
                                                          job_data.job))
            if not job_data.last_start_time:
                jobs += ('<td style="border:1px dotted grey;"></td>'
                         '<td style="border:1px dotted grey;"></td>'
                         '<td style="border:1px dotted grey;"></td>')
            else:
                jobs += ('<td style="border:1px dotted grey;">%s</td>' %
                         timestamp_to_str(job_data.last_start_time))
                if not job_data.last_end_time:
                    jobs += ('<td style="border:1px dotted grey;"></td>'
                             '<td style="border:1px dotted grey;"></td>')
                else:
                    delta = int(job_data.last_end_time -
                                job_data.last_start_time)
                    jobs += ('<td style="border:1px dotted grey;">%s</td>'
                             '<td style="border:1px dotted grey;">%s</td>' % (
                                 timestamp_to_str(job_data.last_end_time),
                                 datetime.timedelta(seconds=delta)))
            jobs += ('<td style="border:1px dotted grey;background-color:%s;'
                     'text-align: center;">%s</td>\n' % (
                         Status.COLORS[job_data.status],
                         Status.to_string(job_data.status)))
            jobs += '</tr>'
        start_time = timestamp_to_str(instance_data.start_time)
        end_time = timestamp_to_str(instance_data.end_time)
        delta = int(instance_data.end_time - instance_data.start_time)
        run_time = datetime.timedelta(seconds=delta)
        instance_status_color = Status.COLORS[instance_data.status]
        status = Status.to_string(instance_data.status)
        return HTML_TEMPLATE % {'workflow': instance_data.workflow,
                                'instance': instance_data.instance,
                                'start_time': start_time,
                                'end_time': end_time,
                                'run_time': run_time,
                                'instance_status_color': instance_status_color,
                                'status': status,
                                'ui_host': self._ui_host,
                                'ui_port': self._ui_port,
                                'jobs': jobs}