Commit 9c33b79d authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Fix invalid DB checks

We should not use `ActiveRecord::Base.connected?` to
check if a DB exists because that only checks if a
connection is already established. It's possible
for the DB to exist but a connection has not yet
been established.

I noticed that this method in the initializer was
wrong but we didn't notice it because this method
was never invoked.

0_license.rb is run before any connections are
established so `connected?` always returned false
even if the table exists.

I've also fixed other places that use the same check
even though they might not be having problems because
a connection is already established at that point.
parent e06090d7
...@@ -10,7 +10,7 @@ Gitlab.ee do ...@@ -10,7 +10,7 @@ Gitlab.ee do
end end
# Needed to run migration # Needed to run migration
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('licenses') if Gitlab::Database.cached_table_exists?('licenses')
message = LicenseHelper.license_message(signed_in: true, is_admin: true, in_html: false) message = LicenseHelper.license_message(signed_in: true, is_admin: true, in_html: false)
if ::License.block_changes? && message.present? if ::License.block_changes? && message.present?
warn "WARNING: #{message}" warn "WARNING: #{message}"
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# We need to run this initializer after migrations are done so it doesn't fail on CI # We need to run this initializer after migrations are done so it doesn't fail on CI
Gitlab.ee do Gitlab.ee do
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('licenses') if Gitlab::Database.cached_table_exists?('licenses')
if Gitlab::Database::LoadBalancing.enable? if Gitlab::Database::LoadBalancing.enable?
Gitlab::Database.disable_prepared_statements Gitlab::Database.disable_prepared_statements
......
...@@ -18,7 +18,7 @@ module LicenseHelper ...@@ -18,7 +18,7 @@ module LicenseHelper
License.current&.maximum_user_count || 0 License.current&.maximum_user_count || 0
end end
def license_message(signed_in: signed_in?, is_admin: current_user&.admin?) def license_message(signed_in: signed_in?, is_admin: current_user&.admin?, in_html: true)
return unless current_license return unless current_license
return unless signed_in return unless signed_in
return unless (is_admin && current_license.notify_admins?) || current_license.notify_users? return unless (is_admin && current_license.notify_admins?) || current_license.notify_users?
...@@ -48,12 +48,7 @@ module LicenseHelper ...@@ -48,12 +48,7 @@ module LicenseHelper
message << 'service.' message << 'service.'
end end
unless is_trial message << renewal_instructions_message(in_html: in_html) unless is_trial
renewal_faq_url = 'https://about.gitlab.com/pricing/licensing-faq/#self-managed-gitlab'
renewal_faq_link_start = "<a href='#{renewal_faq_url}' target='_blank'>".html_safe
link_end = '</a>'.html_safe
message << _('For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}') % { link_start: renewal_faq_link_start, link_end: link_end }
end
message.join(' ').html_safe message.join(' ').html_safe
end end
...@@ -148,4 +143,16 @@ module LicenseHelper ...@@ -148,4 +143,16 @@ module LicenseHelper
def active_user_count def active_user_count
User.active.count User.active.count
end end
def renewal_instructions_message(in_html: true)
renewal_faq_url = 'https://about.gitlab.com/pricing/licensing-faq/#self-managed-gitlab'
renewal_faq_link_start = in_html ? "<a href='#{renewal_faq_url}' target='_blank'>".html_safe : ''
link_end = in_html ? '</a>'.html_safe : ''
message = _('For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}') % { link_start: renewal_faq_link_start, link_end: link_end }
message += ' ' + renewal_faq_url unless in_html
message
end
end end
...@@ -12,9 +12,10 @@ module EE ...@@ -12,9 +12,10 @@ module EE
def ee_import_table def ee_import_table
# This method can be called/loaded before the database # This method can be called/loaded before the database
# has been created. With this guard clause we prevent calling # has been created. With this guard clause we prevent querying
# the License table until the connection has been established # the License table until the table exists
return [] unless ActiveRecord::Base.connected? && License.feature_available?(:custom_project_templates) return [] unless ::Gitlab::Database.cached_table_exists?('licenses') &&
License.feature_available?(:custom_project_templates)
[::Gitlab::ImportSources::ImportSource.new('gitlab_custom_project_template', [::Gitlab::ImportSources::ImportSource.new('gitlab_custom_project_template',
'GitLab custom project template export', 'GitLab custom project template export',
......
...@@ -10,10 +10,7 @@ describe LicenseHelper do ...@@ -10,10 +10,7 @@ describe LicenseHelper do
describe '#license_message' do describe '#license_message' do
context 'license installed' do context 'license installed' do
subject { license_message(signed_in: true, is_admin: false) }
let(:license) { double('License') } let(:license) { double('License') }
let(:faq_link_regex) { /For renewal instructions <a href.*>view our Licensing FAQ\.<\/a>/ }
before do before do
allow(License).to receive(:current).and_return(license) allow(License).to receive(:current).and_return(license)
...@@ -22,16 +19,32 @@ describe LicenseHelper do ...@@ -22,16 +19,32 @@ describe LicenseHelper do
allow(license).to receive(:remaining_days).and_return(4) allow(license).to receive(:remaining_days).and_return(4)
end end
it 'does NOT have a license faq link if license is a trial' do context 'in HTML' do
allow(license).to receive(:trial?).and_return(true) let(:faq_link_regex) { /For renewal instructions <a href.*>view our Licensing FAQ\.<\/a>/ }
subject { license_message(signed_in: true, is_admin: false) }
it 'does NOT have a license faq link if license is a trial' do
allow(license).to receive(:trial?).and_return(true)
expect(subject).not_to match(faq_link_regex)
end
expect(subject).not_to match(faq_link_regex) it 'has license faq link if license is not a trial' do
allow(license).to receive(:trial?).and_return(false)
expect(subject).to match(faq_link_regex)
end
end end
it 'has license faq link if license is not a trial' do context 'not in HTML' do
allow(license).to receive(:trial?).and_return(false) subject { license_message(signed_in: true, is_admin: false, in_html: false) }
expect(subject).to match(faq_link_regex) it 'has license faq link if license is not a trial' do
allow(license).to receive(:trial?).and_return(false)
expect(subject).to match(/For renewal instructions view our Licensing FAQ. https:.*/)
end
end end
end end
......
...@@ -233,7 +233,7 @@ module Gitlab ...@@ -233,7 +233,7 @@ module Gitlab
end end
def self.cached_table_exists?(table_name) def self.cached_table_exists?(table_name)
connection.schema_cache.data_source_exists?(table_name) exists? && connection.schema_cache.data_source_exists?(table_name)
end end
def self.database_version def self.database_version
......
...@@ -22,7 +22,7 @@ module Gitlab ...@@ -22,7 +22,7 @@ module Gitlab
def self.set_feature_cache def self.set_feature_cache
# During db:create and db:bootstrap skip feature query as DB is not available yet. # During db:create and db:bootstrap skip feature query as DB is not available yet.
return false unless ActiveRecord::Base.connected? && Gitlab::Database.cached_table_exists?('features') return false unless Gitlab::Database.cached_table_exists?('features')
self.enabled = Feature.enabled?(MARGINALIA_FEATURE_FLAG) self.enabled = Feature.enabled?(MARGINALIA_FEATURE_FLAG)
end end
......
...@@ -394,6 +394,12 @@ describe Gitlab::Database do ...@@ -394,6 +394,12 @@ describe Gitlab::Database do
expect(described_class.cached_table_exists?(:bogus_table_name)).to be_falsey expect(described_class.cached_table_exists?(:bogus_table_name)).to be_falsey
end end
end end
it 'returns false when database does not exist' do
expect(ActiveRecord::Base).to receive(:connection) { raise ActiveRecord::NoDatabaseError, 'broken' }
expect(described_class.cached_table_exists?(:projects)).to be(false)
end
end end
describe '.exists?' do describe '.exists?' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment