将 S3/Spaces 非图片上传迁移至本地

我已阅读以下页面:

因此,我查看了 lib/tasks/uploads.rake:migrate_from_s3,发现:

    .where("raw LIKE '%.s3%.amazonaws.com/%' OR raw LIKE '%(upload://%'")

然而,我注意到视频上传不会获得原生的 upload:// 伪协议,而是直接变成指向存储提供商(在我的案例中是 DigitalOcean Spaces)的字面链接。

显然,我必须修改此任务才能成功。

与其(或除了)直接引用 Amazon,是否更合理地去查看 SiteSetting.s3_endpointSiteSetting.s3_upload_bucket

这些任务有测试吗?我没看到。我有一个看似显而易见的修复方案,但无法增强现有测试,也没有简单的方法进行非破坏性测试。这让我感到不安……

index 0761c4712a..63f49155f3 100644
--- a/lib/tasks/uploads.rake
+++ b/lib/tasks/uploads.rake
@@ -129,12 +129,12 @@ def migrate_from_s3
 
   Post
     .where("user_id > 0")
-    .where("raw LIKE '%.s3%.amazonaws.com/%' OR raw LIKE '%(upload://%'")
+    .where("raw LIKE '%.s3%.amazonaws.com/%' OR raw LIKE '%#{SiteSetting.Upload.absolute_base_url}%' OR raw LIKE '%(upload://%'")
     .find_each do |post|
     begin
       updated = false
 
-      post.raw.gsub!(/(\/\/[\w.-]+amazonaws\.com\/(original|optimized)\/([a-z0-9]+\/)+\h{40}([\w.-]+)?)/i) do |url|
+      post.raw.gsub!(/(\/\/[\w.-]+(amazonaws\.com|#{Regexp.quote(SiteSetting.s3_endpoint)})\/(original|optimized)\/([a-z0-9]+\/)+\h{40}([\w.-]+)?)/i) do |url|
         begin
           if filename = guess_filename(url, post.raw)
             file = FileHelper.download("http:#{url}", max_file_size: max_file_size, tmp_file_name: "from_s3", follow_redirect: true)

此外,根据我的经验,即使所有这些图片都已经被优化过,系统仍可能决定花费 10 天时间重新优化所有 50GB 的图片(总共 96GB 的文件,包括原始和优化后的文件),在迁移过程中这样做会同时关闭整个站点的所有邮件通知。由于我没有好的测试方法,我想确认一下是否真的会这样;如果是的话,我想知道是否有办法绕过它,直接复制已经优化好的图片。

我可以轻松使用 MinIO Client 将所有文件复制到本地系统。我很好奇,如果直接将文件放置到位并修改数据库以指向新位置,而不重新优化所有图片,会有多困难……

我目前还没有测试,但至少它是作为拉取请求分享的,而不仅仅是一个元帖子。

更多相关修复,现已通过真实迁移流程验证,见新 PR

https://github.com/discourse/discourse/pull/10093