升级到 3.0.2:NameError:未定义方法 `call' 用于类 `Redis::Client'(附带“修复”)

刚尝试从 3.0.1 升级到 3.0.2,在 rake db:migrate 阶段遇到了这个错误:

rake aborted!
NameError: undefined method `call' for class `Redis::Client'
Did you mean?  caller
/var/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/mini_profiler/profiling_methods.rb:83:in `alias_method'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/mini_profiler/profiling_methods.rb:83:in `profile_method'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/rack-mini-profiler-3.0.0/lib/mini_profiler/profiling_methods.rb:65:in `counter_method'
/var/discourse/config/initializers/006-mini_profiler.rb:90:in `<main>'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `load'

长话短说,我发现将 redis 固定在 4.8.0 版本而不是在 Gemfile 中不指定 redis 版本可以解决问题。即,对于 Gemfile:

-gem "redis"
+gem "redis", "4.8.0"

我对修改这个感到不太舒服,但对我来说,这似乎是由于我的上一次升级(到 3.0.1)以来,redis 在其他地方被升级而产生的意外副作用,并且重新安装 Discourse 3.0.1 现在也会出现同样的问题。

希望这对某人有帮助,如果这会让我的系统处于易受攻击的状态,请告诉我 :slight_smile:

1 个赞

我们在 Gemfile.lock 文件中设置了 gem 版本,并且它已经设置为相同的版本

当然!奇怪的是,我以前从未听说过 Gemfile 或 Gemfile.lock。但是,还有 20 个论坛需要重复安装(叹气),结果发现整个事情始于安装过程中的另一个问题,当时的抱怨建议尝试删除 Gemfile.lock:

Bundler 发现了 Ruby 版本之间存在冲突的要求:
  在 Gemfile 中:
    actionmailer (= 7.0.4.3) 被解析为 7.0.4.3,它依赖于
      Ruby (>= 2.7.0)

    sassc-rails 被解析为 2.1.2,它依赖于
      sprockets-rails 被解析为 3.4.2,它依赖于
        Ruby (>= 2.5)

    json 被解析为 2.6.3,它依赖于
      Ruby (>= 2.3)

    :
    :
    :
    json_schemer 被解析为 0.2.23,它依赖于
      ecma-re-validator (~> 0.3) 被解析为 0.4.0,它依赖于
        Ruby (>= 2.6, < 4.0)

    rspec 被解析为 3.12.0,它依赖于
      rspec-expectations (~> 3.12.0) 被解析为 3.12.2,它依赖于
        diff-lcs (>= 1.2.0, < 2.0) 被解析为 1.5.0,它依赖于
          Ruby (>= 1.8)

    web-push 被解析为 3.0.0,它依赖于
      Ruby (>= 3.0)

  当前的 Ruby 版本:
    Ruby (= 2.7.6)

Bundler 无法为 gem "hkdf" 找到兼容的版本:
  在快照 (Gemfile.lock) 中:
    hkdf (= 1.0.0)

  在 Gemfile 中:
    web-push 被解析为 1.0.0,它依赖于
      hkdf (~> 0.2)

删除你的 Gemfile.lock 文件并运行 `bundle install` 将会从头开始重建你的快照,只使用 Gemfile 中的 gem,这可能会解决冲突。

因此,在删除 lock 文件后,我解决了最初的错误,然后遇到了 NameError: undefined method ‘call’ 的问题,如前所述。通过固定 redis 版本解决了这个问题。然后,一切都正常了。

所以,我的脚本被修改为 a) 删除 Gemfile.lock(因为上面引用的错误)和 b) 自动更改 Gemfile 以将 redis 固定在 4.8.0。一切顺利……我以为。这在 20 台“相同”的机器中有三台成功了!其余的出现了这个新错误:

[discourse@in3020-discourse discourse]$ cd $INSTA; RAILS_ENV=production /usr/local/bin/bundle exec rake db:migrate # 将大量内容填充到数据库中
rake aborted!
NoMethodError: undefined method `logger=' for Sidekiq:Module
Did you mean?  logger
/var/discourse/config/initializers/100-sidekiq.rb:58:in `<main>'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `load'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `block in load_config_initializer'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.4.3/lib/active_support/notifications.rb:208:in `instrument'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:666:in `load_config_initializer'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:620:in `block (2 levels) in <class:Engine>'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `each'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `block in <class:Engine>'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `instance_exec'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `run'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:61:in `block in run_initializers'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `each'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `tsort_each_child'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:60:in `run_initializers'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/application.rb:372:in `initialize!'
/var/discourse/config/environment.rb:7:in `<main>'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.6.7/lib/zeitwerk/kernel.rb:38:in `require'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/application.rb:348:in `require_environment!'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/railties-7.0.4.3/lib/rails/application.rb:511:in `block in run_tasks_blocks'
/var/discourse/vendor/bundle/ruby/2.7.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli.rb:486:in `exec'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli.rb:31:in `dispatch'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/cli.rb:25:in `start'
/usr/local/share/gems/gems/bundler-2.3.26/exe/bundle:48:in `block in <top (required)>'
/usr/local/share/gems/gems/bundler-2.3.26/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
/usr/local/share/gems/gems/bundler-2.3.26/exe/bundle:36:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment
(通过运行带有 --trace 的任务查看完整跟踪)

这真的很奇怪,因为在所有机器上,/var/discourse/config/initializers/100-sidekiq.rb 文件都是相同的,并且肯定不包含 logger=,而是包含 logger = ... 语句。

我最终发现,在那些工作的机器上,/usr/local/bin/bundle 的版本是 2.3.20,而不是在失败的机器上的 2.3.26。所以总而言之,在 discourse 的安装命令之前添加这个可以解决我的问题(在 discourse 的 bundler 安装之后进行 bundler 固定到 2.3.20 命令是不够的,它必须在此之前):

rm Gemfile.lock
perl -pi.bak -e 's/gem \"redis\"/gem \"redis\",\"4.8.0\"/;' Gemfile

/usr/bin/gem uninstall bundler -v 2.3.26
/usr/bin/gem install bundler -v 2.3.20
RAILS_ENV=production /usr/local/bin/bundle install
RAILS_ENV=production /usr/local/bin/bundle exec rake db:migrate
RAILS_ENV=production /usr/local/bin/bundle exec rake assets:precompile

为什么那些机器上会有 bundler 2.3.26 而其他机器上有 2.3.20,我完全不知道……但这可能不是你的错 :laughing:

这就是为什么我使用稳定版 :laughing:

Ruby 2.7 已到达生命周期终点,我们不再支持。按照标准的安装指南安装 Discourse 时,一段时间以来都不会安装该版本,因此我假设这是一个自定义安装?

我建议即使是熟悉 Discourse 技术栈的人也应坚持使用官方支持的安装指南,对于不熟悉所用技术的人来说,这一点更为重要。

是的,走官方路线几乎肯定会让我少操心(很可能一点都不操心)。问题是我不允许使用未经我们 IT 安全部门预先批准的 Docker 镜像——而你们的就没有。

所以这确实是在 RHEL8 机器上进行的自定义、原生安装,还需要一些 SELinux 的技巧才能工作。

也许有其他人也遇到同样的问题——如果我发布一个关于我的安装过程的主题,对他们来说可能会有用?请随意提出异议——我明白这可能会被视为一种“鼓励”,即使并非绝对必要也以这种方式安装,这可能会给你带来更多问题。

另外,在谷歌搜索 SELinux 问题的解决方案时,你会发现最常见的建议是“就这样禁用它” :laughing:。但这在这里是不可行的。

感谢你的帮助!

感谢您提供背景信息。请注意,我们不在此处为自定义安装提供免费支持。

此安装已在使用一个与当前任何 Discourse 版本都不兼容的 Ruby 版本,不遵循任何精心管理的 gem 版本,并且不使用我们提供的所有手动管理的操作系统级别共享库。因此,出现故障不是“是否”的问题,而是“何时”的问题。

3 个赞

您可以向您的安全团队建议,一个经过开发人员审查和使用的镜像要安全得多,比您试图为那些除非是您唯一的工作否则您不可能跟踪到的东西打安全补丁要安全得多。

. . . . 但这可能没什么帮助。

哈哈,是的(可能用你的图片更安全),而且不是(没用——但还是谢谢你的评论😊)。

这确实不是我的本职工作,我只是“因为我能做到”而运行这些论坛,作为一个试点项目,以便我们能说服IT部门接手并为整个奥斯陆大学运行。

幸运的是,这似乎奏效了,所以希望这是我必须负责的最后一个学期。我敢打赌IT部门会使用这些图片……:wink:

另外,感谢@Falco指出Ruby版本不匹配的问题,如果/当我将来更新遇到问题时,我会看看的。

1 个赞

天哪!我曾在几所美国大学担任过教职,对此我印象深刻。

1 个赞

哎呀,好久没按回复按钮了……

@pfaffman 哈哈,是的。我们还没有完全脱离困境,即使 IT 同意了:它首先必须得到最高层(大学委员会)的批准,才能成为官方的沟通渠道。幸运的是,我们得到了自然科学系的全力支持,他们一直在推动这件事。

我为能够运行这些试点实例感到非常自豪——(在必要的安全策略范围内)没有多少非 IT 部门的人能够做到这一点。自然科学系的人一直称之为“Astro-Discourse”(我在理论天体物理研究所)::laughing:

但现在……我似乎不得不以同样的非标准设置再运行这个节目一个学期。我想知道,当前的 Discourse 版本与哪个 pgsql 版本(或多个版本)兼容?