Actualización a 3.0.2: NameError: método no definido `call' para la clase `Redis::Client' (con una "solución")

Acabo de intentar actualizar de la versión 3.0.1 a la 3.0.2 y obtuve este error durante la etapa de 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'

En resumen, descubrí que fijar la versión de redis en 4.8.0 en lugar de dejarla sin especificar en el Gemfile solucionó el problema. Es decir, para el Gemfile:

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

No me siento muy cómodo manipulando esto, pero me parece que es un efecto secundario no intencionado de que redis se haya actualizado en otro lugar desde mi última actualización (a la 3.0.1), y que una reinstalación de Discourse 3.0.1 mostraría ahora el mismo problema.

Espero que esto ayude a alguien, y por favor, háganme saber si esto deja mi sistema en un estado vulnerable :slight_smile:

1 me gusta

Establecemos las versiones de las gemas en el archivo Gemfile.lock, y ya está configurada en esa misma versión

¡Ciertamente! Extraño, ya que nunca antes había oído hablar de Gemfile ni de Gemfile.lock. Pero teniendo 20 foros más para repetir la instalación (suspiro), resulta que todo comenzó con un problema diferente durante la instalación, donde las quejas terminaron con una recomendación de intentar eliminar Gemfile.lock:

Bundler encontró requisitos conflictivos para la versión de Ruby:
  En Gemfile:
    actionmailer (= 7.0.4.3) se resolvió a 7.0.4.3, que depende de
      Ruby (>= 2.7.0)

    sassc-rails se resolvió a 2.1.2, que depende de
      sprockets-rails se resolvió a 3.4.2, que depende de
        Ruby (>= 2.5)

    json se resolvió a 2.6.3, que depende de
      Ruby (>= 2.3)

    json_schemer se resolvió a 0.2.23, que depende de
      ecma-re-validator (~> 0.3) se resolvió a 0.4.0, que depende de
        Ruby (>= 2.6, < 4.0)

    rspec se resolvió a 3.12.0, que depende de
      rspec-expectations (~> 3.12.0) se resolvió a 3.12.2, que depende de
        diff-lcs (>= 1.2.0, < 2.0) se resolvió a 1.5.0, que depende de
          Ruby (>= 1.8)

    web-push se resolvió a 3.0.0, que depende de
      Ruby (>= 3.0)

  Versión actual de Ruby:
    Ruby (= 2.7.6)

Bundler no pudo encontrar versiones compatibles para el gem "hkdf":
  En snapshot (Gemfile.lock):
    hkdf (= 1.0.0)

  En Gemfile:
    web-push se resolvió a 1.0.0, que depende de
      hkdf (~> 0.2)

Eliminar tu archivo Gemfile.lock y ejecutar `bundle install` reconstruirá tu
snapshot desde cero, usando solo
los gems en tu Gemfile, lo que puede resolver el conflicto.

Así que, superé ese error inicial después de eliminar el archivo de bloqueo según lo sugerido, y luego me encontré con el NameError: undefined method ‘call’ descrito anteriormente. Lo solucioné fijando la versión de redis. Luego, todo funcionó.

Por lo tanto, mi script se modificó para a) eliminar Gemfile.lock (debido al error citado anteriormente) y b) cambiar automáticamente Gemfile para fijar redis en 4.8.0. Todo bien… pensé. ¡Esto funcionó en tres de las 20 máquinas “idénticas”! Las demás presentaron este nuevo error:

[discourse@in3020-discourse discourse]$ cd $INSTA; RAILS_ENV=production /usr/local/bin/bundle exec rake db:migrate # cargando muchas cosas en la base de datos
rake abortado!
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)

Lo cual fue realmente, realmente extraño porque los archivos /var/discourse/config/initializers/100-sidekiq.rb eran idénticos en todas las máquinas, y ciertamente no contenían ‘logger=’, sino una declaración ‘logger = …’.

Finalmente descubrí que en las máquinas donde funcionó, /usr/local/bin/bundle era la versión 2.3.20, no la 2.3.26 como en las máquinas donde falló. Así que, en resumen, agregar esto antes del comando de instalación para discourse hizo el truco para mí (no fue suficiente hacer el anclaje de bundler en los comandos 2.3.20 después de la instalación de bundler de discourse, tuvo 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 qué demonios algunas de esas máquinas tenían bundler 2.3.26 y otras tenían 2.3.20, no tengo ni idea… pero probablemente no sea tu culpa :laughing:.

Y por eso uso la versión estable :laughing:

Ruby 2.7 está al final de su vida útil (EOL) y ya no lo admitimos. No obtienes esa versión al instalar Discourse siguiendo la guía de instalación estándar desde hace un tiempo, ¿así que supongo que esta es una instalación personalizada?

Recomiendo ceñirse a la guía de instalación oficial compatible, incluso para personas familiarizadas con la pila de Discourse, y eso es aún más importante para las personas que no están familiarizadas con las tecnologías utilizadas.

Sí, hacerlo de la manera oficial casi con toda seguridad me habría dado menos dolores de cabeza (lo más probable es que ninguno). El problema es que no tengo permitido usar imágenes de Docker que no estén pre-aprobadas por nuestro departamento de seguridad de TI, y la tuya no lo está.

Así que, en efecto, esta es una instalación nativa personalizada en máquinas RHEL8, que también requirió algunos trucos de SELinux para funcionar.

Quizás haya otros con el mismo problema; ¿sería útil para ellos si publico un tema con mi procedimiento de instalación? Siéntete libre de protestar; puedo ver que esto podría tomarse como un “aliento” para instalarlo de esta manera incluso si no es estrictamente necesario, lo que podría generar más preguntas para ti.

Aparte, al buscar soluciones a cualquier problema de SELinux en Google, el consejo más frecuente que encontrarás es “así es como se deshabilita”: risa. Pero esa no es una opción aquí.

¡Gracias por tu ayuda!

Gracias por el contexto. Solo tenga en cuenta que no ofrecemos soporte gratuito para instalaciones personalizadas aquí.

Esta instalación ya está utilizando una versión de Ruby que no funciona con ninguna de las versiones actuales de Discourse, no respeta ninguna de las versiones de gem cuidadosamente administradas y no utiliza todas las bibliotecas compartidas a nivel del sistema operativo administradas manualmente que enviamos. Por lo tanto, la interrupción no es una cuestión de si ocurrirá, sino de cuándo.

3 Me gusta

Podrías sugerir a tu equipo de seguridad que una imagen que sea revisada y utilizada por los desarrolladores es mucho, mucho más segura que intentar aplicar parches de seguridad a cosas que es imposible seguirles la pista a menos que sea tu único trabajo.

. . . . Pero, eso probablemente no sea útil.

Jaja, sí (probablemente más seguro con tus imágenes) y no (no es útil, pero gracias por el comentario de todos modos😊).

De hecho, este no es mi trabajo principal, solo estoy dirigiendo estos foros “porque soy el que pudo hacerlo” como un programa piloto para que podamos convencer a nuestro departamento de TI de que lo adopte y lo ejecute para toda la Universidad de Oslo.

Afortunadamente, eso parece haber funcionado, así que espero que este sea el último semestre que tenga que dirigir el espectáculo. Supongo que el departamento de TI usará las imágenes… :wink:

Y gracias, @Falco, por señalar que hay una discrepancia en la versión de Ruby, lo miraré si/cuando tenga problemas con futuras actualizaciones.

1 me gusta

¡Vaya! Habiendo sido profesor en varias universidades de los EE. UU., estoy bastante impresionado.

1 me gusta

Oops, olvidé presionar el botón de Responder hace mucho tiempo…

@pfaffman Jaja, sí. Aún no estamos 100% fuera de peligro, incluso si TI dice que está bien: primero tiene que ser aprobado en la cúpula (por la junta universitaria) como un canal de comunicación oficial. Afortunadamente, contamos con el gran apoyo del Departamento de Ciencias Naturales, y ellos han estado impulsando el proceso.

Estoy bastante orgulloso de haber podido ejecutar estas instancias piloto; no mucha gente ajena al departamento de TI habría podido hacerlo (dentro de las políticas de seguridad necesarias, claro). La gente de Ciencias Naturales se refiere consistentemente a él como “Astro-Discourse” (estoy en el Instituto de Astrofísica Teórica) :laughing:.

Pero ahora… parece que tengo que dirigir este espectáculo un semestre más, con la misma configuración no estándar. Me pregunto, ¿con qué versión(es) de pgsql es compatible la versión actual de Discourse?