Skip to content

Commit

Permalink
Fixes #37874 - don't try to swap modules, this can fail
Browse files Browse the repository at this point in the history
instead use single-user mode cluster based on the postgresql-upgrade
binaries

(cherry picked from commit 67702be)
  • Loading branch information
evgeni authored and ekohl committed Oct 7, 2024
1 parent 4a3177d commit 3c2d385
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 22 deletions.
22 changes: 14 additions & 8 deletions hooks/boot/06-postgresql-upgrade-extensions.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require 'csv'

module PostgresqlUpgradeHookContextExtension
def needs_postgresql_upgrade?(new_version)
current_version.to_i < new_version.to_i
Expand All @@ -18,12 +16,6 @@ def os_needs_postgresql_upgrade?
def postgresql_upgrade(new_version)
logger.notice("Performing upgrade of PostgreSQL to #{new_version}")

execute!("dnf module switch-to postgresql:#{current_version} -y", false, true)
start_services(['postgresql'])
postgres_list = `runuser -l postgres -c 'psql --list --tuples-only --csv'`
postgres_databases = CSV.parse(postgres_list)
(_name, _owner, _enconding, collate, ctype, _privileges) = postgres_databases.find { |line| line.first == 'postgres' }

stop_services

logger.notice("Upgrading PostgreSQL packages")
Expand All @@ -41,6 +33,20 @@ def postgresql_upgrade(new_version)

logger.notice("Migrating PostgreSQL data")

# We need to know the collation and ctype of the DB as postgresql-setup --upgrade
# doesn't detect those on its own: https://issues.redhat.com/browse/RHEL-58410
# dnf switch-to has already replaced the packages and the cluster is down
# We have to start the cluster in single-user mode with the old postgres binary
postgres_result = `echo "select datcollate,datctype from pg_database where datname='postgres';" | runuser -l postgres -c '/usr/lib64/pgsql/postgresql-#{current_version}/bin/postgres --single -D /var/lib/pgsql/data postgres'`
data = {}
postgres_result.each_line do |line|
line.match(/dat(collate|ctype)\s+=\s+(\S+)/) do |m|
data[m[1]] = m[2].delete('"')
end
end
collate = data['collate']
ctype = data['ctype']

# puppetlabs-postgresql always sets data_directory in the config
# see https://github.com/puppetlabs/puppetlabs-postgresql/issues/1576
# however, one can't use postgresql-setup --upgrade if that value is set
Expand Down
23 changes: 9 additions & 14 deletions spec/postgresql_upgrade_hook_context_extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,16 @@
allow(context).to receive(:ensure_packages)
allow(context).to receive(:stop_services)
allow(context).to receive(:start_services)
allow(context).to receive(:'`').with("runuser -l postgres -c 'psql --list --tuples-only --csv'")
allow(context).to receive(:'`').with("echo \"select datcollate,datctype from pg_database where datname='postgres';\" | runuser -l postgres -c '/usr/lib64/pgsql/postgresql-12/bin/postgres --single -D /var/lib/pgsql/data postgres'")
.and_return(<<~PSQL
candlepin,postgres,UTF8,en_US.utf8,en_US.utf8,"=T/postgres
postgres=CTc/postgres
candlepin=CTc/postgres"
foreman,foreman,UTF8,en_US.utf8,en_US.utf8,"=T/foreman
foreman=CTc/foreman"
postgres,postgres,UTF8,en_US.UTF-8,en_US.UTF-8,
pulpcore,postgres,UTF8,en_US.utf8,en_US.utf8,"=T/postgres
postgres=CTc/postgres
pulp=CTc/postgres"
template0,postgres,UTF8,en_US.UTF-8,en_US.UTF-8,"=c/postgres
postgres=CTc/postgres"
template1,postgres,UTF8,en_US.UTF-8,en_US.UTF-8,"=c/postgres
postgres=CTc/postgres"
PostgreSQL stand-alone backend 12.18
backend> 1: datcollate (typeid = 19, len = 64, typmod = -1, byval = f)
2: datctype (typeid = 19, len = 64, typmod = -1, byval = f)
----
1: datcollate = "en_US.UTF-8" (typeid = 19, len = 64, typmod = -1, byval = f)
2: datctype = "en_US.UTF-8" (typeid = 19, len = 64, typmod = -1, byval = f)
----
backend>
PSQL
)
allow(logger).to receive(:notice)
Expand Down

0 comments on commit 3c2d385

Please sign in to comment.