66from requests import Session
77from urllib .parse import urljoin
88from uuid import UUID
9- from wal_e .cmd import configure_backup_cxt
109
11- from .utils import Attrs , defaulting , these
10+ from .utils import defaulting , these
1211from operator_ui .adapters .logger import logger
1312
1413session = Session ()
@@ -284,10 +283,8 @@ def read_stored_clusters(bucket, prefix, delimiter='/'):
284283def read_versions (
285284 pg_cluster ,
286285 bucket ,
287- s3_endpoint ,
288286 prefix ,
289287 delimiter = '/' ,
290- use_aws_instance_profile = False ,
291288):
292289 return [
293290 'base' if uid == 'wal' else uid
@@ -305,35 +302,72 @@ def read_versions(
305302 if uid == 'wal' or defaulting (lambda : UUID (uid ))
306303 ]
307304
308- BACKUP_VERSION_PREFIXES = ['' , '10/' , '11/' , '12/' , '13/' , '14/' , '15/' , '16/' , '17/' ]
305+ def lsn_to_wal_segment_stop (finish_lsn , start_segment , wal_segment_size = 16 * 1024 * 1024 ):
306+ timeline = int (start_segment [:8 ], 16 )
307+ log_id = finish_lsn >> 32
308+ seg_id = (finish_lsn & 0xFFFFFFFF ) // wal_segment_size
309+ return f"{ timeline :08X} { log_id :08X} { seg_id :08X} "
310+
311+ def lsn_to_offset_hex (lsn , wal_segment_size = 16 * 1024 * 1024 ):
312+ return f"{ lsn % wal_segment_size :08X} "
309313
310314def read_basebackups (
311315 pg_cluster ,
312316 uid ,
313317 bucket ,
314- s3_endpoint ,
315318 prefix ,
316- delimiter = '/' ,
317- use_aws_instance_profile = False ,
319+ postgresql_versions ,
318320):
319- environ ['WALE_S3_ENDPOINT' ] = s3_endpoint
320321 suffix = '' if uid == 'base' else '/' + uid
321322 backups = []
322323
323- for vp in BACKUP_VERSION_PREFIXES :
324-
325- backups = backups + [
326- {
327- key : value
328- for key , value in basebackup .__dict__ .items ()
329- if isinstance (value , str ) or isinstance (value , int )
330- }
331- for basebackup in Attrs .call (
332- f = configure_backup_cxt ,
333- aws_instance_profile = use_aws_instance_profile ,
334- s3_prefix = f's3://{ bucket } /{ prefix } { pg_cluster } { suffix } /wal/{ vp } ' ,
335- )._backup_list (detail = True )
336- ]
324+ for vp in postgresql_versions :
325+ backup_prefix = f'{ prefix } { pg_cluster } { suffix } /wal/{ vp } /basebackups_005/'
326+ logger .info (f"{ bucket } /{ backup_prefix } " )
327+
328+ paginator = client ('s3' ).get_paginator ('list_objects_v2' )
329+ pages = paginator .paginate (Bucket = bucket , Prefix = backup_prefix )
330+
331+ for page in pages :
332+ for obj in page .get ("Contents" , []):
333+ key = obj ["Key" ]
334+ if not key .endswith ("backup_stop_sentinel.json" ):
335+ continue
336+
337+ response = client ('s3' ).get_object (Bucket = bucket , Key = key )
338+ backup_info = loads (response ["Body" ].read ().decode ("utf-8" ))
339+ last_modified = response ["LastModified" ].astimezone (timezone .utc ).isoformat ()
340+
341+ backup_name = key .split ("/" )[- 1 ].replace ("_backup_stop_sentinel.json" , "" )
342+ start_seg , start_offset = backup_name .split ("_" )[1 ], backup_name .split ("_" )[- 1 ] if "_" in backup_name else None
343+
344+ if "LSN" in backup_info and "FinishLSN" in backup_info :
345+ # WAL-G
346+ lsn = backup_info ["LSN" ]
347+ finish_lsn = backup_info ["FinishLSN" ]
348+ backups .append ({
349+ "expanded_size_bytes" : backup_info .get ("UncompressedSize" ),
350+ "last_modified" : last_modified ,
351+ "name" : backup_name ,
352+ "wal_segment_backup_start" : start_seg ,
353+ "wal_segment_backup_stop" : lsn_to_wal_segment_stop (finish_lsn , start_seg ),
354+ "wal_segment_offset_backup_start" : lsn_to_offset_hex (lsn ),
355+ "wal_segment_offset_backup_stop" : lsn_to_offset_hex (finish_lsn ),
356+ })
357+ elif "wal_segment_backup_stop" in backup_info :
358+ # WAL-E
359+ stop_seg = backup_info ["wal_segment_backup_stop" ]
360+ stop_offset = backup_info ["wal_segment_offset_backup_stop" ]
361+
362+ backups .append ({
363+ "expanded_size_bytes" : backup_info .get ("expanded_size_bytes" ),
364+ "last_modified" : last_modified ,
365+ "name" : backup_name ,
366+ "wal_segment_backup_start" : start_seg ,
367+ "wal_segment_backup_stop" : stop_seg ,
368+ "wal_segment_offset_backup_start" : start_offset ,
369+ "wal_segment_offset_backup_stop" : stop_offset ,
370+ })
337371
338372 return backups
339373
0 commit comments