def wait(self, pk, parent_pk=None, min_interval=1, max_interval=30, timeout=None, outfile=sys.stdout,
             exit_on=['successful'], **kwargs):
        """
        Wait for a running job to finish. Blocks further input until the job completes (whether successfully
        or unsuccessfully) and a final status can be given.

        =====API DOCS=====
        Wait for a job resource object to enter certain status.

        :param pk: Primary key of the job resource object to wait.
        :type pk: int
        :param parent_pk: Primary key of the unified job template resource object whose latest job run will be
                          waited if ``pk`` is not set.
        :type parent_pk: int
        :param timeout: Number in seconds after which this method will time out.
        :type timeout: float
        :param min_interval: Minimum polling interval to request an update from Tower.
        :type min_interval: float
        :param max_interval: Maximum polling interval to request an update from Tower.
        :type max_interval: float
        :param outfile: Alternative file than stdout to write job status updates on.
        :type outfile: file
        :param exit_on: Job resource object statuses to wait on.
        :type exit_on: array
        :param `**kwargs`: Keyword arguments used to look up job resource object to wait if ``pk`` is
                           not provided.
        :returns: A dictionary combining the JSON output of the status-changed job resource object, as well
                  as two extra fields: "changed", a flag indicating if the job resource object is status-changed
                  as expected; "id", an integer which is the primary key of the job resource object being
                  status-changed.
        :rtype: dict
        :raises tower_cli.exceptions.Timeout: When wait time reaches time out.
        :raises tower_cli.exceptions.JobFailure: When the job being waited on runs into failure.
        =====API DOCS=====
        """
        # If we do not have the unified job info, infer it from parent
        if pk is None:
            pk = self.last_job_data(parent_pk, **kwargs)['id']
        job_endpoint = '%s%s/' % (self.unified_job_type, pk)

        dots = itertools.cycle([0, 1, 2, 3])
        longest_string = 0
        interval = min_interval
        start = time.time()

        # Poll the Ansible Tower instance for status, and print the status to the outfile (usually standard out).
        #
        # Note that this is one of the few places where we use `secho` even though we're in a function that might
        # theoretically be imported and run in Python.  This seems fine; outfile can be set to /dev/null and very
        # much the normal use for this method should be CLI monitoring.
        result = client.get(job_endpoint).json()
        last_poll = time.time()
        timeout_check = 0
        while result['status'] not in exit_on:
            # If the job has failed, we want to raise an Exception for that so we get a non-zero response.
            if result['failed']:
                if is_tty(outfile) and not settings.verbose:
                    secho('\r' + ' ' * longest_string + '\n', file=outfile)
                raise exc.JobFailure('Job failed.')

            # Sanity check: Have we officially timed out?
            # The timeout check is incremented below, so this is checking to see if we were timed out as of
            # the previous iteration. If we are timed out, abort.
            if timeout and timeout_check - start > timeout:
                raise exc.Timeout('Monitoring aborted due to timeout.')

            # If the outfile is a TTY, print the current status.
            output = '\rCurrent status: %s%s' % (result['status'], '.' * next(dots))
            if longest_string > len(output):
                output += ' ' * (longest_string - len(output))
            else:
                longest_string = len(output)
            if is_tty(outfile) and not settings.verbose:
                secho(output, nl=False, file=outfile)

            # Put the process to sleep briefly.
            time.sleep(0.2)

            # Sanity check: Have we reached our timeout?
            # If we're about to time out, then we need to ensure that we do one last check.
            #
            # Note that the actual timeout will be performed at the start of the **next** iteration,
            # so there's a chance for the job's completion to be noted first.
            timeout_check = time.time()
            if timeout and timeout_check - start > timeout:
                last_poll -= interval

            # If enough time has elapsed, ask the server for a new status.
            #
            # Note that this doesn't actually do a status check every single time; we want the "spinner" to
            # spin even if we're not actively doing a check.
            #
            # So, what happens is that we are "counting down" (actually up) to the next time that we intend
            # to do a check, and once that time hits, we do the status check as part of the normal cycle.
            if time.time() - last_poll > interval:
                result = client.get(job_endpoint).json()
                last_poll = time.time()
                interval = min(interval * 1.5, max_interval)

                # If the outfile is *not* a TTY, print a status update when and only when we make an actual
                # check to job status.
                if not is_tty(outfile) or settings.verbose:
                    click.echo('Current status: %s' % result['status'], file=outfile)

            # Wipe out the previous output
            if is_tty(outfile) and not settings.verbose:
                secho('\r' + ' ' * longest_string, file=outfile, nl=False)
                secho('\r', file=outfile, nl=False)

        # Return the job ID and other response data
        answer = OrderedDict((('changed', True), ('id', pk)))
        answer.update(result)
        # Make sure to return ID of resource and not update number relevant for project creation and update
        if parent_pk:
            answer['id'] = parent_pk
        else:
            answer['id'] = pk
        return answer
def wait(self, pk, parent_pk=None, min_interval=1, max_interval=30, timeout=None, outfile=sys.stdout,
             exit_on=['successful'], **kwargs):
        """
        Wait for a running job to finish. Blocks further input until the job completes (whether successfully
        or unsuccessfully) and a final status can be given.

        =====API DOCS=====
        Wait for a job resource object to enter certain status.

        :param pk: Primary key of the job resource object to wait.
        :type pk: int
        :param parent_pk: Primary key of the unified job template resource object whose latest job run will be
                          waited if ``pk`` is not set.
        :type parent_pk: int
        :param timeout: Number in seconds after which this method will time out.
        :type timeout: float
        :param min_interval: Minimum polling interval to request an update from Tower.
        :type min_interval: float
        :param max_interval: Maximum polling interval to request an update from Tower.
        :type max_interval: float
        :param outfile: Alternative file than stdout to write job status updates on.
        :type outfile: file
        :param exit_on: Job resource object statuses to wait on.
        :type exit_on: array
        :param `**kwargs`: Keyword arguments used to look up job resource object to wait if ``pk`` is
                           not provided.
        :returns: A dictionary combining the JSON output of the status-changed job resource object, as well
                  as two extra fields: "changed", a flag indicating if the job resource object is status-changed
                  as expected; "id", an integer which is the primary key of the job resource object being
                  status-changed.
        :rtype: dict
        :raises tower_cli.exceptions.Timeout: When wait time reaches time out.
        :raises tower_cli.exceptions.JobFailure: When the job being waited on runs into failure.
        =====API DOCS=====
        """
        # If we do not have the unified job info, infer it from parent
        if pk is None:
            pk = self.last_job_data(parent_pk, **kwargs)['id']
        job_endpoint = '%s%s/' % (self.unified_job_type, pk)

        dots = itertools.cycle([0, 1, 2, 3])
        longest_string = 0
        interval = min_interval
        start = time.time()

        # Poll the Ansible Tower instance for status, and print the status to the outfile (usually standard out).
        #
        # Note that this is one of the few places where we use `secho` even though we're in a function that might
        # theoretically be imported and run in Python.  This seems fine; outfile can be set to /dev/null and very
        # much the normal use for this method should be CLI monitoring.
        result = client.get(job_endpoint).json()
        last_poll = time.time()
        timeout_check = 0
        while result['status'] not in exit_on:
            # If the job has failed, we want to raise an Exception for that so we get a non-zero response.
            if result['failed']:
                if is_tty(outfile) and not settings.verbose:
                    secho('\r' + ' ' * longest_string + '\n', file=outfile)
                raise exc.JobFailure('Job failed.')

            # Sanity check: Have we officially timed out?
            # The timeout check is incremented below, so this is checking to see if we were timed out as of
            # the previous iteration. If we are timed out, abort.
            if timeout and timeout_check - start > timeout:
                raise exc.Timeout('Monitoring aborted due to timeout.')

            # If the outfile is a TTY, print the current status.
            output = '\rCurrent status: %s%s' % (result['status'], '.' * next(dots))
            if longest_string > len(output):
                output += ' ' * (longest_string - len(output))
            else:
                longest_string = len(output)
            if is_tty(outfile) and not settings.verbose:
                secho(output, nl=False, file=outfile)

            # Put the process to sleep briefly.
            time.sleep(0.2)

            # Sanity check: Have we reached our timeout?
            # If we're about to time out, then we need to ensure that we do one last check.
            #
            # Note that the actual timeout will be performed at the start of the **next** iteration,
            # so there's a chance for the job's completion to be noted first.
            timeout_check = time.time()
            if timeout and timeout_check - start > timeout:
                last_poll -= interval

            # If enough time has elapsed, ask the server for a new status.
            #
            # Note that this doesn't actually do a status check every single time; we want the "spinner" to
            # spin even if we're not actively doing a check.
            #
            # So, what happens is that we are "counting down" (actually up) to the next time that we intend
            # to do a check, and once that time hits, we do the status check as part of the normal cycle.
            if time.time() - last_poll > interval:
                result = client.get(job_endpoint).json()
                last_poll = time.time()
                interval = min(interval * 1.5, max_interval)

                # If the outfile is *not* a TTY, print a status update when and only when we make an actual
                # check to job status.
                if not is_tty(outfile) or settings.verbose:
                    click.echo('Current status: %s' % result['status'], file=outfile)

            # Wipe out the previous output
            if is_tty(outfile) and not settings.verbose:
                secho('\r' + ' ' * longest_string, file=outfile, nl=False)
                secho('\r', file=outfile, nl=False)

        # Return the job ID and other response data
        answer = OrderedDict((('changed', True), ('id', pk)))
        answer.update(result)
        # Make sure to return ID of resource and not update number relevant for project creation and update
        if parent_pk:
            answer['id'] = parent_pk
        else:
            answer['id'] = pk
        return answer
def wait ( self , pk , parent_pk = None , min_interval = 1 , max_interval = 30 , timeout = None , outfile = sys . stdout , exit_on = [ 'successful' ] , * * kwargs ) : # If we do not have the unified job info, infer it from parent if pk is None : pk = self . last_job_data ( parent_pk , * * kwargs ) [ 'id' ] job_endpoint = '%s%s/' % ( self . unified_job_type , pk ) dots = itertools . cycle ( [ 0 , 1 , 2 , 3 ] ) longest_string = 0 interval = min_interval start = time . time ( ) # Poll the Ansible Tower instance for status, and print the status to the outfile (usually standard out). # # Note that this is one of the few places where we use `secho` even though we're in a function that might # theoretically be imported and run in Python.  This seems fine; outfile can be set to /dev/null and very # much the normal use for this method should be CLI monitoring. result = client . get ( job_endpoint ) . json ( ) last_poll = time . time ( ) timeout_check = 0 while result [ 'status' ] not in exit_on : # If the job has failed, we want to raise an Exception for that so we get a non-zero response. if result [ 'failed' ] : if is_tty ( outfile ) and not settings . verbose : secho ( '\r' + ' ' * longest_string + '\n' , file = outfile ) raise exc . JobFailure ( 'Job failed.' ) # Sanity check: Have we officially timed out? # The timeout check is incremented below, so this is checking to see if we were timed out as of # the previous iteration. If we are timed out, abort. if timeout and timeout_check - start > timeout : raise exc . Timeout ( 'Monitoring aborted due to timeout.' ) # If the outfile is a TTY, print the current status. output = '\rCurrent status: %s%s' % ( result [ 'status' ] , '.' * next ( dots ) ) if longest_string > len ( output ) : output += ' ' * ( longest_string - len ( output ) ) else : longest_string = len ( output ) if is_tty ( outfile ) and not settings . verbose : secho ( output , nl = False , file = outfile ) # Put the process to sleep briefly. time . sleep ( 0.2 ) # Sanity check: Have we reached our timeout? # If we're about to time out, then we need to ensure that we do one last check. # # Note that the actual timeout will be performed at the start of the **next** iteration, # so there's a chance for the job's completion to be noted first. timeout_check = time . time ( ) if timeout and timeout_check - start > timeout : last_poll -= interval # If enough time has elapsed, ask the server for a new status. # # Note that this doesn't actually do a status check every single time; we want the "spinner" to # spin even if we're not actively doing a check. # # So, what happens is that we are "counting down" (actually up) to the next time that we intend # to do a check, and once that time hits, we do the status check as part of the normal cycle. if time . time ( ) - last_poll > interval : result = client . get ( job_endpoint ) . json ( ) last_poll = time . time ( ) interval = min ( interval * 1.5 , max_interval ) # If the outfile is *not* a TTY, print a status update when and only when we make an actual # check to job status. if not is_tty ( outfile ) or settings . verbose : click . echo ( 'Current status: %s' % result [ 'status' ] , file = outfile ) # Wipe out the previous output if is_tty ( outfile ) and not settings . verbose : secho ( '\r' + ' ' * longest_string , file = outfile , nl = False ) secho ( '\r' , file = outfile , nl = False ) # Return the job ID and other response data answer = OrderedDict ( ( ( 'changed' , True ) , ( 'id' , pk ) ) ) answer . update ( result ) # Make sure to return ID of resource and not update number relevant for project creation and update if parent_pk : answer [ 'id' ] = parent_pk else : answer [ 'id' ] = pk return answer
Wait for a running job to finish. Blocks further input until the job completes (whether successfully
        or unsuccessfully) and a final status can be given.

        =====API DOCS=====
        Wait for a job resource object to enter certain status.

        :param pk: Primary key of the job resource object to wait.
        :type pk: int
        :param parent_pk: Primary key of the unified job template resource object whose latest job run will be
                          waited if ``pk`` is not set.
        :type parent_pk: int
        :param timeout: Number in seconds after which this method will time out.
        :type timeout: float
        :param min_interval: Minimum polling interval to request an update from Tower.
        :type min_interval: float
        :param max_interval: Maximum polling interval to request an update from Tower.
        :type max_interval: float
        :param outfile: Alternative file than stdout to write job status updates on.
        :type outfile: file
        :param exit_on: Job resource object statuses to wait on.
        :type exit_on: array
        :param `**kwargs`: Keyword arguments used to look up job resource object to wait if ``pk`` is
                           not provided.
        :returns: A dictionary combining the JSON output of the status-changed job resource object, as well
                  as two extra fields: "changed", a flag indicating if the job resource object is status-changed
                  as expected; "id", an integer which is the primary key of the job resource object being
                  status-changed.
        :rtype: dict
        :raises tower_cli.exceptions.Timeout: When wait time reaches time out.
        :raises tower_cli.exceptions.JobFailure: When the job being waited on runs into failure.
        =====API DOCS=====
Wait for a running job to finish . Blocks further input until the job completes ( whether successfully or unsuccessfully ) and a final status can be given .