Migração para s3 falhou - mas apenas a verificação falha

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:

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 dbname como o nome do banco de dados para este exemplo
  • temos S3_CDN_URL definido
  • não temos CDN_URL definido

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

  1. cdn_path é uma substring do novo caminho de destino
  2. o Post.where("cooked LIKE '%#{cdn_path}%'").count assim sempre encontrará posts
  3. ele gritará lobo e falhará :scream: :scream: :scream:
3 curtidas