発生事象
bundle updateしたらPassengerエラー発生。Redmineが起動できなくなった。
apacheのエラーログを見ると以下のようにloofahのエラー「uninitialized constant Nokogiri::HTML4 (NameError)」が出ている
App 1686 output: Error: The application encountered the following error: uninitialized constant Nokogiri::HTML4 (NameError)
App 1686 output: /var/lib/redmine/vendor/bundle/ruby/2.6.0/gems/loofah-2.21.1/lib/loofah/html4/document.rb:10:in `<module:HTML4>'
App 1686 output: /var/lib/redmine/vendor/bundle/ruby/2.6.0/gems/loofah-2.21.1/lib/loofah/html4/document.rb:4:in `<module:Loofah>'
App 1686 output: /var/lib/redmine/vendor/bundle/ruby/2.6.0/gems/loofah-2.21.1/lib/loofah/html4/document.rb:3:in `<top (required)>'
発生環境
Redmineは4.1.7、Rubyのバージョンは2.6.10。
Environment:
Redmine version 4.1.7.stable.21507
Ruby version 2.6.10-p210 (2022-04-12) [x86_64-linux]
Rails version 5.2.6.3
Environment production
Database adapter PostgreSQL
Mailer queue ActiveJob::QueueAdapters::AsyncAdapter
Mailer delivery smtp
SCM:
Subversion 1.7.14
Git 1.8.3.1
Filesystem
Redmine plugins:
openpgp 1.0.1
redmine_theme_changer 0.4.0
redmine_wiki_extensions 0.9.3
view_customize 2.7.0
発生原因
以下のように、loofah-2.20.0まででは、Nokogiri::HTML::Documentのサブクラスを使用しているようなのですが、loofah-2.21.0ではNokogiri::HTML4::Documentにクラスの名前が変わっているようです。
# frozen_string_literal: true
module Loofah
module HTML # :nodoc:
#
# Subclass of Nokogiri::HTML::Document.
#
# See Loofah::ScrubBehavior and Loofah::TextBehavior for additional methods.
#
class Document < Nokogiri::HTML::Document
include Loofah::ScrubBehavior::Node
include Loofah::DocumentDecorator
include Loofah::TextBehavior
def serialize_root
at_xpath("/html/body")
end
end
end
end
# frozen_string_literal: true
module Loofah
module HTML4 # :nodoc:
#
# Subclass of Nokogiri::HTML4::Document.
#
# See Loofah::ScrubBehavior and Loofah::TextBehavior for additional methods.
#
class Document < Nokogiri::HTML4::Document
include Loofah::ScrubBehavior::Node
include Loofah::DocumentDecorator
include Loofah::TextBehavior
include Loofah::HtmlDocumentBehavior
end
end
end
RedmineのGemfileでは、
gem 'nokogiri', (RUBY_VERSION < '2.5' ? '~> 1.10.0' : '~> 1.11.1')
となっており、Rubyのバージョンが2.6であれば1.11.1以上のnokogiriを使う、という記述になっています。
一方で、nokogiriのドキュメントで、以下のように1.12.0にて変更されたことが書かれていました 1
v1.12.0より前は、Nokogiri Nokogiri::HTML4 は存在せず、 Nokogiri Nokogiri::HTML HTML を解析するためのモジュール/名前空間でした。
loofahについてはGemfileに記述はありませんが、Gemfile.lockをみるとcrassとnokogiriの依存関係から現在使える最新のloofahがインストールされたようです。
loofah (2.21.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
対処
案1 Gemfile.localを作成してloofahのバージョンを2.20.0以下にする
gem 'loofah', '<= 2.20.0'
案2 Gemfileのnokogiriのバージョンを1.12.0に修正
#gem 'nokogiri', (RUBY_VERSION < '2.5' ? '~> 1.10.0' : '~> 1.11.1')
gem 'nokogiri', (RUBY_VERSION < '2.5' ? '~> 1.10.0' : '~> 1.12.0')
言うまでもないかもしれませんが、どちらの対処の場合もbundle update
した後にapacheを再起動する必要があります
私はRubyの専門家ではないので、本当にこの修正でいいかはわかりませんが、どちらの方法でもRedmineが起動できなくなる事象は解決できました。Redmineのオリジナルファイルに修正を加えたくない場合は案1かなとおもいます。
将来的にRedmineのソースファイルにてこのnokogiriとloofahの制約を織り込んで修正されることを期待したいとおもいます。
追跡調査を行い続編記事を書きました。
対策についても、以下の通りGemfile.localを作成する、と訂正いたします。
gem 'loofah', '~> 2.20.0'