Atualização para 3.0.2: NameError: método não definido `call' para classe `Redis::Client' (com um "fix")

Acabei de tentar atualizar de 3.0.1 para 3.0.2 e recebi este erro durante o estágio 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'

Resumindo muito, descobri que fixar o redis na versão 4.8.0 em vez de deixar a versão do redis não especificada no Gemfile resolveu o problema. Ou seja, para o Gemfile:

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

Não me sinto muito confortável mexendo nisso, mas parece-me que este é um efeito colateral não intencional da atualização do redis em outro lugar desde a minha última atualização (para 3.0.1), e que uma reinstalação do Discourse 3.0.1 agora mostraria o mesmo problema.

Espero que isso ajude alguém, e por favor me avise se isso deixa meu sistema em um estado vulnerável :slight_smile:

1 curtida

Definimos as versões do gem no arquivo Gemfile.lock, e ele já está definido para essa mesma versão

Com certeza! Estranho, pois eu nunca tinha ouvido falar de Gemfile ou Gemfile.lock antes. Mas tendo 20 outros fóruns para repetir a instalação (suspiro), acontece que tudo começou com um problema diferente durante a instalação, onde as reclamações terminaram com uma recomendação para tentar excluir o Gemfile.lock:

Bundler encontrou requisitos conflitantes para a versão Ruby:
  No Gemfile:
    actionmailer (= 7.0.4.3) foi resolvido para 7.0.4.3, que depende de
      Ruby (>= 2.7.0)

    sassc-rails foi resolvido para 2.1.2, que depende de
      sprockets-rails foi resolvido para 3.4.2, que depende de
        Ruby (>= 2.5)

    json foi resolvido para 2.6.3, que depende de
      Ruby (>= 2.3)

    json_schemer foi resolvido para 0.2.23, que depende de
      ecma-re-validator (~> 0.3) foi resolvido para 0.4.0, que depende de
        Ruby (>= 2.6, < 4.0)

    rspec foi resolvido para 3.12.0, que depende de
      rspec-expectations (~> 3.12.0) foi resolvido para 3.12.2, que depende de
        diff-lcs (>= 1.2.0, < 2.0) foi resolvido para 1.5.0, que depende de
          Ruby (>= 1.8)

    web-push foi resolvido para 3.0.0, que depende de
      Ruby (>= 3.0)

  Versão Ruby atual:
    Ruby (= 2.7.6)

Bundler não conseguiu encontrar versões compatíveis para o gem "hkdf":
  No snapshot (Gemfile.lock):
    hkdf (= 1.0.0)

  No Gemfile:
    web-push foi resolvido para 1.0.0, que depende de
      hkdf (~> 0.2)

Excluir seu arquivo Gemfile.lock e executar `bundle install` reconstruirá seu
snapshot do zero, usando apenas
os gems em seu Gemfile, o que pode resolver o conflito.

Então, eu passei por esse erro inicial depois de remover o arquivo de lock conforme sugerido, e então encontrei o NameError: undefined method ‘call’ descrito anteriormente. Corrigi isso fixando a versão do redis. Então, tudo funcionou.

Portanto, meu script foi modificado para a) remover Gemfile.lock (devido ao erro citado acima) e b) alterar automaticamente o Gemfile para fixar o redis em 4.8.0. Tudo perfeito… pensei. Isso funcionou em três das 20 máquinas “idênticas”! As outras apresentaram este novo erro:

[discourse@in3020-discourse discourse]$ cd $INSTA; RAILS_ENV=production /usr/local/bin/bundle exec rake db:migrate # colocando um monte de coisas no banco de dados
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
(See full trace by running task with --trace)

O que foi realmente, realmente estranho porque os arquivos /var/discourse/config/initializers/100-sidekiq.rb eram idênticos em todas as máquinas e certamente não continham ‘logger=’, mas uma declaração ‘logger = …’.

Finalmente descobri que nas máquinas onde funcionou, /usr/local/bin/bundle era a versão 2.3.20, não 2.3.26 como nas máquinas onde falhou. Então, em resumo, adicionar isso antes do comando de instalação para discourse fez o truque para mim (não foi suficiente fazer o pegging do bundler em 2.3.20 comandos após a instalação do bundler do discourse, teve que ser antes):

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

Por que diabos algumas daquelas máquinas tinham bundler 2.3.26 e outras tinham 2.3.20 eu não faço ideia… mas provavelmente não é culpa sua :laughing:.

E é por isso que eu uso a versão estável :laughing:

O Ruby 2.7 está no fim de vida (EOL) e não é mais suportado por nós. Você não obtém essa versão ao instalar o Discourse seguindo o guia de instalação padrão há algum tempo, então presumo que esta seja uma instalação personalizada?

Recomendo seguir o guia de instalação oficial suportado, mesmo para pessoas familiarizadas com a stack do Discourse, e isso é ainda mais importante para pessoas que não estão familiarizadas com as tecnologias utilizadas.

Sim, fazer isso da maneira oficial certamente me daria menos dores de cabeça (muito provavelmente nenhuma). O problema é que não tenho permissão para usar imagens do Docker que não sejam pré-aprovadas pelo nosso departamento de segurança de TI - e a sua não é.

Portanto, esta é realmente uma instalação nativa personalizada em máquinas RHEL8, que também precisou de alguns truques de SELinux para funcionar.

Talvez existam outros com o mesmo problema - talvez seja útil para eles se eu postar um tópico com o meu procedimento de instalação? Sinta-se à vontade para protestar - posso ver que isso pode ser interpretado como um “incentivo” para instalá-lo dessa forma, mesmo que não seja estritamente necessário, o que pode levar a mais perguntas para você.

Como observação, ao pesquisar soluções para qualquer problema de SELinux, o conselho mais frequente que você encontrará é “é assim que você o desabilita”: risos. Mas esta não é uma opção aqui.

Obrigado pela sua ajuda!

Obrigado pelo contexto. Apenas esteja ciente de que não oferecemos suporte gratuito para instalações personalizadas aqui.

Esta instalação já está usando uma versão do Ruby que não funciona com nenhuma das versões atuais do Discourse, não respeita nenhuma das versões de gem cuidadosamente gerenciadas e não usa todas as bibliotecas compartilhadas gerenciadas manualmente em nível de sistema operacional que enviamos. Portanto, a quebra não é uma questão de se, mas sim de quando.

3 curtidas

Você pode sugerir à sua equipe de segurança que uma imagem que é verificada e usada pelos desenvolvedores é muito, muito mais segura do que você tentar aplicar patches de segurança a coisas que você não pode rastrear, a menos que seja seu único trabalho.

. . . . Mas, isso provavelmente não é útil.

Haha, sim (provavelmente mais seguro com suas imagens) e não (não é útil - mas obrigado pelo comentário de qualquer forma😊).

De fato, este não é meu trabalho principal, estou apenas administrando estes fóruns “porque sou quem poderia fazê-lo” como um programa piloto para que possamos convencer nosso departamento de TI a adotá-lo e executá-lo para toda a Universidade de Oslo.

Felizmente, isso parece ter funcionado, então espero que este seja o último semestre em que terei que administrar tudo. Aposto que o departamento de TI usará as imagens… :wink:

E obrigado, @Falco, por apontar que há uma incompatibilidade de versão do Ruby, darei uma olhada nisso se/quando eu encontrar problemas com futuras atualizações.

1 curtida

Nossa! Tendo sido professor em várias universidades nos EUA, estou bastante impressionado.

1 curtida

Oops, esqueci de pressionar o botão Responder há muito tempo…

@pfaffman Haha, sim. Ainda não estamos 100% fora de perigo, mesmo que o TI diga ok: primeiro precisa ser aprovado no mais alto escalão (pelo conselho universitário) como um canal oficial de comunicação. Felizmente, conseguimos o Departamento de Ciências Naturais a bordo em grande estilo, e eles têm feito isso passar por todos os obstáculos.

Tenho bastante orgulho de ter conseguido executar essas instâncias piloto - não muitas pessoas fora do departamento de TI teriam conseguido fazer isso (dentro das políticas de segurança necessárias, é claro). As pessoas das Ciências Naturais consistentemente se referem a isso como “Astro-Discourse” (estou no Instituto de Astrofísica Teórica) :laughing:.

Mas agora… parece que tenho que conduzir este semestre mais um, com a mesma configuração não padrão. Gostaria de saber, com qual(is) versão(ões) do pgsql a versão atual do Discourse é compatível?