Esempio n. 1
0
    def Run(self, args):
        start = time_utils.CurrentTimeSec()
        group_ref = self.CreateZonalReference(args.name, args.zone)
        while True:
            responses, errors = self._GetResources(group_ref)
            if errors:
                utils.RaiseToolException(errors)
            if WaitUntilStable._IsGroupStable(responses[0]):
                break
            log.out.Print(WaitUntilStable._MakeWaitText(responses[0]))
            time_utils.Sleep(WaitUntilStable._TIME_BETWEEN_POLLS_SEC)

            if args.timeout and time_utils.CurrentTimeSec(
            ) - start > args.timeout:
                raise utils.TimeoutError(
                    'Timeout while waiting for group to become '
                    'stable.')
        log.out.Print('Group is stable')
Esempio n. 2
0
  def WaitUntilSSHable(self, user, external_ip_address):
    """Blocks until SSHing to the given host succeeds."""
    ssh_args_for_polling = [self.ssh_executable]
    ssh_args_for_polling.extend(self.GetDefaultFlags())
    ssh_args_for_polling.append(UserHost(user, external_ip_address))
    ssh_args_for_polling.append('true')

    start_sec = time_utils.CurrentTimeSec()
    while True:
      logging.debug('polling instance for SSHability')
      retval = subprocess.call(ssh_args_for_polling)
      if retval == 0:
        break
      if (time_utils.CurrentTimeSec() - start_sec >
          _SSH_KEY_PROPAGATION_TIMEOUT_SEC):
        raise exceptions.ToolException(
            'Your SSH key has not propagated to your instance yet. '
            'Try running this command again.')
      time_utils.Sleep(5)
  def _GetEncryptedPasswordFromSerialPort(self, search_modulus):
    """Returns the decrypted password from the data in the serial port."""
    encrypted_password_data = {}
    start_time = time_utils.CurrentTimeSec()
    count = 1
    agent_ready = False
    while not encrypted_password_data:
      log.debug('Get Serial Port Output, Try {0}'.format(count))
      if (time_utils.CurrentTimeSec()
          > (start_time + WINDOWS_PASSWORD_TIMEOUT_SEC)):
        raise utils.TimeoutError(
            TIMEOUT_ERROR.format(time_utils.CurrentDatetimeUtc()))
      serial_port_output = self._GetSerialPortOutput(port=4).split('\n')
      for line in reversed(serial_port_output):
        try:
          encrypted_password_dict = json.loads(line)
        # Sometimes the serial port output only contains a partial entry.
        except ValueError:
          continue

        modulus = encrypted_password_dict.get('modulus')
        if modulus or encrypted_password_dict.get('ready'):
          agent_ready = True

        # Ignore any output that doesn't contain an encrypted password.
        if not encrypted_password_dict.get('encryptedPassword'):
          continue

        if search_modulus == modulus:
          encrypted_password_data = encrypted_password_dict
          break
      if not agent_ready:
        if self.old_metadata_keys:
          message = OLD_WINDOWS_BUILD_ERROR.format(self.ref.Name(),
                                                   self.ref.zone)
          raise utils.WrongInstanceTypeError(message)
        else:
          message = NOT_READY_ERROR
          raise utils.InstanceNotReadyError(message)
      time_utils.Sleep(POLLING_SEC)
      count += 1
    encrypted_password = encrypted_password_data['encryptedPassword']
    return encrypted_password
Esempio n. 4
0
def WaitForOperation(client, operation_ref, message):
    """Waits until the given operation finishes.

  Wait loop terminates when the operation's status becomes 'DONE'.

  Args:
    client: interface to the Cloud Updater API
    operation_ref: operation to poll
    message: message to be displayed by progress tracker

  Returns:
    True iff the operation finishes with success
  """
    with console_io.ProgressTracker(message, autotick=False) as pt:
        while True:
            operation = client.zoneOperations.Get(operation_ref.Request())
            if operation.error:
                return False
            if operation.status == 'DONE':
                return True
            pt.Tick()
            time_utils.Sleep(2)
Esempio n. 5
0
  def WaitUntilSSHable(self, user, external_ip_address):
    """Blocks until SSHing to the given host succeeds."""
    ssh_args_for_polling = [self.ssh_executable]
    ssh_args_for_polling.extend(self.GetDefaultFlags())
    ssh_args_for_polling.append(UserHost(user, external_ip_address))
    ssh_args_for_polling.append('true')

    start_sec = time_utils.CurrentTimeSec()
    while True:
      logging.debug('polling instance for SSHability')
      retval = subprocess.call(ssh_args_for_polling)
      if retval == 0:
        break
      if (time_utils.CurrentTimeSec() - start_sec >
          _SSH_KEY_PROPAGATION_TIMEOUT_SEC):
        raise exceptions.ToolException(
            'Could not SSH to the instance.  It is possible that '
            'your SSH key has not propagated to the instance yet. '
            'Try running this command again.  If you still cannot connect, '
            'verify that the firewall and instance are set to accept '
            'ssh traffic.')
      time_utils.Sleep(5)
Esempio n. 6
0
def WaitForOperations(operations,
                      project,
                      operation_service,
                      resource_service,
                      http,
                      batch_url,
                      warnings,
                      errors,
                      custom_get_requests=None,
                      timeout=None):
    """Blocks until the given operations are done or until a timeout is reached.

  Args:
    operations: A list of Operation objects to poll.
    project: The project to which the resources belog.
    operation_service: The service that can be used to get operation
      objects.
    resource_service: The service of the collection being mutated by
      the operations. If the operation type is not delete, this service
      is used to fetch the mutated objects after the operations are done.
    http: An HTTP object.
    batch_url: The URL to which batch requests should be sent.
    warnings: An output parameter for capturing warnings.
    errors: An output parameter for capturing errors.
    custom_get_requests: A mapping of resource names to requests. If
      this is provided, when an operation is DONE, instead of performing
      a get on the targetLink, this function will consult custom_get_requests
      and perform the request dictated by custom_get_requests.
    timeout: The maximum amount of time, in seconds, to wait for the
      operations to reach the DONE state.

  Yields:
    The resources pointed to by the operations' targetLink fields if
    the operation type is not delete. Only resources whose
    corresponding operations reach done are yielded.
  """
    timeout = timeout or _POLLING_TIMEOUT_SEC

    operation_type = operation_service.GetResponseType('Get')

    responses = []
    start = time_utils.CurrentTimeSec()
    sleep_sec = 0

    while operations:
        resource_requests = []
        operation_requests = []

        log.debug('Operations to inspect: %s', operations)
        for operation in operations:
            if operation.status == operation_type.StatusValueValuesEnum.DONE:
                # The operation has reached the DONE state, so we record any
                # problems it contains (if any) and proceed to get the target
                # resource if there were no problems and the operation is not
                # a deletion.

                _RecordProblems(operation, warnings, errors)

                # We shouldn't attempt to get the target resource if there was
                # anything wrong with the operation. Note that
                # httpErrorStatusCode is set only when the operation is not
                # successful.
                if (operation.httpErrorStatusCode
                        and operation.httpErrorStatusCode != httplib.OK):
                    continue

                # Just in case the server did not set httpErrorStatusCode but
                # the operation did fail, we check the "error" field.
                if operation.error:
                    continue

                target_link = operation.targetLink

                if custom_get_requests:
                    target_link, service, request_protobuf = (
                        custom_get_requests[operation.targetLink])
                    resource_requests.append(
                        (service, 'Get', request_protobuf))

                # We shouldn't get the target resource if the operation type
                # is delete because there will be no resource left.
                elif operation.operationType != 'delete':
                    request = resource_service.GetRequestType('Get')(
                        project=project)
                    if operation.zone:
                        request.zone = path_simplifier.Name(operation.zone)
                    elif operation.region:
                        request.region = path_simplifier.Name(operation.region)
                    name_field = resource_service.GetMethodConfig(
                        'Get').ordered_params[-1]
                    setattr(request, name_field,
                            path_simplifier.Name(operation.targetLink))
                    resource_requests.append(
                        (resource_service, 'Get', request))

                log.status.write('{0} [{1}].\n'.format(
                    _HUMAN_FRIENDLY_OPERATION_TYPES.get(
                        operation.operationType, 'Updated'), target_link))

            else:
                # The operation has not reached the DONE state, so we add a
                # get request to poll the operation.
                request = operation_service.GetRequestType('Get')(
                    operation=operation.name, project=project)
                if operation.zone:
                    request.zone = path_simplifier.Name(operation.zone)
                elif operation.region:
                    request.region = path_simplifier.Name(operation.region)
                operation_requests.append((operation_service, 'Get', request))

        requests = resource_requests + operation_requests
        if not requests:
            break

        responses, request_errors = batch_helper.MakeRequests(
            requests=requests, http=http, batch_url=batch_url)
        errors.extend(request_errors)

        operations = []
        for response in responses:
            if isinstance(response, operation_type):
                operations.append(response)
            else:
                yield response

        # If there are no more operations, we are done.
        if not operations:
            break

        # Did we time out? If so, record the operations that timed out so
        # they can be reported to the user.
        if time_utils.CurrentTimeSec() - start > timeout:
            log.debug('Timeout of %ss reached.', timeout)
            _RecordUnfinishedOperations(operations, errors)
            break

        # Sleeps before trying to poll the operations again.
        sleep_sec += 1
        log.debug('Sleeping for %ss.', sleep_sec)
        time_utils.Sleep(min(sleep_sec, _MAX_TIME_BETWEEN_POLLS_SEC))