Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions definitions/checks/candlepin/db_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Checks
module Candlepin
class DBIndex < ForemanMaintain::Check
metadata do
description 'Make sure Candlepin DB indexes are OK'
label :candlepin_db_index
tags :db_index
for_feature :candlepin_database
confine do
feature(:candlepin_database)&.local?
end
end

def run
status, output = feature(:candlepin_database).amcheck

if !status.nil?
assert(status == 0, "Candlepin DB indexes have issues:\n#{output}")
else
skip 'amcheck is not available in this setup'
end
end
end
end
end
25 changes: 25 additions & 0 deletions definitions/checks/foreman/db_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Checks
module Foreman
class DBIndex < ForemanMaintain::Check
metadata do
description 'Make sure Foreman DB indexes are OK'
label :foreman_db_index
tags :db_index
for_feature :foreman_database
confine do
feature(:foreman_database)&.local?
end
end

def run
status, output = feature(:foreman_database).amcheck

if !status.nil?
assert(status == 0, "Foreman DB indexes have issues:\n#{output}")
else
skip 'amcheck is not available in this setup'
end
end
end
end
end
25 changes: 25 additions & 0 deletions definitions/checks/pulpcore/db_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Checks
module Pulpcore
class DBIndex < ForemanMaintain::Check
metadata do
description 'Make sure Pulpcore DB indexes are OK'
label :pulpcore_db_index
tags :db_index
for_feature :pulpcore_database
confine do
feature(:pulpcore_database)&.local?
end
end

def run
status, output = feature(:pulpcore_database).amcheck

if !status.nil?
assert(status == 0, "Pulpcore DB indexes have issues:\n#{output}")
else
skip 'amcheck is not available in this setup'
end
end
end
end
end
3 changes: 3 additions & 0 deletions definitions/scenarios/backup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class Backup < ForemanMaintain::Scenario

def compose
check_valid_strategy
add_step(Checks::Foreman::DBIndex)
add_step(Checks::Candlepin::DBIndex)
add_step(Checks::Pulpcore::DBIndex)
add_step(Checks::ForemanTasks::NotRunning.new(:wait_for_tasks => wait_for_tasks?))
add_step(Checks::Pulpcore::NoRunningTasks.new(:wait_for_tasks => wait_for_tasks?))
add_step_with_context(Procedures::Backup::AccessibilityConfirmation) if strategy == :offline
Expand Down
34 changes: 34 additions & 0 deletions lib/foreman_maintain/concerns/base_database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,40 @@ def raise_psql_missing_error
' Make sure system has psql utility installed.'
end

def amcheck
# executing the check requires superuser privileges
return unless local?

return unless amcheck_installed?

psqlcmd = "runuser - postgres -c 'psql --set=ON_ERROR_STOP=on #{configuration['database']}'"

amcheck_query = <<~SQL
SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique),
c.relname,
c.relpages
FROM pg_index i
JOIN pg_opclass op ON i.indclass[0] = op.oid
JOIN pg_am am ON op.opcmethod = am.oid
JOIN pg_class c ON i.indexrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE am.amname = 'btree' AND n.nspname = 'public'
-- Don't check temp tables, which may be from another session:
AND c.relpersistence != 't'
-- Function may throw an error when this is omitted:
AND c.relkind = 'i' AND i.indisready AND i.indisvalid
ORDER BY c.relpages DESC;
SQL

execute_with_status(psqlcmd, :stdin => amcheck_query)
end

def amcheck_installed?
sql = "select 'amcheck_installed' from pg_extension where extname='amcheck'"
result = query(sql)
!result.nil? && !result.empty?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it check for the column we want to be present instead of just non-empty?

Suggested change
!result.nil? && !result.empty?
!result.nil? && result.include?('amcheck_installed')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now result is something like [{"?column?"=>"amcheck_installed"}], so the include? would need to be a tad more smart, but it's really not necessary, as the result will be empty if the extensions is not there.

end

private

def base_env
Expand Down
6 changes: 5 additions & 1 deletion test/definitions/scenarios/backup_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ module Scenarios
end

let(:checks) do
task_checks
task_checks + [
Checks::Foreman::DBIndex,
Checks::Candlepin::DBIndex,
Checks::Pulpcore::DBIndex,
]
end

describe 'offline' do
Expand Down