def VerifyObjectCustomAttribute(self, bucket_name, object_name, attr_name, expected_value, expected_present=True): """Retrieves and verifies an object's custom metadata attribute. Args: bucket_name: The name of the bucket the object is in. object_name: The name of the object itself. attr_name: The name of the custom metadata attribute. expected_value: The expected retrieved value for the attribute. expected_present: True if the attribute must be present in the object metadata, False if it must not be present. Returns: None """ gsutil_api = (self.json_api if self.default_provider == 'gs' else self.xml_api) metadata = gsutil_api.GetObjectMetadata( bucket_name, object_name, provider=self.default_provider, fields=['metadata/%s' % attr_name]) attr_present, value = GetValueFromObjectCustomMetadata( metadata, attr_name, default_value=expected_value) self.assertEqual(expected_present, attr_present) self.assertEqual(expected_value, value)
def DeserializeFileAttributesFromObjectMetadata(obj_metadata, url_str): """Parses the POSIX attributes from the supplied metadata. Args: obj_metadata: The metadata for an object. url_str: File/object path that provides context if a warning is thrown. Returns: A POSIXAttribute object with the retrieved values or a default value for any attribute that could not be found. """ posix_attrs = POSIXAttributes() # Parse atime. found, atime = GetValueFromObjectCustomMetadata(obj_metadata, ATIME_ATTR, NA_TIME) try: atime = long(atime) if found and atime <= NA_TIME: WarnNegativeAttribute('atime', url_str) atime = NA_TIME elif atime > long(time.time()) + SECONDS_PER_DAY: WarnFutureTimestamp('atime', url_str) atime = NA_TIME except ValueError: WarnInvalidValue('atime', url_str) atime = NA_TIME posix_attrs.atime = atime # Parse gid. DeserializeIDAttribute(obj_metadata, GID_ATTR, url_str, posix_attrs) # Parse uid. DeserializeIDAttribute(obj_metadata, UID_ATTR, url_str, posix_attrs) found, mode = GetValueFromObjectCustomMetadata(obj_metadata, MODE_ATTR, NA_MODE) if found and MODE_REGEX.match(mode): try: # Parse mode into a 3-digit base-8 number. posix_attrs.mode = POSIXMode(int(mode)) except ValueError: WarnInvalidValue('mode', url_str) return posix_attrs
def DeserializeIDAttribute(obj_metadata, attr, url_str, posix_attrs): """Parses the POSIX attributes from the supplied metadata into posix_attrs. Args: obj_metadata: The metadata for an object. attr: Either GID_ATTR or UID_ATTR. url_str: File/object path that provides context if a warning is thrown. posix_attrs: POSIXAttribute object. """ attr_name = attr.split('-')[-1] found, val = GetValueFromObjectCustomMetadata(obj_metadata, attr, NA_ID) try: val = int(val) if found and id <= NA_ID: WarnNegativeAttribute(attr_name, url_str) val = NA_ID except ValueError: WarnInvalidValue(attr_name, url_str) val = NA_ID setattr(posix_attrs, attr_name, val)
def ParseAndSetPOSIXAttributes(path, obj_metadata, is_rsync=False, preserve_posix=False): """Parses POSIX attributes from obj_metadata and sets them. Attributes will only be set if they exist in custom metadata. This function should only be called after ValidateFilePermissionAccess has been called for the specific file/object so as not to orphan files. Args: path: The local filesystem path for the file. Valid metadata attributes will be set for the file located at path, some attributes will only be set if preserve_posix is set to True. obj_metadata: The metadata for the file/object. is_rsync: Whether or not the caller is the rsync command. Used to determine if timeCreated should be used. preserve_posix: Whether or not all POSIX attributes should be set. """ if obj_metadata is None: # This exception is meant for debugging purposes as it should never be # thrown unless there are unexpected code changes. raise CommandException('obj_metadata cannot be None for %s' % path) try: found_at, atime = GetValueFromObjectCustomMetadata( obj_metadata, ATIME_ATTR, default_value=NA_TIME) found_mt, mtime = GetValueFromObjectCustomMetadata( obj_metadata, MTIME_ATTR, default_value=NA_TIME) found_uid, uid = GetValueFromObjectCustomMetadata(obj_metadata, UID_ATTR, default_value=NA_ID) found_gid, gid = GetValueFromObjectCustomMetadata(obj_metadata, GID_ATTR, default_value=NA_ID) found_mode, mode = GetValueFromObjectCustomMetadata( obj_metadata, MODE_ATTR, default_value=NA_MODE) if not found_mode: mode = int(GetDefaultMode()) if found_mt: mtime = long(mtime) if not preserve_posix: atime_tmp = os.stat(path).st_atime os.utime(path, (atime_tmp, mtime)) return elif is_rsync: mtime = ConvertDatetimeToPOSIX(obj_metadata.timeCreated) os.utime(path, (mtime, mtime)) if not preserve_posix: return if found_at: atime = long(atime) if atime > NA_TIME and mtime > NA_TIME: # Set both atime and mtime. os.utime(path, (atime, mtime)) elif atime > NA_TIME and mtime <= NA_TIME: # atime is valid but mtime isn't. mtime_tmp = os.stat(path).st_mtime os.utime(path, (atime, mtime_tmp)) elif atime <= NA_TIME and mtime > NA_TIME: # mtime is valid but atime isn't atime_tmp = os.stat(path).st_atime os.utime(path, (atime_tmp, mtime)) if IS_WINDOWS: # Windows doesn't use POSIX uid/gid/mode unlike other systems. So there's # no point continuing. return if found_uid: uid = int(uid) if found_gid: gid = int(gid) if uid > NA_ID and gid > NA_ID: # Set both uid and gid. os.chown(path, uid, gid) elif uid > NA_ID and gid <= NA_ID: # uid is valid but gid isn't. os.chown(path, uid, -1) elif uid <= NA_ID and gid > NA_ID: # gid is valid but uid isn't. os.chown(path, -1, gid) if found_mode: mode = int(str(mode), 8) os.chmod(path, mode) except ValueError: raise CommandException('Check POSIX attribute values for %s' % obj_metadata.name)