diff --git a/controllers/maintenance_controller/maintainance_controller.go b/controllers/maintenance_controller/maintainance_controller.go index 34cc640910643f5d509d2bd7e2dffd43e1a5dd1a..c9b701e379225b6bd38959a72bfa3d17545d45fb 100644 --- a/controllers/maintenance_controller/maintainance_controller.go +++ b/controllers/maintenance_controller/maintainance_controller.go @@ -283,10 +283,27 @@ func doPurge(media *types.Media, ctx context.Context, log *logrus.Entry) error { return err } - err = ds.DeleteObject(media.Location) + mediaDb := storage.GetDatabase().GetMediaStore(ctx, log) + similarMedia, err := mediaDb.GetByHash(media.Sha256Hash) if err != nil { return err } + hasSimilar := false + for _, m := range similarMedia { + if m.Origin != media.Origin && m.MediaId != media.MediaId { + hasSimilar = true + break + } + } + + if !hasSimilar || media.Quarantined { + err = ds.DeleteObject(media.Location) + if err != nil { + return err + } + } else { + log.Warnf("Not deleting media from datastore: media is shared over %d objects", len(similarMedia)) + } metadataDb := storage.GetDatabase().GetMetadataStore(ctx, log) @@ -308,7 +325,6 @@ func doPurge(media *types.Media, ctx context.Context, log *logrus.Entry) error { return nil } - mediaDb := storage.GetDatabase().GetMediaStore(ctx, log) err = mediaDb.Delete(media.Origin, media.MediaId) if err != nil { return err diff --git a/docs/admin.md b/docs/admin.md index 945e48bc60264ed2025cc4d536916d0384d0508e..466a1d6dcc0b3b100265eb012d2a73796fb75766 100644 --- a/docs/admin.md +++ b/docs/admin.md @@ -6,6 +6,8 @@ All the API calls here require your user ID to be listed in the configuration as Sometimes you just want your disk space back - purging media is the best way to do that. **Be careful about what you're purging.** The media repo will happily purge a local media object, making it highly unlikely to ever exist in Matrix again. When the media repo deletes remote media, it is only deleting its copy of it - it cannot delete media on the remote server itself. Thumbnails will also be deleted for the media. +If the file is duplicated over many media records, it will not be physically deleted (however the media record that was purged will be counted as deleted). The exception to this is quarantined media: when the record being purged is also quarantined, the media is deleted from the datastore even if it is duplicated in multiple records. + #### Purge remote media URL: `POST /_matrix/media/unstable/admin/purge/remote?before_ts=1234567890&access_token=your_access_token` (`before_ts` is in milliseconds)