Ao longo dos anos, vimos muitos, muitos problemas com a migração para o s3, incluindo migrações implícitas ao restaurar um backup.
EXCEPTION: 8 posts are not remapped to new S3 upload URL. S3 migration failed for db 'default'.
Alguns dos muitos exemplos:
- False positives on "posts are not remapped to new S3 upload URL"
- Restore process cancelled at migrating uploads to S3 step
- Restore to New Host
Hoje, encontrei mais um desses e, como era sexta-feira, decidi investigar em vez de apenas comentar a verificação.
Então temos esta situação:
- estamos em multisite
- vamos assumir
dbnamecomo o nome do banco de dados para este exemplo - temos
S3_CDN_URLdefinido - não temos
CDN_URLdefinido
Isto é o que acontece em /lib/file_store/to_s3_migration.rb
Primeiro o prefixo é decidido
prefix = @migrate_to_multisite ? "uploads/#{@current_db}/original/" : "original/"
Em seguida, os arquivos são carregados no s3 e depois o remapeamento é feito, que é basicamente isto e algumas variações
from = "/uploads/#{@current_db}/original/"
to = "#{SiteSetting.Upload.s3_base_url}/#{prefix}"
Então, em multisite, isso irá remapear
- de
/uploads/dbname/original/ - para
https://bucket-location-url.com/uploads/dbname/original/
e então finalmente a verificação é feita
cdn_path = SiteSetting.cdn_path("/uploads/#{@current_db}/original").sub(/https?:/, "")
count = Post.where("cooked LIKE '%#{cdn_path}%'").count
if count > 0
error_message = "#{count} posts are not remapped to new S3 upload URL. #{failure_message}"
raise_or_log(error_message, should_raise)
success = false
end
Agora SiteSetting.cdn_path vem de lib/global_path.rb e se parece com isto
def cdn_path(p)
GlobalSetting.cdn_url.blank? ? p : "#{GlobalSetting.cdn_url}#{path(p)}"
end
Entãooooooo, se tivermos um CDN S3, mas não um CDN regular, então SiteSetting.cdn_path("/uploads/#{@current_db}/original") será simplesmente /uploads/dbname/original
e, de acordo com nosso remapeamento, os novos caminhos são https://bucket-location-url.com/uploads/dbname/original/
Isso significa que
cdn_pathé uma substring do novo caminho de destino- o
Post.where("cooked LIKE '%#{cdn_path}%'").countassim sempre encontrará posts - ele gritará lobo e falhará
