예제 #1
0
    def SetMetadataFunc(self, name_expansion_result, thread_state=None):
        """Sets metadata on an object.

    Args:
      name_expansion_result: NameExpansionResult describing target object.
      thread_state: gsutil Cloud API instance to use for the operation.
    """
        gsutil_api = GetCloudApiInstance(self, thread_state=thread_state)

        exp_src_url = name_expansion_result.expanded_storage_url
        self.logger.info("Setting metadata on %s...", exp_src_url)

        fields = ["generation", "metadata", "metageneration"]
        cloud_obj_metadata = gsutil_api.GetObjectMetadata(
            exp_src_url.bucket_name,
            exp_src_url.object_name,
            generation=exp_src_url.generation,
            provider=exp_src_url.scheme,
            fields=fields,
        )

        preconditions = Preconditions(
            gen_match=self.preconditions.gen_match, meta_gen_match=self.preconditions.meta_gen_match
        )
        if preconditions.gen_match is None:
            preconditions.gen_match = cloud_obj_metadata.generation
        if preconditions.meta_gen_match is None:
            preconditions.meta_gen_match = cloud_obj_metadata.metageneration

        # Patch handles the patch semantics for most metadata, but we need to
        # merge the custom metadata field manually.
        patch_obj_metadata = ObjectMetadataFromHeaders(self.metadata_change)

        api = gsutil_api.GetApiSelector(provider=exp_src_url.scheme)
        # For XML we only want to patch through custom metadata that has
        # changed.  For JSON we need to build the complete set.
        if api == ApiSelector.XML:
            pass
        elif api == ApiSelector.JSON:
            CopyObjectMetadata(patch_obj_metadata, cloud_obj_metadata, override=True)
            patch_obj_metadata = cloud_obj_metadata
            # Patch body does not need the object generation and metageneration.
            patch_obj_metadata.generation = None
            patch_obj_metadata.metageneration = None

        gsutil_api.PatchObjectMetadata(
            exp_src_url.bucket_name,
            exp_src_url.object_name,
            patch_obj_metadata,
            generation=exp_src_url.generation,
            preconditions=preconditions,
            provider=exp_src_url.scheme,
        )
예제 #2
0
    def SetMetadataFunc(self, name_expansion_result, thread_state=None):
        """Sets metadata on an object.

    Args:
      name_expansion_result: NameExpansionResult describing target object.
      thread_state: gsutil Cloud API instance to use for the operation.
    """
        gsutil_api = GetCloudApiInstance(self, thread_state=thread_state)

        exp_src_url = name_expansion_result.expanded_storage_url
        self.logger.info('Setting metadata on %s...', exp_src_url)

        cloud_obj_metadata = encoding.JsonToMessage(
            apitools_messages.Object, name_expansion_result.expanded_result)

        preconditions = Preconditions(
            gen_match=self.preconditions.gen_match,
            meta_gen_match=self.preconditions.meta_gen_match)
        if preconditions.gen_match is None:
            preconditions.gen_match = cloud_obj_metadata.generation
        if preconditions.meta_gen_match is None:
            preconditions.meta_gen_match = cloud_obj_metadata.metageneration

        # Patch handles the patch semantics for most metadata, but we need to
        # merge the custom metadata field manually.
        patch_obj_metadata = ObjectMetadataFromHeaders(self.metadata_change)

        api = gsutil_api.GetApiSelector(provider=exp_src_url.scheme)
        # For XML we only want to patch through custom metadata that has
        # changed.  For JSON we need to build the complete set.
        if api == ApiSelector.XML:
            pass
        elif api == ApiSelector.JSON:
            CopyObjectMetadata(patch_obj_metadata,
                               cloud_obj_metadata,
                               override=True)
            patch_obj_metadata = cloud_obj_metadata
            # Patch body does not need the object generation and metageneration.
            patch_obj_metadata.generation = None
            patch_obj_metadata.metageneration = None

        gsutil_api.PatchObjectMetadata(exp_src_url.bucket_name,
                                       exp_src_url.object_name,
                                       patch_obj_metadata,
                                       generation=exp_src_url.generation,
                                       preconditions=preconditions,
                                       provider=exp_src_url.scheme,
                                       fields=['id'])
        _PutToQueueWithTimeout(gsutil_api.status_queue,
                               MetadataMessage(message_time=time.time()))
예제 #3
0
  def ObjectUpdateMetadataFunc(self,
                               patch_obj_metadata,
                               log_template,
                               name_expansion_result,
                               thread_state=None):
    """Updates metadata on an object using PatchObjectMetadata.

    Args:
      patch_obj_metadata: Metadata changes that should be applied to the
                          existing object.
      log_template: The log template that should be printed for each object.
      name_expansion_result: NameExpansionResult describing target object.
      thread_state: gsutil Cloud API instance to use for the operation.
    """
    gsutil_api = GetCloudApiInstance(self, thread_state=thread_state)

    exp_src_url = name_expansion_result.expanded_storage_url
    self.logger.info(log_template, exp_src_url)

    cloud_obj_metadata = encoding.JsonToMessage(
        apitools_messages.Object, name_expansion_result.expanded_result)

    preconditions = Preconditions(
        gen_match=self.preconditions.gen_match,
        meta_gen_match=self.preconditions.meta_gen_match)
    if preconditions.gen_match is None:
      preconditions.gen_match = cloud_obj_metadata.generation
    if preconditions.meta_gen_match is None:
      preconditions.meta_gen_match = cloud_obj_metadata.metageneration

    gsutil_api.PatchObjectMetadata(
        exp_src_url.bucket_name,
        exp_src_url.object_name,
        patch_obj_metadata,
        generation=exp_src_url.generation,
        preconditions=preconditions,
        provider=exp_src_url.scheme,
        fields=['id'])
    PutToQueueWithTimeout(
        gsutil_api.status_queue, MetadataMessage(message_time=time.time()))
예제 #4
0
def PreconditionsFromHeaders(headers):
  """Creates bucket or object preconditions acccording to the provided headers.

  Args:
    headers: Dict of headers passed via gsutil -h

  Returns:
    gsutil Cloud API Preconditions object fields populated from headers, or None
    if no precondition headers are present.
  """
  return_preconditions = Preconditions()
  try:
    for header, value in headers.items():
      if GOOG_GENERATION_MATCH_REGEX.match(header):
        return_preconditions.gen_match = long(value)
      if GOOG_METAGENERATION_MATCH_REGEX.match(header):
        return_preconditions.meta_gen_match = long(value)
  except ValueError, _:
    raise ArgumentException('Invalid precondition header specified. '
                            'x-goog-if-generation-match and '
                            'x-goog-if-metageneration match must be specified '
                            'with a positive integer value.')
예제 #5
0
def PreconditionsFromHeaders(headers):
  """Creates bucket or object preconditions acccording to the provided headers.

  Args:
    headers: Dict of headers passed via gsutil -h

  Returns:
    gsutil Cloud API Preconditions object fields populated from headers, or None
    if no precondition headers are present.
  """
  return_preconditions = Preconditions()
  try:
    for header, value in headers.items():
      if GOOG_GENERATION_MATCH_REGEX.match(header):
        return_preconditions.gen_match = long(value)
      if GOOG_METAGENERATION_MATCH_REGEX.match(header):
        return_preconditions.meta_gen_match = long(value)
  except ValueError, _:
    raise ArgumentException('Invalid precondition header specified. '
                            'x-goog-if-generation-match and '
                            'x-goog-if-metageneration match must be specified '
                            'with a positive integer value.')
예제 #6
0
  def ApplyAclChanges(self, name_expansion_result, thread_state=None):
    """Applies the changes in self.changes to the provided URL.

    Args:
      name_expansion_result: NameExpansionResult describing the target object.
      thread_state: If present, gsutil Cloud API instance to apply the changes.
    """
    if thread_state:
      gsutil_api = thread_state
    else:
      gsutil_api = self.gsutil_api

    url_string = name_expansion_result.GetExpandedUrlStr()
    url = StorageUrlFromString(url_string)

    if url.IsBucket():
      bucket = gsutil_api.GetBucket(url.bucket_name, provider=url.scheme,
                                    fields=['acl', 'metageneration'])
      current_acl = bucket.acl
    elif url.IsObject():
      gcs_object = gsutil_api.GetObjectMetadata(
          url.bucket_name, url.object_name, provider=url.scheme,
          generation=url.generation,
          fields=['acl', 'generation', 'metageneration'])
      current_acl = gcs_object.acl
    if not current_acl:
      self._WarnServiceAccounts()
      self.logger.warning('Failed to set acl for %s. Please ensure you have '
                          'OWNER-role access to this resource.' % url_string)
      return

    modification_count = 0
    for change in self.changes:
      modification_count += change.Execute(url_string, current_acl,
                                           self.logger)
    if modification_count == 0:
      self.logger.info('No changes to {0}'.format(url_string))
      return

    try:
      if url.IsBucket():
        preconditions = Preconditions(meta_gen_match=bucket.metageneration)
        bucket_metadata = apitools_messages.Bucket(acl=current_acl)
        gsutil_api.PatchBucket(url.bucket_name, bucket_metadata,
                               preconditions=preconditions,
                               provider=url.scheme, fields=['id'])
      else:  # Object
        preconditions = Preconditions(meta_gen_match=gcs_object.metageneration)
        # If we're operating on the live version of the object, only apply
        # if the live version hasn't changed or been overwritten.  If we're
        # referring to a version explicitly, then we don't care what the live
        # version is and we will change the ACL on the requested version.
        if not url.generation:
          preconditions.gen_match = gcs_object.generation

        object_metadata = apitools_messages.Object(acl=current_acl)
        gsutil_api.PatchObjectMetadata(
            url.bucket_name, url.object_name, object_metadata,
            preconditions=preconditions, provider=url.scheme,
            generation=url.generation)
    except BadRequestException as e:
      # Don't retry on bad requests, e.g. invalid email address.
      raise CommandException('Received bad request from server: %s' % str(e))

    self.logger.info('Updated ACL on {0}'.format(url_string))