全局与站点设置之间的 S3 配置预期

我有一个 Discourse 实例,在创建几个月后,我们仅通过管理员设置启用了“S3”(在我们的案例中是 DigitalOcean Spaces),而从未在 app.yml 文件中配置任何 DISCOURSE_ 环境变量选项。我们从未将全部内容迁移到 S3,但在启用该功能期间,大部分图片已写入 S3。现在出于各种此处不重要的原因,我们希望将所有内容从“S3”迁移出来。

(我知道这听起来像是一个支持帖子,但并非如此……)

在一个最近合并的 PR 中,我添加了一个 Rake 任务 uploads:batch_migrate_from_s3,作为 uploads:migrate_from_s3 的简单封装,以便能够迁移小到仅包含一个帖子图片的批次,并执行了该任务。此时我发现,我调用的 upload:migrate_from_s3 假设 discourse.conf 中包含 UI 中不可用的 S3 设置:

** Invoke uploads:batch_migrate_from_s3 (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute uploads:batch_migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `downcase' for nil:NilClass
/var/www/discourse/app/models/global_setting.rb:107:in `s3_bucket_name'
/var/www/discourse/app/models/site_setting.rb:157:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'

最佳解决方案是什么?

  1. 预期 S3 设置始终通过 app.yml 文件中的 DISCOURSE_ 环境变量完成,并在构建容器时写入 config/discourse.conf。我应该这样做并重新构建我的应用。(我注意到传递给 Rake 的环境变量输入似乎也没有在此处设置 GlobalSettings;我也尝试过这样做。显然,仅配置 SiteSettings 就能让某些功能正常运行是一个疏忽且非预期的行为。)我通过在现有容器的 config/discourse.conf 中添加 s3_bucket 进行了测试,这为我解决了错误。
  2. 进一步修改迁移任务,使得如果 SiteSetting.s3_upload_bucket 已设置但 GlobalSetting.s3_bucketnil,则将 GlobalSetting.s3_bucket 设置为 SiteSetting.s3_upload_bucket——我猜测如果这被认为是正确的做法,提交一个 PR 并不难,但我尚未深入查看。编辑:我尝试在 uploads:migrate_from_s3 中修改 GlobalSetting.s3_bucket,但由于缺少访问器而未成功。
  3. SiteSetting.absolute_base_urlGlobalSetting.s3_bucketnil 时使用 SiteSetting.s3_upload_bucket——这是否真的是预期的配置方式?
  4. 添加在站点设置中设置 s3_bucket 的功能,使其在 UI 中暴露。

第一种方案仅涉及站点配置,我可能会直接采用。如果第二种方案被视为良好的替代方案,我很乐意尝试提交 PR。然而,我在此领域还比较新,对于像后两种方案那样涉及核心逻辑的修改缺乏信心;我对配置对象如何工作的期望有些模糊不清。

明确说明:我已经通过简单的变通方法解决了我的问题;只是让我感到意外的是,竟然有必要这样做。

2 个赞