def iterate_timeout(timeout, message, wait=2): """Iterate and raise an exception on timeout. This is a generator that will continually yield and sleep for wait seconds, and if the timeout is reached, will raise an exception with <message>. """ log = _log.setup_logging('openstack.iterate_timeout') try: # None as a wait winds up flowing well in the per-resource cache # flow. We could spread this logic around to all of the calling # points, but just having this treat None as "I don't have a value" # seems friendlier if wait is None: wait = 2 elif wait == 0: # wait should be < timeout, unless timeout is None wait = 0.1 if timeout is None else min(0.1, timeout) wait = float(wait) except ValueError: raise exceptions.SDKException( "Wait value must be an int or float value. {wait} given" " instead".format(wait=wait)) start = time.time() count = 0 while (timeout is None) or (time.time() < start + timeout): count += 1 yield count log.debug('Waiting %s seconds', wait) time.sleep(wait) raise exceptions.ResourceTimeout(message)
def wait_for_status(session, resource, status, failures=[], interval=5, wait=120): """Wait for the resource to be in a particular status. :param session: The session to use for making this request. :type session: :class:`~openstack.session.Session` :param resource: The resource to wait on to reach the status. The resource must have a status attribute. :type resource: :class:`~openstack.resource.Resource` :param status: Desired status of the resource. :param list failures: Statuses that would indicate the transition failed such as 'ERROR'. :param interval: Number of seconds to wait between checks. :param wait: Maximum number of seconds to wait for transition. :return: Method returns self on success. :raises: :class:`~openstack.exceptions.ResourceTimeout` transition to status failed to occur in wait seconds. :raises: :class:`~openstack.exceptions.ResourceFailure` resource transitioned to one of the failure states. :raises: :class:`~AttributeError` if the resource does not have a status attribute """ if resource.status == status: return resource total_sleep = 0 if failures is None: failures = [] while total_sleep < wait: resource.get(session) if resource.status == status: return resource if resource.status in failures: msg = ("Resource %s transitioned to failure state %s" % (resource.id, resource.status)) raise exceptions.ResourceFailure(msg) time.sleep(interval) total_sleep += interval msg = "Timeout waiting for %s to transition to %s" % (resource.id, status) raise exceptions.ResourceTimeout(msg)
def wait_for_status(self, session, status='ACTIVE', failures=None, interval=5, wait=120): """Wait for the server to be in some status. :param session: The session to use for making this request. :type session: :class:`~openstack.session.Session` :param status: Desired status of the server. :param list failures: Statuses that would indicate the transition failed such as 'ERROR'. :param interval: Number of seconds to wait between checks. :param wait: Maximum number of seconds to wait for transition. :return: Method returns self on success. :raises: :class:`~openstack.exceptions.ResourceTimeout` transition to status failed to occur in wait seconds. :raises: :class:`~openstack.exceptions.ResourceFailure` resource transitioned to one of the failure states. """ try: if self.status == status: return self except AttributeError: pass total_sleep = 0 if failures is None: failures = [] while total_sleep < wait: self.get(session) if self.status == status: return self if self.status in failures: msg = ("Resource %s transitioned to failure state %s" % (self.id, self.status)) raise exceptions.ResourceFailure(msg) time.sleep(interval) total_sleep += interval msg = "Timeout waiting for %s to transition to %s" % (self.id, status) raise exceptions.ResourceTimeout(msg)
def lb_wait_for_status(cls, lb, status, failures, interval=1, wait=120): """Wait for load balancer to be in a particular provisioning status. :param lb: The load balancer to wait on to reach the status. :type lb: :class:`~openstack.load_blanacer.v2.load_balancer :param status: Desired status of the resource. :param list failures: Statuses that would indicate the transition failed such as 'ERROR'. :param interval: Number of seconds to wait between checks. :param wait: Maximum number of seconds to wait for transition. Note, most actions should easily finish in 120 seconds, but for load balancer create slow hosts can take up to ten minutes for nova to fully boot a VM. :return: None :raises: :class:`~openstack.exceptions.ResourceTimeout` transition to status failed to occur in wait seconds. :raises: :class:`~openstack.exceptions.ResourceFailure` resource transitioned to one of the failure states. """ total_sleep = 0 if failures is None: failures = [] while total_sleep < wait: lb = cls.conn.load_balancer.get_load_balancer(lb.id) if lb.provisioning_status == status: return None if lb.provisioning_status in failures: msg = ("Load Balancer %s transitioned to failure state %s" % (lb.id, lb.provisioning_status)) raise exceptions.ResourceFailure(msg) time.sleep(interval) total_sleep += interval msg = "Timeout waiting for Load Balancer %s to transition to %s" % ( lb.id, status) raise exceptions.ResourceTimeout(msg)
def wait_for_delete(session, resource, interval, wait): """Wait for the resource to be deleted. :param session: The session to use for making this request. :type session: :class:`~openstack.session.Session` :param resource: The resource to wait on to be deleted. :type resource: :class:`~openstack.resource.Resource` :param interval: Number of seconds to wait between checks. :param wait: Maximum number of seconds to wait for the delete. :return: Method returns self on success. :raises: :class:`~openstack.exceptions.ResourceTimeout` transition to status failed to occur in wait seconds. """ total_sleep = 0 while total_sleep < wait: try: resource.get(session) except exceptions.NotFoundException: return resource time.sleep(interval) total_sleep += interval msg = "Timeout waiting for %s delete" % (resource.id) raise exceptions.ResourceTimeout(msg)