@RGJ da mesma forma, sou sincero ao dizer que, se alguém souber com certeza como evitar o imbróglio de reconstruir todas as imagens, estou totalmente a favor. E se eu fosse um desenvolvedor experiente do Discourse e soubesse como fazer isso facilmente, provavelmente teria feito isso desde o início.
Minha suposição é que migrar do S3 não é um caso comum para quem tem muitas imagens, então dificilmente vale a pena o tempo gasto, em comparação com adicionar recursos mais geralmente úteis ao Discourse. Eu tinha aproximadamente 100 GB de uploads importados do Google+ para o MakerForums e escolhemos o S3 com a ideia de que muitas pessoas poderiam migrar dessas comunidades para o MakerForums. No entanto, no final, apenas algumas comunidades migraram ativamente, e o crescimento contínuo não justificou permanecer no S3. Acredito que esse seja um caso bastante extremo, e o reprocessamento das imagens é um custo único.
Por fim, sou muito grato por você ter aberto esse tópico desde o início, pois, caso contrário, eu poderia facilmente ter perdido os uploads não relacionados a posts.
…
@RGJ Você está claramente certo de que destruir e recriar não é uma boa solução. Adicionei uma verificação: raise "Erro: URL do upload #{url} mudou para #{new_upload.short_url}, deveria permanecer inalterada." if url != new_upload.short_url, que pelo menos relata problemas com fontes corrompidas. A interrupção dos Digital Ocean Spaces de hoje enviou-me dados corrompidos, o que acionou esse erro para muitos uploads — não sei quantos. Mas, como já havia destruído o upload antigo, agora tenho algumas páginas corrompidas, e só percebi depois de perder o histórico de logs que indicava quais páginas estavam corrompidas. Assim, nem mesmo consigo corrigi-las manualmente a partir de um backup.
Portanto, embora meu trabalho seja uma melhoria em relação à maneira antiga, pois pelo menos relata alguns erros, seria muito melhor baixar os arquivos, verificar os SHA1 dos arquivos baixados e escrevê-los em arquivos locais. Enquanto isso, modifiquei meu PR para interromper a migração em qualquer erro não tratado, pelo menos para limitar a perda de dados.
Ainda acho que meu trabalho deve ser mesclado como uma melhoria de Pareto, já que não piora nada e, de fato, melhora a situação. No entanto, seria ainda melhor fazer da maneira correta. Acredito que isso envolveria criar lib/file_store/from_s3_migration.rb em paralelo a lib/file_store/to_s3_migration.rb, mas não estou à altura disso.
Como meu PR ainda não foi revisado, adicionei mais coisas a ele. Criei uma tarefa uploads:report_missing_uploads que percorre o campo raw procurando instâncias de upload://... onde o objeto de upload não está presente. Pelo menos no meu caso, com backups, poderei examinar meus backups, encontrar os arquivos órfãos e restaurá-los no site, depois recriar esses posts para restaurar as imagens que desapareceram. Encontrei 678 deles para buscar nos backups, dos quais já localizei todos, exceto 10, então estou feliz por ter escrito o teste! Preciso lidar com isso antes de avançar para a fase em que recriarei os posts restantes.
…
Concluí minha primeira fase de migração, sem incluir a recriação de posts afetados com uploads compartilhados e sem incluir uploads não relacionados a posts. Após concluir outro backup remoto, planejo testar esses recursos também e adicioná-los ao meu PR.
…
Agora comecei a testar as próximas fases da migração: recriação de posts e migração de uploads não relacionados a posts. Minha primeira lição foi que a recriação como próxima etapa falha devido a avatares de uploads não relacionados a posts em posts citados, então a recriação de posts precisa ser a última etapa.
Próxima descoberta: Obrigado, restrições de chave estrangeira! Ao migrar uploads não relacionados a posts, descobri que preciso migrar pelo menos os perfis antes de migrar os uploads não relacionados a posts de forma geral.
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"
A migração de perfis foi complicada, pois precisei migrar dois uploads anexados ao perfil, mas, em alguns casos, as pessoas usavam a mesma imagem para ambos, então precisei fazer esse trabalho em três etapas. Migrei com sucesso todos os perfis do meu site com URLs do S3.
Migrei todos os meus uploads não relacionados a posts e não relacionados a perfis. @RGJ, se quiser testar a branch que publiquei, ela está atualizada com meu trabalho. Tudo nela já foi usado para uma migração completa do site.
…
@cvx Não sei quando você terá a chance de revisar, mas sem meu PR, migrate_from_s3 definitivamente está cheio de bugs de destruição silenciosa de dados. O que fiz não é perfeito, mas protege contra muitos bugs que encontrei na prática.
Fiz todo o trabalho que pretendo fazer aqui por enquanto. Migrei meu site, o que significa que nem mesmo consigo avaliar efetivamente quaisquer alterações solicitadas. Se você rejeitar este PR, sugiro fortemente que, em vez disso, exclua a migração existente, pois ela destruirá dados silenciosamente para os usuários.
Em relação ao PR, às vezes obtenho falhas de teste no CI (na versão atual), algo assim:
7867 exemplos, 0 falhas, 11 pendentes, 1 erro ocorreu fora dos exemplos
##[error]Process completed with exit code 1.
Isso não se reproduz localmente (até agora) e não vejo nenhuma informação nos logs do CI que indique o que está errado no CI, então não vou perder mais tempo tentando explorar a saída do CI em busca de informações ocultas.
Uma última observação: Após concluir a migração, descobrimos que as fotos de perfil de alguns usuários foram perdidas durante a migração, e eles estão restaurando-as manualmente. Acredito que seria necessário código adicional para ter sucesso nisso, mas como só percebi isso tarde demais, não tenho um caso de teste para validar. Portanto, esse é um bug remanescente que pode causar problemas em algumas configurações, mas não estou mais em condições de escrever essa correção adicional.