コード例 #1
0
ファイル: wait.py プロジェクト: wsong/google-cloud-sdk
    def Run(self, args):
        """Run 'operations wait'.

    Args:
      args: argparse.Namespace, The arguments that this command was invoked
          with.

    Raises:
      HttpException: An http error response was received while executing api
          request.
    Raises:
      DeploymentManagerError: Operation finished with error(s) or timed out.
    """
        project = properties.VALUES.core.project.Get(required=True)
        failed_ops = []
        for operation_name in args.operation_name:
            try:
                dm_v2_util.WaitForOperation(operation_name, project,
                                            self.context, '',
                                            OPERATION_TIMEOUT)
            except DeploymentManagerError:
                failed_ops.append(operation_name)
        if failed_ops:
            if len(failed_ops) == 1:
                raise DeploymentManagerError(
                    'Operation %s failed to complete or has errors.' %
                    failed_ops[0])
            else:
                raise DeploymentManagerError(
                    'Some operations failed to complete without errors:\n' +
                    '\n'.join(failed_ops))
        else:
            log.status.Print('All operations completed successfully.')
コード例 #2
0
def WaitForOperation(operation_name,
                     project,
                     context,
                     operation_description,
                     timeout=None):
    """Wait for an operation to complete.

  Polls the operation requested approximately every second, showing a
  progress indicator. Returns when the operation has completed.

  Args:
    operation_name: The name of the operation to wait on, as returned by
        operations.list.
    project: The name of the project that this operation belongs to.
    context: Context object with messages and client to access the
        deploymentmanager service.
    operation_description: A short description of the operation to wait on,
        such as 'create' or 'delete'. Will be displayed to the user.
    timeout: Optional (approximate) timeout in seconds, after which wait
        will return failure.

  Raises:
      HttpException: A http error response was received while executing api
          request. Will be raised if the operation cannot be found.
      DeploymentManagerError: The operation finished with error(s) or exceeded
          the timeout without completing.
  """
    client = context['deploymentmanager-client']
    messages = context['deploymentmanager-messages']
    ticks = 0
    message = ('Waiting for ' + ('{0} '.format(operation_description)
                                 if operation_description else '') +
               operation_name)
    with console_io.ProgressTracker(message, autotick=False) as ticker:
        while timeout is None or ticks < timeout:
            ticks += 1

            try:
                operation = client.operations.Get(
                    messages.DeploymentmanagerOperationsGetRequest(
                        project=project,
                        operation=operation_name,
                    ))
            except apitools_exceptions.HttpError as error:
                raise HttpException(GetError(error))
            ticker.Tick()
            # Operation status will be one of PENDING, RUNNING, DONE
            if operation.status == 'DONE':
                if operation.error:
                    raise DeploymentManagerError('Error in Operation ' +
                                                 operation_name + ': ' +
                                                 str(operation.error))
                else:  # Operation succeeded
                    return
            time.sleep(1)  # wait one second and try again
        # Timeout exceeded
        raise DeploymentManagerError('Wait for Operation ' + operation_name +
                                     ' exceeded timeout.')
コード例 #3
0
def BuildTargetConfigFromManifest(client,
                                  messages,
                                  project_id,
                                  deployment_id,
                                  manifest_id,
                                  properties=None):
    """Construct a TargetConfig from a manifest of a previous deployment.

  Args:
    client: Deployment Manager v2 API client.
    messages: Object with v2 API messages.
    project_id: Project for this deployment. This is used when pulling the
        the existing manifest.
    deployment_id: Deployment used to pull retrieve the manifest.
    manifest_id: The manifest to pull down for constructing the target.
    properties: Dictionary of properties, only used if the manifest has a
        single resource. Properties will override only. If the manifest
        has properties which do not exist in the properties hash will remain
        unchanged.

  Returns:
    TargetConfig containing the contents of the config file and the names and
    contents of any imports.

  Raises:
    HttpException: in the event that there is a failure to pull the manifest
        from deployment manager
    DeploymentManagerError: When the manifest being revived has more than one
        resource
  """
    try:
        manifest = client.manifests.Get(
            messages.DeploymentmanagerManifestsGetRequest(
                project=project_id,
                deployment=deployment_id,
                manifest=manifest_id,
            ))
        config_file = manifest.config
        imports = manifest.imports
    except apitools_exceptions.HttpError as error:
        raise exceptions.HttpException(error)

    # If properties were specified, then we need to ensure that the
    # configuration in the manifest retrieved has only a single resource.
    if properties:
        config_yaml = yaml.load(config_file.content)
        if len(config_yaml['resources']) != 1:
            raise DeploymentManagerError(
                'Manifest reuse with properties requires '
                'there only be a single resource.')
        single_resource = config_yaml['resources'][0]
        if not single_resource.has_key('properties'):
            single_resource['properties'] = {}
        existing_properties = single_resource['properties']
        for key, value in properties.iteritems():
            existing_properties[key] = value
        config_file.content = yaml.dump(config_yaml, default_flow_style=False)

    return messages.TargetConfiguration(config=config_file, imports=imports)
コード例 #4
0
def _BuildConfig(full_path, properties):
  """Takes the argument from the --config flag, and returns a processed config.

  Args:
    full_path: Path to the config yaml file, with an optional list of imports.
    properties: Dictionary of properties, only used if the file is a template.

  Returns:
    A tuple of base_path, config_contents, and a list of import objects.

  Raises:
    DeploymentManagerError: If using the properties flag for a config file
        instead of a template.
  """
  config_obj = _BuildImportObject(full_path)

  if not config_obj.IsTemplate():
    if properties:
      raise DeploymentManagerError(
          'The properties flag should only be used '
          'when passing in a template as your config file.')

    return config_obj

  # Otherwise we should build the config from scratch.
  base_name = config_obj.GetBaseName()

  # Build the single template resource.
  custom_resource = {'type': base_name,
                     'name': _SanitizeBaseName(base_name)}

  # Attach properties if we were given any.
  if properties:
    custom_resource['properties'] = properties

  # Add the import and single resource together into a config file.
  custom_dict = {'imports': [{'path': base_name},],
                 'resources': [custom_resource,]}

  # Dump using default_flow_style=False to use spacing instead of '{ }'
  custom_content = yaml.dump(custom_dict, default_flow_style=False)

  # Override the template_object with it's new config_content
  return config_obj.SetContent(custom_content)
コード例 #5
0
def _SanitizeLimitFlag(limit):
    """Sanitizes and returns a limit flag value.

  Args:
    limit: the limit flag value to sanitize.
  Returns:
    Sanitized limit flag value.
  Raises:
    DeploymentManagerError: if the provided limit flag value is not a positive
        integer.
  """
    if limit is None:
        limit = sys.maxint
    else:
        if limit > sys.maxint:
            limit = sys.maxint
        elif limit <= 0:
            raise DeploymentManagerError(
                '--limit must be a positive integer; received: {0}'.format(
                    limit))
    return limit
コード例 #6
0
def _BuildConfig(full_path, properties):
    """Takes the argument from the --config flag, and returns a processed config.

  Args:
    full_path: Path to the config yaml file, with an optional list of imports.
    properties: Dictionary of properties, only used if the file is a template.

  Returns:
    A tuple of base_path, config_contents, and a list of import objects.

  Raises:
    DeploymentManagerError: If using the properties flag for a config file
        instead of a template.
  """
    config_obj = _BuildImportObject(full_path)

    if not config_obj.IsTemplate():
        if properties:
            raise DeploymentManagerError(
                'The properties flag should only be used '
                'when passing in a template as your config file.')

        return config_obj

    # Otherwise we should build the config from scratch.
    base_name = config_obj.GetBaseName()

    # Build the single template resource.
    custom_resource = {'type': base_name, 'name': _SanitizeBaseName(base_name)}

    # Attach properties if we were given any.
    if properties:
        custom_resource['properties'] = properties

    # Add the import and single resource together into a config file.
    custom_dict = {
        'imports': [
            {
                'path': base_name
            },
        ],
        'resources': [
            custom_resource,
        ]
    }

    custom_outputs = []

    # Import the schema file and attach the outputs to config if there is any
    schema_path = config_obj.GetFullPath() + '.schema'
    schema_name = config_obj.GetName() + '.schema'

    schema_object = _BuildImportObject(schema_path, schema_name)

    if schema_object.Exists():
        schema_content = schema_object.GetContent()
        config_name = custom_resource['name']
        try:
            yaml_schema = yaml.safe_load(schema_content)
            if yaml_schema and OUTPUTS in yaml_schema:
                for output_name in yaml_schema[OUTPUTS].keys():
                    custom_outputs.append({
                        'name':
                        output_name,
                        'value':
                        '$(ref.' + config_name + '.' + output_name + ')'
                    })
        except yaml.YAMLError as e:
            raise exceptions.BadFileException('Invalid schema file %s. %s' %
                                              (schema_path, str(e)))

    if custom_outputs:
        custom_dict['outputs'] = custom_outputs

    # Dump using default_flow_style=False to use spacing instead of '{ }'
    custom_content = yaml.dump(custom_dict, default_flow_style=False)

    # Override the template_object with it's new config_content
    return config_obj.SetContent(custom_content)