Backup multisite usando usuário do discourse em vez de DB_USER ou valor de multisite.yml

EDIT/Tl;dr: ActiveRecord::Base.connection_pool.db_config.configuration_hash tem o nome de usuário em user, não em username, mas o Discourse está procurando em username.
PR trivial: FIX: backup_restore.rb wants db user from user, not username by pfaffman · Pull Request #28229 · discourse/discourse · GitHub

Tenho uma instância multisite usando o postgres hospedado da Digital Ocean. Está funcionando bem, mas quando tento fazer backup, recebo um erro que

[2024-08-05 16:13:31] pg_dump: error: connection to server at "private-forum-cluster-postgresql-prod-do-user-1230.j.db.ondigitalocean.com" (10.11.1.6), port 25060 failed: FATAL:  password authentication failed for user "discourse"

Mas o usuário não é discourse. Ele está usando o usuário correto em outros lugares, incluindo ActiveRecord::Base.connection_pool.db_config.configuration_hash e BackupRestore.database_configuration (quando executo esses comandos em RAILS_DB=sitename rails c). PG_USER não está definido no ambiente (pelo que posso ver).

Parece que isso é o culpado:

Eu o editei no contêiner (para puxá-lo de DISCOURSE_DB_USER, o que parecia uma boa ideia na época) e o backup funciona agora. Não sei se você deveria ser capaz de extrair informações de conexão de multisite.yml ou não, mas ignorar DB_USER parece errado.

Ou talvez eu devesse apenas fazer o usuário ser discourse como acho que todo mundo deve estar fazendo?

EDIT: Espere. Não.

config['username'] deveria ser config['user']

    config = ActiveRecord::Base.connection_pool.db_config.configuration_hash

retorna isso!

   
=> {:adapter=>"postgresql",
 :database=>"theDatabase",
 :pool=>25,
 :port=>25060,
 :timeout=>5000,
 :host=>"private-forum-cluster-postgresql-prod-do-user-123-0.j.db.ondigitalocean.com",
 :user=>"theCurrentUsername",
 :password=>"supersecret",
 :host_names=>["forum.example.com"],
 :db_key=>"mydb",
 :prepared_statements=>false}

Então

    config["username"] || username || ENV["USER"] || "postgres",

deveria ser

    config["user"] || username || ENV["USER"] || "postgres",
2 curtidas

@pfaffman Receio que tivemos que reverter isso, porque quebrou a restauração de backups em nossos ambientes de produção.

Nossa configuração de multisite de exemplo (e, de fato, a configuração de produção) a tem em ‘username’:

2 curtidas

Desculpe! Ainda estou confuso sobre como funciona para tudo, exceto para backup.

Hmm.

Talvez esse seja o meu problema. Mas como está funcionando para todo o resto?

Talvez todo o resto use a configuração global de uma variável de ambiente.

2 curtidas

Sinto muito.

Não me ocorreu que ActiveRecord::Base.connection_pool.db_config.configuration_hash era apenas o que quer que eu tivesse colocado no arquivo multisite.yml.

Renomeei todos os meus campos user: incorretos como username: e agora meu backup funciona.

Minha explicação (que não testei) é que o restante do Rails substitui o db_username do GlobalSettings se um for definido lá, mas quando ele vai buscar essas informações para fazer a chamada externa para pg_dump, ele as puxa da configuração do multisite.

Ainda acho que é um bug que o backup obtenha um usuário diferente e que a correção seria incluir a busca por env['DISCOURSE_DB_USERNAME'] em algum lugar nessa instrução de atribuição, mas não estou disposto a arriscar quebrar a produção novamente, e agora está funcionando.

Você deveria descurtir minha postagem e remover meu distintivo! :crying_cat_face:

2 curtidas

Sem problemas, essas coisas acontecem. Idealmente, isso teria sido pego no CI, mas acho que não temos cobertura dessa lógica (talvez difícil, já que a configuração do banco de dados é toda diferente nos testes de qualquer maneira).

Obrigado por documentar o que você encontrou - tenho certeza de que ajudará outras pessoas no futuro. Concordo que a inconsistência aqui é ruim e seria bom corrigir em algum momento.

3 curtidas