@@ -271,6 +271,7 @@ def hard_delete_expired_soft_deleted_objects():
271271 prefix_exclude = QUERY_RESULTS_FILE_PREFIX , # handled by diff cron task.
272272 )
273273
274+ objects_to_re_soft_delete = []
274275 for object_name in candidate_objects_to_purge :
275276 protected_ids = protected_versions_map .get (object_name , set ())
276277
@@ -283,8 +284,11 @@ def hard_delete_expired_soft_deleted_objects():
283284 # Delete both file versions and delete markers of the object.
284285 objects_to_delete = []
285286 for version in versions_resp .get ("Versions" , []):
286- if version ["Key" ] == object_name and version ["VersionId" ] not in protected_ids :
287- objects_to_delete .append ({"Key" : object_name , "VersionId" : version ["VersionId" ]})
287+ if version ["Key" ] == object_name :
288+ if version ["VersionId" ] not in protected_ids :
289+ objects_to_delete .append ({"Key" : object_name , "VersionId" : version ["VersionId" ]})
290+ else :
291+ objects_to_re_soft_delete .append (object_name )
288292
289293 for marker in versions_resp .get ("DeleteMarkers" , []):
290294 if marker ["Key" ] == object_name :
@@ -298,10 +302,11 @@ def hard_delete_expired_soft_deleted_objects():
298302
299303 per_project_delete_count [project .name ] += len (objects_to_delete )
300304
301- # We take advantage of a special behaviour of S3, that you can delete objects that don't exist.
302- # This ensures that if a protected version now becomes the latest, it wont be used in queries/downloadable etc..
305+ # If the latest version of a file was hard deleted, but an older version is protected.
306+ # Then we need to re-add a delete marker, otherwise the protected file will become the latest.
307+ # Which would make it show up in ls, download and query jobs...
303308 s3_file_manager .soft_delete_objects (
304- objects = list ( candidate_objects_to_purge ) ,
309+ objects = objects_to_re_soft_delete ,
305310 bucket_name = project .bucket_name ,
306311 )
307312
0 commit comments