def __iter__(self): # Try to identify the sentinel file. This is sort of a drag, the # storage format should be changed to put them in their own leaf # directory. # # TODO: change storage format sentinel_depth = self.layout.basebackups().count('/') matcher = re.compile(storage.COMPLETE_BASE_BACKUP_REGEXP).match for key in self._backup_list(self.layout.basebackups()): key_name = self.layout.key_name(key) # Use key depth vs. base and regexp matching to find # sentinel files. key_depth = key_name.count('/') if key_depth == sentinel_depth: backup_sentinel_name = key_name.rsplit('/', 1)[-1] match = matcher(backup_sentinel_name) if match: # TODO: It's necessary to use the name of the file to # get the beginning wal segment information, whereas # the ending information is encoded into the file # itself. Perhaps later on it should all be encoded # into the name when the sentinel files are broken out # into their own directory, so that S3 listing gets # all commonly useful information without doing a # request-per. groups = match.groupdict() info = storage.get_backup_info( self.layout, name='base_{filename}_{offset}'.format(**groups), last_modified=self.layout.key_last_modified(key), wal_segment_backup_start=groups['filename'], wal_segment_offset_backup_start=groups['offset']) if self.detail: try: # This costs one web request info.load_detail(self.conn) except gevent.Timeout: pass yield info