Port Homebrew::Cmd::PostgresqlUpgradeDatabase
This commit is contained in:
parent
c1b1c11a8c
commit
31aa89aa7c
@ -1,169 +1,167 @@
|
||||
# typed: true
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
require "abstract_command"
|
||||
require "formula"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
module Cmd
|
||||
class PostgresqlUpgradeDatabase < AbstractCommand
|
||||
cmd_args do
|
||||
description <<~EOS
|
||||
Upgrades the database for the `postgresql` formula.
|
||||
EOS
|
||||
|
||||
sig { returns(CLI::Parser) }
|
||||
def postgresql_upgrade_database_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Upgrades the database for the `postgresql` formula.
|
||||
EOS
|
||||
named_args :none
|
||||
|
||||
named_args :none
|
||||
|
||||
hide_from_man_page!
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def postgresql_upgrade_database
|
||||
postgresql_upgrade_database_args.parse
|
||||
|
||||
odisabled "brew postgresql_upgrade_database",
|
||||
"using new, versioned e.g. `var/postgres@14` datadir and `pg_upgrade`"
|
||||
|
||||
name = "postgresql"
|
||||
pg = Formula[name]
|
||||
bin = pg.bin
|
||||
var = pg.var
|
||||
version = pg.version
|
||||
pg_version_file = var/"postgres/PG_VERSION"
|
||||
|
||||
pg_version_installed = version.to_s[/^\d+/]
|
||||
pg_version_data = pg_version_file.read.chomp
|
||||
if pg_version_installed == pg_version_data
|
||||
odie <<~EOS
|
||||
#{name} data already upgraded!
|
||||
EOS
|
||||
end
|
||||
|
||||
datadir = var/"postgres"
|
||||
old_datadir = var/"postgres.old"
|
||||
if old_datadir.exist?
|
||||
odie <<~EOS
|
||||
#{old_datadir} already exists!
|
||||
Remove it if you want to upgrade data automatically.
|
||||
EOS
|
||||
end
|
||||
|
||||
old_pg_name = "#{name}@#{pg_version_data}"
|
||||
old_pg_glob = "#{HOMEBREW_CELLAR}/#{old_pg_name}/#{pg_version_data}.*/bin"
|
||||
old_bin = Pathname.glob(old_pg_glob).first
|
||||
old_bin ||= begin
|
||||
Formula[old_pg_name]
|
||||
ohai "brew install #{old_pg_name}"
|
||||
system HOMEBREW_BREW_FILE, "install", old_pg_name
|
||||
Pathname.glob(old_pg_glob).first
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
end
|
||||
|
||||
odie "No #{name} #{pg_version_data}.* version installed!" unless old_bin
|
||||
|
||||
server_stopped = T.let(false, T::Boolean)
|
||||
moved_data = T.let(false, T::Boolean)
|
||||
initdb_run = T.let(false, T::Boolean)
|
||||
upgraded = T.let(false, T::Boolean)
|
||||
|
||||
begin
|
||||
# Following instructions from:
|
||||
# https://www.postgresql.org/docs/10/static/pgupgrade.html
|
||||
ohai "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed}..."
|
||||
services_json_output = Utils.popen_read(HOMEBREW_BREW_FILE, "services", "info", "--all", "--json")
|
||||
services_json = JSON.parse(services_json_output)
|
||||
loaded_service_names = services_json.select { |sj| sj[:loaded] }.map { |sj| sj[:name] }
|
||||
if loaded_service_names.include?(name)
|
||||
system HOMEBREW_BREW_FILE, "services", "stop", name
|
||||
service_stopped = true
|
||||
elsif quiet_system "#{bin}/pg_ctl", "-D", datadir, "status"
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "stop"
|
||||
server_stopped = true
|
||||
hide_from_man_page!
|
||||
end
|
||||
|
||||
# Shut down old server if it is up via brew services
|
||||
system HOMEBREW_BREW_FILE, "services", "stop", old_pg_name if loaded_service_names.include?(old_pg_name)
|
||||
sig { override.void }
|
||||
def run
|
||||
odisabled "brew postgresql_upgrade_database",
|
||||
"using new, versioned e.g. `var/postgres@14` datadir and `pg_upgrade`"
|
||||
|
||||
# get 'lc_collate' from old DB"
|
||||
unless quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "start"
|
||||
end
|
||||
name = "postgresql"
|
||||
pg = Formula[name]
|
||||
bin = pg.bin
|
||||
var = pg.var
|
||||
version = pg.version
|
||||
pg_version_file = var/"postgres/PG_VERSION"
|
||||
|
||||
initdb_args = T.let([], T::Array[String])
|
||||
locale_settings = %w[
|
||||
lc_collate
|
||||
lc_ctype
|
||||
lc_messages
|
||||
lc_monetary
|
||||
lc_numeric
|
||||
lc_time
|
||||
server_encoding
|
||||
]
|
||||
locale_settings.each do |setting|
|
||||
sql = "SELECT setting FROM pg_settings WHERE name LIKE '#{setting}';"
|
||||
value = Utils.popen_read("#{old_bin}/psql", "postgres", "-qtAX", "-U", ENV.fetch("USER"), "-c", sql).strip
|
||||
|
||||
next if value.empty?
|
||||
|
||||
initdb_args += if setting == "server_encoding"
|
||||
["-E #{value}"]
|
||||
else
|
||||
["--#{setting.tr("_", "-")}=#{value}"]
|
||||
pg_version_installed = version.to_s[/^\d+/]
|
||||
pg_version_data = pg_version_file.read.chomp
|
||||
if pg_version_installed == pg_version_data
|
||||
odie <<~EOS
|
||||
#{name} data already upgraded!
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
if quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "stop"
|
||||
end
|
||||
|
||||
ohai "Moving #{name} data from #{datadir} to #{old_datadir}..."
|
||||
FileUtils.mv datadir, old_datadir
|
||||
moved_data = true
|
||||
|
||||
(var/"postgres").mkpath
|
||||
ohai "Creating database..."
|
||||
safe_system "#{bin}/initdb", *initdb_args, "#{var}/postgres"
|
||||
initdb_run = true
|
||||
|
||||
ohai "Migrating and upgrading data..."
|
||||
(var/"log").cd do
|
||||
safe_system "#{bin}/pg_upgrade",
|
||||
"-r",
|
||||
"-b", old_bin,
|
||||
"-B", bin,
|
||||
"-d", old_datadir,
|
||||
"-D", datadir,
|
||||
"-j", Hardware::CPU.cores.to_s
|
||||
end
|
||||
upgraded = true
|
||||
|
||||
ohai "Upgraded #{name} data from #{pg_version_data} to #{pg_version_installed}!"
|
||||
ohai "Your #{name} #{pg_version_data} data remains at #{old_datadir}"
|
||||
ensure
|
||||
if upgraded
|
||||
if server_stopped
|
||||
safe_system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
safe_system HOMEBREW_BREW_FILE, "services", "start", name
|
||||
datadir = var/"postgres"
|
||||
old_datadir = var/"postgres.old"
|
||||
if old_datadir.exist?
|
||||
odie <<~EOS
|
||||
#{old_datadir} already exists!
|
||||
Remove it if you want to upgrade data automatically.
|
||||
EOS
|
||||
end
|
||||
else
|
||||
onoe "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed} failed!"
|
||||
if initdb_run
|
||||
ohai "Removing empty #{name} initdb database..."
|
||||
FileUtils.rm_r datadir
|
||||
|
||||
old_pg_name = "#{name}@#{pg_version_data}"
|
||||
old_pg_glob = "#{HOMEBREW_CELLAR}/#{old_pg_name}/#{pg_version_data}.*/bin"
|
||||
old_bin = Pathname.glob(old_pg_glob).first
|
||||
old_bin ||= begin
|
||||
Formula[old_pg_name]
|
||||
ohai "brew install #{old_pg_name}"
|
||||
system HOMEBREW_BREW_FILE, "install", old_pg_name
|
||||
Pathname.glob(old_pg_glob).first
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
end
|
||||
if moved_data
|
||||
ohai "Moving #{name} data back from #{old_datadir} to #{datadir}..."
|
||||
FileUtils.mv old_datadir, datadir
|
||||
end
|
||||
if server_stopped
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
system HOMEBREW_BREW_FILE, "services", "start", name
|
||||
|
||||
odie "No #{name} #{pg_version_data}.* version installed!" unless old_bin
|
||||
|
||||
server_stopped = T.let(false, T::Boolean)
|
||||
moved_data = T.let(false, T::Boolean)
|
||||
initdb_run = T.let(false, T::Boolean)
|
||||
upgraded = T.let(false, T::Boolean)
|
||||
|
||||
begin
|
||||
# Following instructions from:
|
||||
# https://www.postgresql.org/docs/10/static/pgupgrade.html
|
||||
ohai "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed}..."
|
||||
services_json_output = Utils.popen_read(HOMEBREW_BREW_FILE, "services", "info", "--all", "--json")
|
||||
services_json = JSON.parse(services_json_output)
|
||||
loaded_service_names = services_json.select { |sj| sj[:loaded] }.map { |sj| sj[:name] }
|
||||
if loaded_service_names.include?(name)
|
||||
system HOMEBREW_BREW_FILE, "services", "stop", name
|
||||
service_stopped = true
|
||||
elsif quiet_system "#{bin}/pg_ctl", "-D", datadir, "status"
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "stop"
|
||||
server_stopped = true
|
||||
end
|
||||
|
||||
# Shut down old server if it is up via brew services
|
||||
system HOMEBREW_BREW_FILE, "services", "stop", old_pg_name if loaded_service_names.include?(old_pg_name)
|
||||
|
||||
# get 'lc_collate' from old DB"
|
||||
unless quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "start"
|
||||
end
|
||||
|
||||
initdb_args = T.let([], T::Array[String])
|
||||
locale_settings = %w[
|
||||
lc_collate
|
||||
lc_ctype
|
||||
lc_messages
|
||||
lc_monetary
|
||||
lc_numeric
|
||||
lc_time
|
||||
server_encoding
|
||||
]
|
||||
locale_settings.each do |setting|
|
||||
sql = "SELECT setting FROM pg_settings WHERE name LIKE '#{setting}';"
|
||||
value = Utils.popen_read("#{old_bin}/psql", "postgres", "-qtAX", "-U", ENV.fetch("USER"), "-c",
|
||||
sql).strip
|
||||
|
||||
next if value.empty?
|
||||
|
||||
initdb_args += if setting == "server_encoding"
|
||||
["-E #{value}"]
|
||||
else
|
||||
["--#{setting.tr("_", "-")}=#{value}"]
|
||||
end
|
||||
end
|
||||
|
||||
if quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "stop"
|
||||
end
|
||||
|
||||
ohai "Moving #{name} data from #{datadir} to #{old_datadir}..."
|
||||
FileUtils.mv datadir, old_datadir
|
||||
moved_data = true
|
||||
|
||||
(var/"postgres").mkpath
|
||||
ohai "Creating database..."
|
||||
safe_system "#{bin}/initdb", *initdb_args, "#{var}/postgres"
|
||||
initdb_run = true
|
||||
|
||||
ohai "Migrating and upgrading data..."
|
||||
(var/"log").cd do
|
||||
safe_system "#{bin}/pg_upgrade",
|
||||
"-r",
|
||||
"-b", old_bin,
|
||||
"-B", bin,
|
||||
"-d", old_datadir,
|
||||
"-D", datadir,
|
||||
"-j", Hardware::CPU.cores.to_s
|
||||
end
|
||||
upgraded = true
|
||||
|
||||
ohai "Upgraded #{name} data from #{pg_version_data} to #{pg_version_installed}!"
|
||||
ohai "Your #{name} #{pg_version_data} data remains at #{old_datadir}"
|
||||
ensure
|
||||
if upgraded
|
||||
if server_stopped
|
||||
safe_system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
safe_system HOMEBREW_BREW_FILE, "services", "start", name
|
||||
end
|
||||
else
|
||||
onoe "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed} failed!"
|
||||
if initdb_run
|
||||
ohai "Removing empty #{name} initdb database..."
|
||||
FileUtils.rm_r datadir
|
||||
end
|
||||
if moved_data
|
||||
ohai "Moving #{name} data back from #{old_datadir} to #{datadir}..."
|
||||
FileUtils.mv old_datadir, datadir
|
||||
end
|
||||
if server_stopped
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
system HOMEBREW_BREW_FILE, "services", "start", name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cmd/postgresql-upgrade-database"
|
||||
require "cmd/shared_examples/args_parse"
|
||||
|
||||
RSpec.describe Homebrew::Cmd::PostgresqlUpgradeDatabase do
|
||||
it_behaves_like "parseable arguments"
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user