Migrate_to_S3 не удаётся при ребейке

С помощью @itsbhanusharma я работал над переносом моих старых загрузок в S3.

Я следовал инструкциям из этого руководства:

После пересборки загрузки всё ещё не переместились в S3, что странно. Discourse-doctor сообщил о проблеме с DNS:

> 
> ========================================
> Версия Discourse на : НЕ НАЙДЕНО
> Версия Discourse на localhost: Discourse 2.5.0.beta4
> **> ==================== ПРОБЛЕМА С DNS ====================**
> **> Этот сервер сообщает о версии Discourse 2.5.0.beta4, но на самом деле НЕ НАЙДЕНО.**
> **> Это указывает на проблему с DNS или на то, что виноват промежуточный прокси.**
> **> Если вы используете Cloudflare или CDN, возможно, они настроены неправильно.**

Я выполнил ручную миграцию в S3 и получил следующее:

 > root@discourse-app:/var/www/discourse# rake --trace uploads:migrate_to_s3
 > ** Вызов uploads:migrate_to_s3 (первый раз)
 > ** Вызов environment (первый раз)
 > ** Выполнение environment
 > ** Выполнение uploads:migrate_to_s3
 > Миграция загрузок в S3 для 'default'...
 > Загрузка файлов в S3...
 >  - Список локальных файлов
 > .. => 2980 файлов
 >  - Список файлов в S3
 > .... => 3156 файлов
 >  - Синхронизация файлов с S3
 > ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
 > Обновление URL-адресов в базе данных...
 > Предупреждение: для типа "name" с oid 19 не определено приведение типа. Пожалуйста, явно приведите этот тип к TEXT, чтобы избежать проблем в будущем.
 > Удаление старых оптимизированных изображений...
 > Пометка всех постов, содержащих лайтбоксы, для пересборки...
 > 781 постов помечено для пересборки
 > rake aborted!
 > FileStore::ToS3MigrationError: 68 постов не переназначены на новый URL загрузки S3. Миграция в S3 не удалась для базы данных 'default'.
 > /var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log'
 > /var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?'
 > /var/www/discourse/lib/file_store/to_s3_migration.rb:351:in `migrate_to_s3'
 > /var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate'
 > /var/www/discourse/lib/tasks/uploads.rake:239:in `migrate_to_s3'
 > /var/www/discourse/lib/tasks/uploads.rake:218:in `block in migrate_to_s3_all_sites'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.1.2/lib/rails_multisite/connection_management.rb:64:in `with_connection'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.1.2/lib/rails_multisite/connection_management.rb:74:in `each_connection'
 > /var/www/discourse/lib/tasks/uploads.rake:216:in `migrate_to_s3_all_sites'
 > /var/www/discourse/lib/tasks/uploads.rake:212:in `block in <top (required)>'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `block in execute'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `each'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `execute'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
 > /usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:188:in `invoke'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:160:in `invoke_task'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `each'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block in top_level'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:125:in `run_with_threads'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:110:in `top_level'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:83:in `block in run'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:186:in `standard_exception_handling'
 > /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:80:in `run'
 > bin/rake:13:in `<top (required)>'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:24:in `start'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:46:in `block in <top (required)>'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/friendly_errors.rb:123:in `with_friendly_errors'
 > /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
 > /usr/local/bin/bundle:23:in `load'
 > /usr/local/bin/bundle:23:in `<main>'
 > Задачи: TOP => uploads:migrate_to_s3
 > root@discourse-app:/var/www/discourse#

Есть какие-то мысли по этому поводу, @gerhard?

Это не работает, потому что не проходит следующая проверка:

Я предлагаю вам выяснить, почему эти пути не отображаются корректно. Попробуйте выполнить следующее в консоли Rails, чтобы просмотреть поле cooked для этих постов. Где-то там может быть подсказка…

current_db = RailsMultisite::ConnectionManagement.current_db
cdn_path = SiteSetting.cdn_path("/uploads/#{current_db}/original").sub(/https?:/, "")
Post.where("cooked LIKE '%#{cdn_path}%'").pluck(:cooked)

Вот вывод из консоли rails: (это лишь его часть, и он выглядит не очень красиво)

root@discourse-app:/var/www/discourse# rails console
[1] pry(main)> current_db = RailsMultisite::ConnectionManagement.current_db
=> "default"
[2] pry(main)> cdn_path = SiteSetting.cdn_path("/uploads/#{current_db}/original").sub(/https?:/, "")
=> "/uploads/default/original"
[3] pry(main)> Post.where("cooked LIKE '%#{cdn_path}%'").pluck(:cooked)
=> ["<p>U.C. Tricolor frag $30<br>\nRed Stylocoeniella $30<br>\nBranching Cyphastrea $40<br>\nOrenji Mont frag $30</p>\n<hr>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534.jpeg\" data-download-href=\"/uploads/short-url/5Jf4Z7WaQqYix5IDWN12IlLoYfi.jpeg?dl=1\" title=\"DSCN0069-005.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534_2_524x500.jpeg\" alt=\"DSCN0069-005.JPG\" data-base62-sha1=\"5Jf4Z7WaQqYix5IDWN12IlLoYfi\" width=\"524\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534_2_524x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534_2_786x750.jpeg 1.5x, /uploads/default/original/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/2/282821b1e16dce48ac11f1d607412e1bfed61534_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0069-005.JPG</span><span class=\"informations\">800×762 181 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5.jpeg\" data-download-href=\"/uploads/short-url/lprJZk3t4LfijslovcQ9kgaqzcN.jpeg?dl=1\" title=\"DSCN0119-003.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5_2_513x500.jpeg\" alt=\"DSCN0119-003.JPG\" data-base62-sha1=\"lprJZk3t4LfijslovcQ9kgaqzcN\" width=\"513\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5_2_513x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5_2_769x750.jpeg 1.5x, /uploads/default/original/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/9/960e0f184917ad7e0bbf2d6c31cf546fa9e124f5_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0119-003.JPG</span><span class=\"informations\">800×779 186 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/5/548f0324f3b0e8dd482729c1d1f5c450b5556919.jpeg\" data-download-href=\"/uploads/short-url/c42vC8e8IRT52htW2RX7YedLpaN.jpeg?dl=1\" title=\"DSCN0072-004.JPG\"><img src=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/5/548f0324f3b0e8dd482729c1d1f5c450b5556919.jpeg\" alt=\"DSCN0072-004.JPG\" data-base62-sha1=\"c42vC8e8IRT52htW2RX7YedLpaN\" width=\"468\" height=\"500\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/5/548f0324f3b0e8dd482729c1d1f5c450b5556919_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0072-004.JPG</span><span class=\"informations\">750×800 180 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8.jpeg\" data-download-href=\"/uploads/short-url/vshBXgkYrsRhRqNFakI1jgIE5Sg.jpeg?dl=1\" title=\"DSCN0060-005.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8_2_396x500.jpeg\" alt=\"DSCN0060-005.JPG\" data-base62-sha1=\"vshBXgkYrsRhRqNFakI1jgIE5Sg\" width=\"396\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8_2_396x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8_2_594x750.jpeg 1.5x, /uploads/default/original/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/d/dc75e2b57072ff260f99cfa9a7cc1e4f39c207f8_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0060-005.JPG</span><span class=\"informations\">635×800 196 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>",
 "<p>U.C. Raspberry delight frag $39 „radion”<br>\nORA Kelly green psammacora $39 \"radion<br>\nU.C. Red Dragon Frag $30<br>\nU.C. Red dragon Smaller frag $20</p>\n<hr>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/d/deb035a3639a3a3bb8b04ebd9da2b97fb5d8652d.jpeg\" data-download-href=\"/uploads/short-url/vLZwAqgUqcslrwos7Q27gheEVSR.jpeg?dl=1\" title=\"DSCN9908-003.JPG\"><img src=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/d/deb035a3639a3a3bb8b04ebd9da2b97fb5d8652d.jpeg\" alt=\"DSCN9908-003.JPG\" data-base62-sha1=\"vLZwAqgUqcslrwos7Q27gheEVSR\" width=\"561\" height=\"500\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/d/deb035a3639a3a3bb8b04ebd9da2b97fb5d8652d_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN9908-003.JPG</span><span class=\"informations\">800×712 165 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/e/e579dab30a023f12755b22e8bb1c077b34225110.jpeg\" data-download-href=\"/uploads/short-url/wK2pz5DNtgezJhhQuxaFE52CvnO.jpeg?dl=1\" title=\"DSCN0059-005.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e579dab30a023f12755b22e8bb1c077b34225110_2_450x500.jpeg\" alt=\"DSCN0059-005.JPG\" data-base62-sha1=\"wK2pz5DNtgezJhhQuxaFE52CvnO\" width=\"450\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e579dab30a023f12755b22e8bb1c077b34225110_2_450x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e579dab30a023f12755b22e8bb1c077b34225110_2_675x750.jpeg 1.5x, /uploads/default/original/2X/e/e579dab30a023f12755b22e8bb1c077b34225110.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e579dab30a023f12755b22e8bb1c077b34225110_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0059-005.JPG</span><span class=\"informations\">721×800 231 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/e/e5d72072aee537852120d7106522b543e6af9085.jpeg\" data-download-href=\"/uploads/short-url/wNgfm2qrVEyTWGfUV3QAc2EGKfX.jpeg?dl=1\" title=\"DSCN0066-005.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e5d72072aee537852120d7106522b543e6af9085_2_506x500.jpeg\" alt=\"DSCN0066-005.JPG\" data-base62-sha1=\"wNgfm2qrVEyTWGfUV3QAc2EGKfX\" width=\"506\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e5d72072aee537852120d7106522b543e6af9085_2_506x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e5d72072aee537852120d7106522b543e6af9085_2_759x750.jpeg 1.5x, /uploads/default/original/2X/e/e5d72072aee537852120d7106522b543e6af9085.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/e/e5d72072aee537852120d7106522b543e6af9085_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0066-005.JPG</span><span class=\"informations\">800×790 200 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"//brcuploads.s3.dualstack.us-east-1.amazonaws.com/original/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e.jpeg\" data-download-href=\"/uploads/short-url/8G3Jz9KwzbbXzYx3PYei4ayTmSa.jpeg?dl=1\" title=\"DSCN0068-005.JPG\"><img src=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e_2_395x500.jpeg\" alt=\"DSCN0068-005.JPG\" data-base62-sha1=\"8G3Jz9KwzbbXzYx3PYei4ayTmSa\" width=\"395\" height=\"500\" srcset=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e_2_395x500.jpeg, https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e_2_592x750.jpeg 1.5x, /uploads/default/original/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e.jpeg 2x\" data-small-upload=\"https://d2hneyr8lp58j4.cloudfront.net/optimized/2X/3/3cd28b0f2704180632ca5e714241b6b62f63459e_2_10x10.png\"><div class=\"meta\"><svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">DSCN0068-005.JPG</span><span class=\"informations\">633×800 139 KB</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg></div></a></div></p>",

Кажется, я исправил проблему. Я заметил, что не могу запустить резервное копирование, и в итоге обнаружил, что в файле app.yml неправильно написано имя бакета для резервных копий. Имя бакета для загрузки было верным. Я исправил опечатку, и резервное копирование снова заработало. Только что проверил это ради интереса, и всё прошло успешно.

Сейчас запускаю ребейк постов.

Я сталкиваюсь с той же проблемой: всего 17 сообщений из 49595 приводят к прерыванию процесса ребейка.

49595 posts were flagged for a rebake
rake aborted!
FileStore::ToS3MigrationError: 17 posts are not remapped to new S3 upload URL. S3 migration failed for db 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:245:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:224:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:86:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:222:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:218:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_to_s3
(See full trace by running task with --trace)

Не совсем понимаю, на что мне следует обратить внимание в выводе команды Rails выше, @gerhard — не могли бы вы дать мне какие-нибудь подсказки?

Получаю ту же ошибку из-за 3 постов :confused:

Обновление URL в базе данных...
Предупреждение: для типа "name" с oid 19 не определено приведение типов. Пожалуйста, явно приведите этот тип к TEXT, чтобы быть уверенным в будущих изменениях.
Удаление старых оптимизированных изображений...
Помечены все посты, содержащие лайтбоксы, для повторной обработки...
123456 постов помечены для повторной обработки
rake aborted!
FileStore::ToS3MigrationError: 3 поста не переназначены на новый URL загрузки S3. Миграция S3 не удалась для базы данных 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:245:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:224:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:86:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:222:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:218:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Задачи: TOP => uploads:migrate_to_s3
(Полный трассировочный вывод можно получить, запустив задачу с флагом --trace)

@gerhard — если мы получаем такую ошибку, вы знаете, означает ли это «успех! — за исключением 3 постов» или «критический сбой миграции из-за 3 постов»?

Чтобы попытаться возобновить процесс, мне следует запустить rake posts:rebake, rake posts:rebake_uncooked_posts или снова rake uploads:migrate_to_s3?

Буду благодарен за любую помощь :slight_smile:

После выполнения этого я не вижу ничего общего между ними. Единственное, что бросается в глаза, — все они находятся внутри тегов <p>, если это имеет какое-то значение.

Странно то, что один из них содержит ссылку на эмодзи форума. Например:
https://www.example.com/images/emoji/twitter/slight_smile.png?v=9


При ручном запуске rake posts:rebake_uncooked_posts после ошибки миграции из моего предыдущего поста (не уверен, что rebake — это то, что мне нужно делать), появилась следующая ошибка:

Failed to report error: "\x8B" from ASCII-8BIT to UTF-8 3 Job exception: 403 Error:

Под ней было много нечитаемого текста. Процесс всё ещё выполняется.

@gerhard Есть ли у вас какие-либо идеи, как исправить проблему, когда все пользовательские аватары после миграции на S3 отображаются как стандартные?

Всё остальное на S3 отображается отлично: изображения постов, карточки пользователей, фоновые изображения пользователей. Отображаются только аватары. Похоже, что оригинальные аватары были перенесены — их видно в базе данных, и файлы существуют на S3, так что проблема, видимо, только с оптимизированными версиями. Я вижу, что у многих людей была такая проблема, но пока не смог найти решение. :sweat_smile:


Обновление/Редактирование:

В итоге решил рискнуть и завершить миграцию, даже если аватары не будут работать. Загрузка новых аватаров идёт на S3, но они тоже не отображаются :confused:

Надеюсь, это можно будет исправить позже.

В логах (/logs) я вижу записи вроде этой для URL аватаров:

Could not find file in the store located at url: //bucketname.s3.fr-par.scw.cloud/original/2X/d/123456.JPG

Однако файл действительно существует, если перейти по ссылке, и путь к файлу выглядит корректно. У меня есть ещё один экземпляр с теми же настройками (единственное отличие — имя бакета), и там аватары работают отлично. Формат пути на другом экземпляре точно такой же (проверял через загрузку в Rails).

Надеюсь, это поможет понять, что происходит.

Я выполнил ручную миграцию в S3 и получил тот же результат, но обнаружил папку tombstone в бакете S3. Это нормально, @gerhard?

Почему эти пути не были переназначены корректно:

> current_db = RailsMultisite::ConnectionManagement.current_db
=> "default"
> cdn_path = SiteSetting.cdn_path("/uploads/#{current_db}/original").sub(/https?:/, "")
=> "/uploads/default/original"
> Post.where("cooked LIKE '%#{cdn_path}%'").pluck(:cooked)
=> []

> Обновление URL в базе данных...
> Предупреждение: для типа "name" с oid 19 не определено приведение типов. Пожалуйста, явно приведите этот тип к TEXT, чтобы избежать проблем в будущем.
> Удаление старых оптимизированных изображений...
> Помечены все посты, содержащие лайтбоксы, для пересборки...
> 10855 постов помечены для пересборки
> rake aborted!
> FileStore::ToS3MigrationError: 1889 из 6492 загрузок не были перенесены в S3. Миграция в S3 для базы данных 'default' не удалась.
> /var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log'
> /var/www/discourse/lib/file_store/to_s3_migration.rb:78:in `migration_successful?'
> /var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3'
> /var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate'
> /var/www/discourse/lib/tasks/uploads.rake:123:in `migrate_to_s3'
> /var/www/discourse/lib/tasks/uploads.rake:102:in `block in migrate_to_s3_all_sites'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:86:in `each_connection'
> /var/www/discourse/lib/tasks/uploads.rake:100:in `migrate_to_s3_all_sites'
> /var/www/discourse/lib/tasks/uploads.rake:96:in `block in <main>'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:281:in `block in execute'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:281:in `each'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:281:in `execute'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:199:in `synchronize'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:199:in `invoke_with_call_chain'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/task.rb:188:in `invoke'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:160:in `invoke_task'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:116:in `block (2 levels) in top_level'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:116:in `each'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:116:in `block in top_level'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:125:in `run_with_threads'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:110:in `top_level'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:83:in `block in run'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:186:in `standard_exception_handling'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/lib/rake/application.rb:80:in `run'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/bin/rake:23:in `load'
> /var/www/discourse/vendor/bundle/ruby/2.7.0/bin/rake:23:in `<top (required)>'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `load'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `kernel_load'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:28:in `run'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:494:in `exec'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:30:in `dispatch'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:24:in `start'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:49:in `block in <top (required)>'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/friendly_errors.rb:130:in `with_friendly_errors'
> /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:37:in `<top (required)>'
> /usr/local/bin/bundle:23:in `load'
> /usr/local/bin/bundle:23:in `<main>'
> Задачи: TOP => uploads:migrate_to_s3

Редакция: Похоже, ваша ошибка отличалась от моей. Судя по всему, некоторые из ваших изображений не были перенесены в S3. Извините, я неправильно понял. Возможно, часть информации ниже всё ещё полезна. Вы настраивали загрузку в S3 по этому руководству? Configure an S3 compatible object storage provider for uploads

@evenif — Сожалею, что у вас возникли проблемы с этим. Я планировал написать руководство для тех, кто сталкивается с аналогичными проблемами, так как значительную часть информации пришлось собирать по разным темам. Но я жду, пока, надеюсь, будут исправлены аватары, так как, как вы видите выше, у меня всё ещё есть с ними проблемы.

Если вы выполните это в Rails, что вернётся: true или false?

SiteSetting.migrate_to_new_scheme

Если false, то можно попробовать установить значение true так:

SiteSetting.migrate_to_new_scheme = true

Затем либо подождать некоторое время и вернуться позже (по-моему, это выполняется каждые 15 минут, если не ошибаюсь), но если хотите запустить немедленно:

Jobs::MigrateUploadScheme.new.execute(nil)

Затем проверьте снова позже, является ли SiteSetting.migrate_to_new_scheme теперь false (это означает, что процесс должен был завершиться).

Затем выполните:
Upload.by_users.where("url NOT LIKE '//%' AND url NOT LIKE '/uploads/default/original/_X/%'").to_a

Это должно найти загрузки, у которых всё ещё есть проблемы и которые не удалось перенести. В моём случае все эти загрузки существовали как записи в базе данных, но сами изображения отсутствовали.

В зависимости от размера списка вы можете скопировать страницу, затем найти и заменить, чтобы создать список команд для удаления этих проблемных записей через список ID загрузок.

Upload.find(1).destroy
Upload.find(2).destroy
Upload.find(3).destroy

Заменяя 1, 2, 3 и т. д. на ID загрузок. Скопируйте и вставьте весь список в Rails и нажмите Enter. Это должно удалить эти проблемные записи.

Затем выйдите из Rails (введите exit), и всё, что вам нужно сделать, это запустить:

rake posts:rebake
или
rake posts:rebake_uncooked_posts

Uncooked позволяет возобновить процесс перекомпоновки, если он прервётся. Я рекомендую использовать обычный rebake, если у вас нет огромного количества загрузок.

Затем всё должно работать нормально, надеюсь. Но есть большая вероятность, что ваши оптимизированные аватары будут повреждены, как у меня, но оригиналы должны существовать в S3.

Вы можете проверить, успешно ли перенеслись аватары (по крайней мере, для некоторых пользователей), выполнив в Rails для пользователя, у которого отображается аватар по умолчанию:
User.find_by_username('username').uploaded_avatar

Также можно проверить наличие оптимизированных версий с помощью:
OptimizedImage.where(upload_id: upload_id).where(version: 2)

@markersocial Спасибо за помощь. Я думаю, что моя проблема возникла из-за того, что я ранее использовал сервис S3 (ещё с 2005 года), затем локальное хранилище, а потом снова вернулся к S3. Теперь при попытке загрузить локальные изображения в S3 возникло множество проблем. В моём бакете S3 отсутствует путь /uploads/default.

После выполнения uploads:migrate_to_s3 я обнаружил, что некоторые изображения по пути /images/transparent.png повреждены. Когда я использовал команду rake uploads:recover_from_tombstone:

Получил следующее сообщение:

Warning /t/topic/6216/4 had an incorrect 338c64ada8cbb0fb99bff79e833a4cc492ead00c should be c95e4b7c08702db4593332f29b40ca07fb1d9db1 storing in custom field ‘rake uploads:fix_relative_upload_links’ can fix this

Затем выполнение Rake было прервано, и появилось сообщение:

rake uploads:fix_relative_upload_links --trace
** Invoke uploads:fix_relative_upload_links (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute uploads:fix_relative_upload_links
Upload not found /uploads/files/general/111/cours-offerts.pdf in Post 23033 - /t/certificate-technique-de-soudage-college-mathieu/11060/1

Теперь я в замешательстве.

Ах :confused: Эта проблема выходит за рамки моего понимания. Надеюсь, вы сможете найти способ её исправить, или кто-то более сведущий подключится к обсуждению.

Что касается отсутствия /uploads/default в вашем бакете, я считаю, что это нормально и не должно быть причиной проблемы. То же самое наблюдается в моих бакетах (как на тех инстансах, которые были перенесены на S3, так и на тех, что использовали S3 с самого начала). Посмотрите на путь к вашему встроенному изображению в этой теме — там тоже нет /uploads/default.

Я тоже страдаю от той же самой проблемы.

Не случилось ли у вас найти хоть какой-то способ!!!???

Если нет, я прошу вас: если вы вдруг найдете какой-то способ, пожалуйста, поделитесь им со мной. Буду крайне признателен.

Я столкнулся с похожей проблемой, возможно, из-за миграции с AWS S3 → локальное хранилище → DO Spaces. В итоге я написал код на Ruby, чтобы вручную заменить старые нерабочие ссылки на загрузку на актуальный обновлённый формат ссылок, и, похоже, это решило мою проблему.

В моём случае все файлы были успешно перенесены в DO Spaces при первой миграции, но migrate_to_s3 зафиксировал их как неудачные. Сначала это не ломало вложения, но после запуска ребейка они перестали работать. Подробнее в связанной теме.

У меня тоже возникает эта ошибка после импорта базы данных smf2, включения S3 и запуска rake --trace uploads:migrate_to_s3

Миграция загрузок в S3 для 'default'...
Загрузка файлов в S3...
 - Список локальных файлов
.. => 2244 файла
 - Список файлов S3
... => 2383 файла
 - Синхронизация файлов с S3
....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Обновление URL в базе данных...
Удаление старых оптимизированных изображений...
Пометка всех постов, содержащих лайтбоксы, для пересборки...
454 поста помечены для пересборки
rake aborted!
FileStore::ToS3MigrationError: 7165 из 9554 загрузок не мигрированы в S3. Миграция в S3 не удалась для базы данных 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:132:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:79:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:373:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:66:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:123:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:102:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-3.1.0/lib/rails_multisite/connection_management.rb:80:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rails_multisite-3.1.0/lib/rails_multisite/connection_management.rb:90:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:100:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:96:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:83:in `block in run'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/lib/rake/application.rb:80:in `run'
bin/rake:13:in `<top (required)>'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli.rb:477:in `exec'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli.rb:31:in `dispatch'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/cli.rb:25:in `start'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/exe/bundle:49:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/lib/bundler/friendly_errors.rb:128:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.26/exe/bundle:37:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Задачи: TOP => uploads:migrate_to_s3

markersocial, когда я выполняю Upload.by_users.where("url NOT LIKE '//%' AND url NOT LIKE '/uploads/default/original/_X/%'").to_a, выводом является []

Предполагаю, что это означает, что моя проблема отличается от вашей?

ipoopfool, думаю, у меня может быть та же проблема, что и у вас. Не могли бы вы поделиться своим кодом на Ruby, который решил эту проблему? :blue_heart:

Спасибо.

При запуске скрипта я получаю следующую ошибку:

NameError: undefined local variable or method `upload_regex' for main:Object
from /var/www/discourse/script/discourse-fix-old-broken-uploads.rb:30:in `update_post_upload_links'

Есть какие-нибудь предложения?

Извините за оживление мертвой темы. Я удалил ссылку, которую публиковал ранее, поэтому решил просто скопировать и вставить код сюда.

Записи, созданные до сентября 2020 года, имеют битые загрузки после миграции на объектные хранилища и повторной обработки. Похоже, что сами загрузки в порядке, но URL в исходном тексте были некорректно отформатированы, поэтому я исправляю их вручную.

# Примечание: обновление таким способом, похоже, не добавляет историю изменений к записям. Перед запуском сделайте резервную копию базы данных на всякий случай.

# https://rubular.com/
# Группы захвата: /uploads/..., имя файла sha1
upload_regex = /\((\/uploads\/[\/\w]+\/)([0-9a-f]+)\.\w+\)/


def to_short_name(sha1)
  # ТРЕБУЕТСЯ ЗАПУСК В КОНСОЛИ RAILS DISCOURSE
  Upload.base62_sha1(sha1)
end

# Проверка на корректность. Вы можете пройти по всем записям и подсчитать, сколько раз встречается /uploads/.
# Затем выполните поиск по регулярному выражению, чтобы убедиться, что количество совпадений совпадает.
def count_num_broken_upload_links(posts)
  num_string_match = 0
  num_regex_match = 0

  posts.each do |post|
    num_string_match += post.raw.count("(/uploads/") # ЭТО НЕРАБОТОСПОСОБНО. COUNT РАБОТАЕТ ТОЛЬКО ДЛЯ СИМВОЛОВ.
    num_regex_match += post.raw.scan(upload_regex).count
  end

  puts "Проверка: количество вхождений старых ссылок на загрузки"
  puts "Простые совпадения по строке: " + num_string_match
  puts "Совпадения по регулярному выражению: " + num_regex_match
end

def update_post_upload_links(post)
  matches = post.raw.scan(upload_regex)
  fixed_raw = matches.reduce(post.raw) do |accumulator, match|
    prefix = match[0]
    sha1 = match[1]
    # sub, а не gsub, чтобы последовательно заменять каждое вложение по одному
    accumulator.sub(prefix, "upload://").sub(sha1, to_short_name(sha1))
  end

  if post.raw != fixed_raw
    # Обновление post.raw, похоже, также запускает повторную обработку. Но я всё равно планирую выполнить полную повторную обработку позже для надёжности.
    post.update(raw: fixed_raw)
  end

  puts "Обновлена запись с id #{post.id}"
end

# Проблема, которую я исправляю, возникает вплоть до конца 2020-09-05, но я добавлю несколько лишних дней для надёжности.
posts = Post.where("created_at < ?", Date.new(2020,9,7))

posts.each { |post| update_post_upload_links(post) }

И ещё один пользователь прокомментировал:

В моём случае переменная upload_regex должна быть глобальной, а не локальной. Поэтому upload_regex нужно изменить на $upload_regex."}