diff --git a/definitions/checks/candlepin/db_up.rb b/definitions/checks/candlepin/db_up.rb index 102a30df5..1b39f6cf3 100644 --- a/definitions/checks/candlepin/db_up.rb +++ b/definitions/checks/candlepin/db_up.rb @@ -1,32 +1,20 @@ +require_relative '../db_up_check' + module Checks module Candlepin - class DBUp < ForemanMaintain::Check + class DBUp < DBUpCheck metadata do description 'Make sure Candlepin DB is up' label :candlepin_db_up for_feature :candlepin_database end - def run - status = false - if feature(:candlepin_database).psql_cmd_available? - with_spinner('Checking connection to the Candlepin DB') do - status = feature(:candlepin_database).ping - end - assert(status, 'Candlepin DB is not responding. ' \ - 'It needs to be up and running to perform the following steps', - :next_steps => start_pgsql) - else - feature(:candlepin_database).raise_psql_missing_error - end + def database_feature + :candlepin_database end - def start_pgsql - if feature(:candlepin_database).local? - [Procedures::Service::Start.new(:only => 'postgresql')] - else - [] # there is nothing we can do for remote db - end + def database_name + 'Candlepin' end end end diff --git a/definitions/checks/container_gateway/db_up.rb b/definitions/checks/container_gateway/db_up.rb new file mode 100644 index 000000000..d3c57ee3d --- /dev/null +++ b/definitions/checks/container_gateway/db_up.rb @@ -0,0 +1,21 @@ +require_relative '../db_up_check' + +module Checks + module ContainerGateway + class DBUp < DBUpCheck + metadata do + description 'Make sure ContainerGateway DB is up' + label :container_gateway_db_up + for_feature :container_gateway_database + end + + def database_feature + :container_gateway_database + end + + def database_name + 'Container Gateway' + end + end + end +end diff --git a/definitions/checks/db_up_check.rb b/definitions/checks/db_up_check.rb new file mode 100644 index 000000000..1d4df9647 --- /dev/null +++ b/definitions/checks/db_up_check.rb @@ -0,0 +1,33 @@ +module Checks + class DBUpCheck < ForemanMaintain::Check + def run + status = false + if feature(database_feature).psql_cmd_available? + with_spinner("Checking connection to the #{database_name} DB") do + status = feature(database_feature).ping + end + assert(status, "#{database_name} DB is not responding. " \ + "It needs to be up and running to perform the following steps", + :next_steps => start_pgsql) + else + feature(database_feature).raise_psql_missing_error + end + end + + def start_pgsql + if feature(database_feature).local? + [Procedures::Service::Start.new(:only => 'postgresql')] + else + [] # there is nothing we can do for remote db + end + end + + def database_feature + raise NotImplementedError, 'Subclasses must define `database_feature`' + end + + def database_name + raise NotImplementedError, 'Subclasses must define `database_name`' + end + end +end diff --git a/definitions/checks/foreman/db_up.rb b/definitions/checks/foreman/db_up.rb index 6ea8ccd00..777b07b82 100644 --- a/definitions/checks/foreman/db_up.rb +++ b/definitions/checks/foreman/db_up.rb @@ -1,32 +1,20 @@ +require_relative '../db_up_check' + module Checks module Foreman - class DBUp < ForemanMaintain::Check + class DBUp < DBUpCheck metadata do description 'Make sure Foreman DB is up' label :foreman_db_up for_feature :foreman_database end - def run - status = false - if feature(:foreman_database).psql_cmd_available? - with_spinner('Checking connection to the Foreman DB') do - status = feature(:foreman_database).ping - end - assert(status, 'Foreman DB is not responding. ' \ - 'It needs to be up and running to perform the following steps', - :next_steps => start_pgsql) - else - feature(:foreman_database).raise_psql_missing_error - end + def database_feature + :foreman_database end - def start_pgsql - if feature(:foreman_database).local? - [Procedures::Service::Start.new(:only => 'postgresql')] - else - [] # there is nothing we can do for remote db - end + def database_name + 'Foreman' end end end diff --git a/definitions/checks/pulpcore/db_up.rb b/definitions/checks/pulpcore/db_up.rb index 30fb353bf..567bdd7c0 100644 --- a/definitions/checks/pulpcore/db_up.rb +++ b/definitions/checks/pulpcore/db_up.rb @@ -1,28 +1,20 @@ +require_relative '../db_up_check' + module Checks module Pulpcore - class DBUp < ForemanMaintain::Check + class DBUp < DBUpCheck metadata do description 'Make sure Pulpcore DB is up' label :pulpcore_db_up for_feature :pulpcore_database end - def run - status = false - with_spinner('Checking connection to the Pulpcore DB') do - status = feature(:pulpcore_database).ping - end - assert(status, 'Pulpcore DB is not responding. ' \ - 'It needs to be up and running to perform the following steps', - :next_steps => next_steps) + def database_feature + :pulpcore_database end - def next_steps - if feature(:pulpcore_database).local? - [Procedures::Service::Start.new(:only => 'postgresql')] - else - [] # there is nothing we can do for remote db - end + def database_name + 'Pulpcore' end end end diff --git a/definitions/checks/restore/validate_postgresql_dump_permissions.rb b/definitions/checks/restore/validate_postgresql_dump_permissions.rb index 486c2ec93..5ade52612 100644 --- a/definitions/checks/restore/validate_postgresql_dump_permissions.rb +++ b/definitions/checks/restore/validate_postgresql_dump_permissions.rb @@ -13,7 +13,7 @@ def run backup = ForemanMaintain::Utils::Backup.new(@backup_dir) if feature(:instance).postgresql_local? errors = [] - [:candlepin_dump, :foreman_dump, :pulpcore_dump].each do |dump| + [:candlepin_dump, :foreman_dump, :pulpcore_dump, :container_gateway_dump].each do |dump| next unless backup.file_map[dump][:present] unless system("runuser - postgres -c 'test -r #{backup.file_map[dump][:path]}'") diff --git a/definitions/features/candlepin_database.rb b/definitions/features/candlepin_database.rb index 34374298b..8051819dc 100644 --- a/definitions/features/candlepin_database.rb +++ b/definitions/features/candlepin_database.rb @@ -47,6 +47,10 @@ def load_configuration 'driver_class' => full_config['jpa.config.hibernate.connection.driver_class'], 'url' => url, } + + # Build connection string for pg_dump (only used for local databases) + @configuration['connection_string'] = "postgres:///#{@configuration['database']}" + @configuration end def extend_with_db_options diff --git a/definitions/features/container_gateway_database.rb b/definitions/features/container_gateway_database.rb new file mode 100644 index 000000000..7d71cd3da --- /dev/null +++ b/definitions/features/container_gateway_database.rb @@ -0,0 +1,39 @@ +class Features::ContainerGatewayDatabase < ForemanMaintain::Feature + CONTAINER_GATEWAY_DB_CONFIG = '/etc/foreman-proxy/settings.d/container_gateway.yml'.freeze + + include ForemanMaintain::Concerns::BaseDatabase + include ForemanMaintain::Concerns::DirectoryMarker + + metadata do + label :container_gateway_database + + confine do + file_nonzero?(CONTAINER_GATEWAY_DB_CONFIG) + end + end + + def configuration + @configuration || load_configuration + end + + def services + [ + system_service('postgresql', 10, :component => 'container_gateway', + :db_feature => feature(:container_gateway_database)), + ] + end + + private + + def load_configuration + config = YAML.load(File.read(CONTAINER_GATEWAY_DB_CONFIG)) + @configuration = {} + connection_string = config[:db_connection_string] + if connection_string + uri = URI.parse(connection_string) + @configuration['connection_string'] = connection_string + @configuration['database'] = uri.path.delete_prefix('/') + end + @configuration + end +end diff --git a/definitions/features/foreman_database.rb b/definitions/features/foreman_database.rb index a37df8a68..d042e35d0 100644 --- a/definitions/features/foreman_database.rb +++ b/definitions/features/foreman_database.rb @@ -43,6 +43,9 @@ def load_configuration @configuration = config['production'] @configuration['host'] ||= 'localhost' + + # Build connection string for pg_dump (only used for local databases) + @configuration['connection_string'] = "postgres:///#{@configuration['database']}" @configuration end end diff --git a/definitions/features/instance.rb b/definitions/features/instance.rb index f8b11e22c..ea72b27f4 100644 --- a/definitions/features/instance.rb +++ b/definitions/features/instance.rb @@ -47,7 +47,8 @@ def database_local?(feature) def postgresql_local? database_local?(:candlepin_database) || database_local?(:foreman_database) || - database_local?(:pulpcore_database) + database_local?(:pulpcore_database) || + database_local?(:container_gateway_database) end def foreman_proxy_with_content? diff --git a/definitions/features/pulpcore_database.rb b/definitions/features/pulpcore_database.rb index 0c9905979..2d7b41421 100644 --- a/definitions/features/pulpcore_database.rb +++ b/definitions/features/pulpcore_database.rb @@ -41,6 +41,9 @@ def load_configuration @configuration['database'] = db_config['NAME'] @configuration['username'] = db_config['USER'] @configuration['password'] = db_config['PASSWORD'] + + # Build connection string for pg_dump (only used for local databases) + @configuration['connection_string'] = "postgres:///#{db_config['NAME']}" @configuration end end diff --git a/definitions/procedures/backup/online/container_gateway_db.rb b/definitions/procedures/backup/online/container_gateway_db.rb new file mode 100644 index 000000000..d2c8a3ab2 --- /dev/null +++ b/definitions/procedures/backup/online/container_gateway_db.rb @@ -0,0 +1,21 @@ +module Procedures::Backup + module Online + class ContainerGatewayDB < ForemanMaintain::Procedure + metadata do + description 'Backup Container Gateway database' + tags :backup + label :backup_online_container_gateway_db + for_feature :container_gateway_database + preparation_steps { Checks::ContainerGateway::DBUp.new } + param :backup_dir, 'Directory where to backup to', :required => true + end + + def run + with_spinner('Getting Container Gateway DB dump') do + feature(:container_gateway_database). + dump_db(File.join(@backup_dir, 'container_gateway.dump')) + end + end + end + end +end diff --git a/definitions/procedures/restore/container_gateway_dump.rb b/definitions/procedures/restore/container_gateway_dump.rb new file mode 100644 index 000000000..63fc5700a --- /dev/null +++ b/definitions/procedures/restore/container_gateway_dump.rb @@ -0,0 +1,31 @@ +module Procedures::Restore + class ContainerGatewayDump < ForemanMaintain::Procedure + metadata do + description 'Restore container gateway postgresql dump from backup' + param :backup_dir, + 'Path to backup directory', + :required => true + preparation_steps { Checks::ContainerGateway::DBUp.new } + confine do + feature(:container_gateway_database) + end + end + + def run + backup = ForemanMaintain::Utils::Backup.new(@backup_dir) + + with_spinner('Restoring container gateway postgresql dump') do |spinner| + restore_container_gateway_dump(backup, spinner) + end + end + + def restore_container_gateway_dump(backup, spinner) + if backup.file_map[:container_gateway_dump][:present] + spinner.update('Restoring container gateway dump') + local = feature(:container_gateway_database).local? + feature(:container_gateway_database). + restore_dump(backup.file_map[:container_gateway_dump][:path], local) + end + end + end +end diff --git a/definitions/procedures/restore/drop_databases.rb b/definitions/procedures/restore/drop_databases.rb index 8afcdef68..cc8fc374b 100644 --- a/definitions/procedures/restore/drop_databases.rb +++ b/definitions/procedures/restore/drop_databases.rb @@ -13,7 +13,8 @@ class DropDatabases < ForemanMaintain::Procedure feature(:iop_inventory_database) || feature(:iop_remediations_database) || feature(:iop_vmaas_database) || - feature(:iop_vulnerability_database) + feature(:iop_vulnerability_database) || + feature(:container_gateway_database) end end @@ -30,6 +31,7 @@ def run drop_iop_remediations(backup, spinner) drop_iop_vmaas(backup, spinner) drop_iop_vulnerability(backup, spinner) + drop_container_gateway(backup, spinner) end end @@ -88,5 +90,12 @@ def drop_iop_vulnerability(backup, spinner) feature(:iop_vulnerability_database).dropdb end end + + def drop_container_gateway(backup, spinner) + if backup.file_map[:container_gateway_dump][:present] + spinner.update('Dropping container gateway database') + feature(:container_gateway_database).dropdb + end + end end end diff --git a/definitions/procedures/restore/extract_files.rb b/definitions/procedures/restore/extract_files.rb index 8390b9f42..764b0cf84 100644 --- a/definitions/procedures/restore/extract_files.rb +++ b/definitions/procedures/restore/extract_files.rb @@ -45,7 +45,12 @@ def extract_pulp_data(backup) end def any_database - feature(:foreman_database) || feature(:candlepin_database) || feature(:pulpcore_database) + %i[ + foreman_database + candlepin_database + pulpcore_database + container_gateway_database + ].any? { |db| feature(db) } end end end diff --git a/definitions/scenarios/backup.rb b/definitions/scenarios/backup.rb index 2062c9850..5aaa65221 100644 --- a/definitions/scenarios/backup.rb +++ b/definitions/scenarios/backup.rb @@ -52,7 +52,8 @@ def set_context_mapping Procedures::Backup::Online::IopRemediationsDB => :backup_dir, Procedures::Backup::Online::IopVmaasDB => :backup_dir, Procedures::Backup::Online::IopVulnerabilityDB => :backup_dir, - Procedures::Backup::Online::PulpcoreDB => :backup_dir) + Procedures::Backup::Online::PulpcoreDB => :backup_dir, + Procedures::Backup::Online::ContainerGatewayDB => :backup_dir) context.map(:preserve_dir, Procedures::Backup::PrepareDirectory => :preserve_dir) context.map(:incremental_dir, @@ -112,7 +113,8 @@ def add_database_backup_steps Procedures::Backup::Online::IopRemediationsDB, Procedures::Backup::Online::IopVmaasDB, Procedures::Backup::Online::IopVulnerabilityDB, - Procedures::Backup::Online::PulpcoreDB + Procedures::Backup::Online::PulpcoreDB, + Procedures::Backup::Online::ContainerGatewayDB ) end diff --git a/definitions/scenarios/restore.rb b/definitions/scenarios/restore.rb index 2778bbd68..09bbb0614 100644 --- a/definitions/scenarios/restore.rb +++ b/definitions/scenarios/restore.rb @@ -47,9 +47,8 @@ def compose add_step_with_context(Procedures::Crond::Start) add_step_with_context(Procedures::Timer::Start) end - # rubocop:enable Metrics/MethodLength,Metrics/AbcSize - # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity + # rubocop:disable Metrics/CyclomaticComplexity def restore_sql_dumps(backup) if feature(:instance).postgresql_local? add_step(Procedures::Service::Start.new(:only => ['postgresql'])) @@ -81,6 +80,9 @@ def restore_sql_dumps(backup) if backup.file_map[:pulpcore_dump][:present] add_steps_with_context(Procedures::Restore::PulpcoreDump) end + if backup.file_map[:container_gateway_dump][:present] + add_steps_with_context(Procedures::Restore::ContainerGatewayDump) + end if feature(:instance).postgresql_local? add_step(Procedures::Service::Stop.new(:only => ['postgresql'])) end @@ -104,6 +106,7 @@ def set_context_mapping Procedures::Restore::IopVmaasDump => :backup_dir, Procedures::Restore::IopVulnerabilityDump => :backup_dir, Procedures::Restore::PulpcoreDump => :backup_dir, + Procedures::Restore::ContainerGatewayDump => :backup_dir, Procedures::Restore::ExtractFiles => :backup_dir) end end diff --git a/lib/foreman_maintain/concerns/base_database.rb b/lib/foreman_maintain/concerns/base_database.rb index b89cbdd03..def91a3d8 100644 --- a/lib/foreman_maintain/concerns/base_database.rb +++ b/lib/foreman_maintain/concerns/base_database.rb @@ -42,8 +42,9 @@ def configuration raise NotImplementedError end - def local? - ['localhost', '127.0.0.1', `hostname`.strip].include?(configuration['host']) + def local?(config = configuration) + ['localhost', '127.0.0.1', `hostname`.strip].include?(configuration['host']) || + config['host'].nil? end def query(sql) @@ -57,20 +58,35 @@ def query_csv(sql) def psql(query) ping! - execute('psql', - :stdin => query, - :env => base_env) + if local? + execute("runuser - postgres -c 'psql -d #{configuration['database']}' -c '#{query}'") + else + execute('psql', + :stdin => query, + :env => base_env) + end end def ping - execute?('psql', - :stdin => 'SELECT 1 as ping', - :env => base_env) + if local? + command = "runuser - postgres -c 'psql -d #{configuration['database']}'" + env = nil + else + command = 'psql' + env = base_env + end + execute?(command, stdin: 'SELECT 1 as ping', env: env) end def dump_db(file) - dump_command = "pg_dump -Fc -f #{file}" - execute!(dump_command, :env => base_env) + if local? + dump_command = "pg_dump --format=c #{configuration['connection_string']}" + execute!("chown -R postgres:postgres #{File.dirname(file)}") + execute!("runuser - postgres -c '#{dump_command} -f #{file}'") + else + dump_command = "pg_dump -Fc -f #{file}" + execute!(dump_command, :env => base_env) + end end def restore_dump(file, localdb) @@ -126,7 +142,11 @@ def db_version query = 'SHOW server_version' server_version_cmd = 'psql --tuples-only --no-align' - version_string = execute!(server_version_cmd, :stdin => query, :env => base_env) + version_string = if local? + execute!("runuser - postgres -c '#{server_version_cmd} -c \"#{query}\"'") + else + execute!(server_version_cmd, :stdin => query, :env => base_env) + end version(version_string) end diff --git a/lib/foreman_maintain/utils/backup.rb b/lib/foreman_maintain/utils/backup.rb index 96faa2af4..7ac356d80 100644 --- a/lib/foreman_maintain/utils/backup.rb +++ b/lib/foreman_maintain/utils/backup.rb @@ -19,7 +19,7 @@ def initialize(backup_dir) @standard_files = ['config_files.tar.gz'] @foreman_online_files = ['foreman.dump'] @katello_online_files = @foreman_online_files + ['candlepin.dump', 'pulpcore.dump'] - @fpc_online_files = ['pulpcore.dump'] + @fpc_online_files = ['pulpcore.dump', 'container_gateway.dump'] end def file_map @@ -35,6 +35,7 @@ def file_map :config_files => map_file(@backup_dir, 'config_files.tar.gz'), :metadata => map_file(@backup_dir, 'metadata.yml'), :pulpcore_dump => map_file(@backup_dir, 'pulpcore.dump'), + :container_gateway_dump => map_file(@backup_dir, 'container_gateway.dump'), } end @@ -96,20 +97,20 @@ def check_file_existence(existence_map) def katello_online_backup? present = [:candlepin_dump, :foreman_dump, :pulpcore_dump] - absent = [] + absent = [:container_gateway_dump] check_file_existence(:present => present, :absent => absent) end def fpc_online_backup? - present = [:pulpcore_dump] + present = [:pulpcore_dump, :container_gateway_dump] absent = [:candlepin_dump, :foreman_dump] check_file_existence(:present => present, :absent => absent) end def foreman_online_backup? check_file_existence(:present => [:foreman_dump], - :absent => [:candlepin_dump, :pulpcore_dump]) + :absent => [:candlepin_dump, :pulpcore_dump, :container_gateway_dump]) end def validate_hostname? @@ -156,7 +157,8 @@ def tar_backups_exist? def sql_dump_files_exist? file_map[:foreman_dump][:present] || file_map[:candlepin_dump][:present] || - file_map[:pulpcore_dump][:present] + file_map[:pulpcore_dump][:present] || + file_map[:container_gateway_dump][:present] end def sql_needs_dump_restore? diff --git a/test/definitions/checks/restore/validate_postgresql_dump_permissions_test.rb b/test/definitions/checks/restore/validate_postgresql_dump_permissions_test.rb index ad0f70609..51026c9d4 100644 --- a/test/definitions/checks/restore/validate_postgresql_dump_permissions_test.rb +++ b/test/definitions/checks/restore/validate_postgresql_dump_permissions_test.rb @@ -12,6 +12,8 @@ :foreman_dump => { :present => true, :path => '/nonexistant/foreman.dump' }, :candlepin_dump => { :present => true, :path => '/nonexistant/candlepin.dump' }, :pulpcore_dump => { :present => true, :path => '/nonexistant/pulpcore.dump' }, + :container_gateway_dump => + { :present => true, :path => '/nonexistant/container_gateway.dump' }, } ForemanMaintain::Utils::Backup.any_instance.stubs(:file_map).returns(file_map) end @@ -53,7 +55,8 @@ result = run_check(subject) refute result.success?, 'Check expected to fail' expected = "The 'postgres' user needs read access to the following files:\n" \ - "/nonexistant/candlepin.dump\n/nonexistant/foreman.dump\n/nonexistant/pulpcore.dump" + "/nonexistant/candlepin.dump\n/nonexistant/foreman.dump\n" \ + "/nonexistant/pulpcore.dump\n/nonexistant/container_gateway.dump" assert_equal result.output, expected end @@ -66,6 +69,9 @@ returns(true) subject.stubs(:system).with("runuser - postgres -c 'test -r /nonexistant/foreman.dump'"). returns(true) + subject.stubs(:system). + with("runuser - postgres -c 'test -r /nonexistant/container_gateway.dump'"). + returns(true) result = run_check(subject) refute result.success?, 'Check expected to fail' expected = "The 'postgres' user needs read access to the following files:\n" \ diff --git a/test/definitions/features/candlepin_database_test.rb b/test/definitions/features/candlepin_database_test.rb index aa875d862..6f5eae185 100644 --- a/test/definitions/features/candlepin_database_test.rb +++ b/test/definitions/features/candlepin_database_test.rb @@ -36,5 +36,21 @@ def stub_without_ssl_config(&block) refute_includes url, 'sslrootcert=/usr/share/foreman/root.crt' end end + + it 'Sets connection_string for local database backups with SSL' do + stub_with_ssl_config do + config = subject.configuration + assert_equal 'candlepin1db', config['database'] + assert_equal 'postgres:///candlepin1db', config['connection_string'] + end + end + + it 'Sets connection_string for local database backups without SSL' do + stub_without_ssl_config do + config = subject.configuration + assert_equal 'candlepin', config['database'] + assert_equal 'postgres:///candlepin', config['connection_string'] + end + end end end diff --git a/test/definitions/features/foreman_database_test.rb b/test/definitions/features/foreman_database_test.rb new file mode 100644 index 000000000..ce740aaad --- /dev/null +++ b/test/definitions/features/foreman_database_test.rb @@ -0,0 +1,37 @@ +require 'test_helper' + +describe Features::ForemanDatabase do + include DefinitionsTestHelper + + subject { Features::ForemanDatabase.new } + + describe '.configuration' do + it 'returns hash with DB config and connection_string' do + database_yml_content = { + 'production' => { + 'adapter' => 'postgresql', + 'host' => 'localhost', + 'port' => 5432, + 'database' => 'foreman', + 'username' => 'foreman', + 'password' => 'password', + }, + } + + File.expects(:exist?).with('/etc/foreman/database.yml').returns(true) + File.expects(:read).with('/etc/foreman/database.yml').returns('mocked_yaml_content') + YAML.expects(:load).with('mocked_yaml_content').returns(database_yml_content) + + expected = { + 'adapter' => 'postgresql', + 'host' => 'localhost', + 'port' => 5432, + 'database' => 'foreman', + 'username' => 'foreman', + 'password' => 'password', + 'connection_string' => 'postgres:///foreman', + } + assert_equal expected, subject.configuration + end + end +end diff --git a/test/definitions/features/pulpcore_database_test.rb b/test/definitions/features/pulpcore_database_test.rb index 1efe52760..a17d8e03f 100644 --- a/test/definitions/features/pulpcore_database_test.rb +++ b/test/definitions/features/pulpcore_database_test.rb @@ -15,7 +15,8 @@ JSON subject.expects(:execute!).with(expected_command, merge_stderr: false).returns(manager_return) expected = { "adapter" => "postgresql", "host" => "remotedb", "port" => "5432", - "database" => "pulpcore", "username" => "pulp", "password" => "password" } + "database" => "pulpcore", "username" => "pulp", "password" => "password", + "connection_string" => "postgres:///pulpcore" } assert_equal expected, subject.configuration end end diff --git a/test/definitions/scenarios/restore_test.rb b/test/definitions/scenarios/restore_test.rb index 3072f130b..59adbda55 100644 --- a/test/definitions/scenarios/restore_test.rb +++ b/test/definitions/scenarios/restore_test.rb @@ -29,6 +29,7 @@ module Scenarios assume_feature_present(:foreman_database, :configuration => {}) assume_feature_present(:candlepin_database, :configuration => {}) assume_feature_present(:pulpcore_database, :configuration => {}) + assume_feature_present(:container_gateway_database, :configuration => {}) ForemanMaintain::Utils::Backup.any_instance.stubs(:file_map).returns( { @@ -40,6 +41,7 @@ module Scenarios :iop_remediations_dump => { :present => false }, :iop_vmaas_dump => { :present => false }, :iop_vulnerability_dump => { :present => false }, + :container_gateway_dump => { :present => true }, :pulp_data => { :present => true }, :metadata => { :present => false }, } @@ -50,6 +52,7 @@ module Scenarios assert_scenario_has_step(scenario, Procedures::Restore::ForemanDump) assert_scenario_has_step(scenario, Procedures::Restore::CandlepinDump) assert_scenario_has_step(scenario, Procedures::Restore::PulpcoreDump) + assert_scenario_has_step(scenario, Procedures::Restore::ContainerGatewayDump) end it 'does not try to drop/restore DB dumps when these are absent' do @@ -63,6 +66,7 @@ module Scenarios refute_scenario_has_step(scenario, Procedures::Restore::ForemanDump) refute_scenario_has_step(scenario, Procedures::Restore::CandlepinDump) refute_scenario_has_step(scenario, Procedures::Restore::PulpcoreDump) + refute_scenario_has_step(scenario, Procedures::Restore::ContainerGatewayDump) end end diff --git a/test/files/backups/fpc_logical_pulpcore_database/container_gateway.dump b/test/files/backups/fpc_logical_pulpcore_database/container_gateway.dump new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/backups/fpc_online_pulpcore_database/container_gateway.dump b/test/files/backups/fpc_online_pulpcore_database/container_gateway.dump new file mode 100644 index 000000000..e69de29bb diff --git a/test/lib/concerns/base_database_test.rb b/test/lib/concerns/base_database_test.rb index c65dd1f38..27afdbd4b 100644 --- a/test/lib/concerns/base_database_test.rb +++ b/test/lib/concerns/base_database_test.rb @@ -37,7 +37,8 @@ module ForemanMaintain assert db.local? end - it 'fetches server version' do + it 'fetches server version remotely' do + db.expects(:local?).returns(false) db.expects(:ping!) db.expects(:execute!).with( 'psql --tuples-only --no-align', @@ -48,6 +49,16 @@ module ForemanMaintain assert db.db_version end + it 'fetches server version locally' do + db.expects(:local?).returns(true) + db.expects(:ping!) + db.expects(:execute!).with( + "runuser - postgres -c 'psql --tuples-only --no-align -c \"SHOW server_version\"'" + ).returns('13.16') + + assert db.db_version + end + it 'drops db' do db.expects(:execute!).with("runuser - postgres -c 'dropdb fakedb'").returns('') @@ -63,25 +74,58 @@ module ForemanMaintain assert db.restore_dump(file, true) end - it 'dumps db' do + it 'dumps db locally and uses the postgres user' do file = '/backup/fake.dump' db.expects(:execute!).with( - "pg_dump -Fc -f /backup/fake.dump", - env: expected_env + "chown -R postgres:postgres #{File.dirname(file)}", + ).returns('') + + db.expects(:execute!).with( + "runuser - postgres -c 'pg_dump --format=c -f /backup/fake.dump'", ).returns('') assert db.dump_db(file) end - it 'pings db' do + it 'pings db locally' do + db.expects(:local?).returns(true) + db.expects(:execute?).with( + "runuser - postgres -c 'psql -d fakedb'", + stdin: 'SELECT 1 as ping', + env: nil + ).returns(true) + + assert db.ping + end + + it 'pings db remotely' do + db.expects(:local?).returns(false) db.expects(:execute?).with("psql", stdin: "SELECT 1 as ping", env: expected_env).returns(true) assert db.ping end - it 'runs db queries' do + it 'runs db queries locally' do + db.expects(:local?).returns(true) + psql_return = <<~PSQL + test + ------ + 42 + (1 row) + PSQL + + db.expects(:ping!) + db.expects(:execute).with( + "runuser - postgres -c 'psql -d fakedb' -c 'SELECT 42 as test'", + ).returns(psql_return) + + assert db.psql('SELECT 42 as test') + end + + it 'runs db queries remotely' do + db.expects(:local?).returns(false) psql_return = <<~PSQL test ------ diff --git a/test/lib/utils/backup_test.rb b/test/lib/utils/backup_test.rb index 7aaf436a2..f236dcff5 100644 --- a/test/lib/utils/backup_test.rb +++ b/test/lib/utils/backup_test.rb @@ -49,6 +49,7 @@ def assume_feature_absent(label) it 'Validates fpc online backup' do assume_feature_present(:pulpcore_database) + assume_feature_present(:container_gateway_database) fpc_online_backup = subject.new(fpc_online) refute fpc_online_backup.katello_online_backup? refute fpc_online_backup.foreman_online_backup?