From e308bcff5a610d6a3bbe33b3769f03f6d4533b16 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:02:19 +0200 Subject: Adding upstream version 248. Signed-off-by: Daniel Baumann --- pg_renamecluster | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 pg_renamecluster (limited to 'pg_renamecluster') diff --git a/pg_renamecluster b/pg_renamecluster new file mode 100755 index 0000000..b8e66c6 --- /dev/null +++ b/pg_renamecluster @@ -0,0 +1,176 @@ +#!/usr/bin/perl -wT + +# Rename a PostgreSQL cluster +# +# (C) 2014-2021 Christoph Berg +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +use strict; +use warnings; +use PgCommon; +use Getopt::Long; +use POSIX; + +# untaint environment +$ENV{'PATH'} = '/bin:/usr/bin'; +delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; + +if (@ARGV != 3) { + print "Usage: $0 [OPTIONS] \n"; + exit 1; +} + +my ($version) = $ARGV[0] =~ /^(\d+\.?\d+)$/; +my ($oldcluster) = $ARGV[1] =~ /^([-.\w]+)$/; +my ($newcluster) = $ARGV[2] =~ /^([-.\w]+)$/; +if ($newcluster =~ /-/ and -t 1) { + print "Warning: cluster names containing dashes (-) will cause problems when running from systemd. Continuing anyway\n"; +} + +error "Old and new name must be different" + if ($oldcluster eq $newcluster); +error "specified cluster $version $oldcluster does not exist" + unless (cluster_exists $version, $oldcluster); +error "target cluster $version $newcluster already exists" + if (cluster_exists $version, $newcluster); +my %info = cluster_info ($version, $oldcluster); +validate_cluster_owner \%info; + +# stopping old cluster, so that we notice early when there are still +# connections +if ($info{'running'}) { + print "Stopping cluster $version $oldcluster ...\n"; + my @argv = ('pg_ctlcluster', $version, $oldcluster, 'stop'); + error "Could not stop cluster" if system @argv; +} + +# Arguments: , , +sub strrepl { + my ($s, $f, $t) = @_; + $s =~ s/\b\Q$f\E\b/$t/g; + return $s; +} + +# rename config directory +my $olddir = "$PgCommon::confroot/$version/$oldcluster"; +my $newdir = "$PgCommon::confroot/$version/$newcluster"; +rename $olddir, $newdir or error "Could not rename config directory $olddir: $!"; + +# adapt paths to configuration files +my %c = read_cluster_conf_file $version, $newcluster, 'postgresql.conf'; +if ($c{hba_file}) { + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', 'hba_file', + strrepl($c{hba_file}, $oldcluster, $newcluster); +} +if ($c{ident_file}) { + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', 'ident_file', + strrepl($c{ident_file}, $oldcluster, $newcluster); +} +if ($c{external_pid_file}) { + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', 'external_pid_file', + strrepl($c{external_pid_file}, $oldcluster, $newcluster); +} + +# update cluster_name +if ($c{cluster_name}) { + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', 'cluster_name', + strrepl ($c{cluster_name}, $oldcluster, $newcluster); +} + + +# rename data directory +if ($info{pgdata}) { + my $newpgdata = strrepl ($info{pgdata}, $oldcluster, $newcluster); + if ($info{pgdata} ne $newpgdata) { + rename $info{pgdata}, $newpgdata or + error "Could not rename data directory $info{pgdata}: $!"; + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', + 'data_directory', $newpgdata; + } +} + +# rename stats_temp_directory +my $statstempdir = $info{config}->{stats_temp_directory}; +if ($statstempdir) { + my $newstatstempdir = strrepl ($statstempdir, $oldcluster, $newcluster); + if ($statstempdir ne $newstatstempdir) { + PgCommon::set_conf_value $version, $newcluster, 'postgresql.conf', + 'stats_temp_directory', $newstatstempdir; + if (-d $statstempdir) { + rename $statstempdir, $newstatstempdir or + error "Could not rename stats temp directory $statstempdir}: $!"; + } + } +} + +# rename old log files +my $logdir = "/var/log/postgresql"; +if (opendir LOG, $logdir) { + while (my $logfile = readdir LOG) { + next unless $logfile =~ /^(\Qpostgresql-$version-$oldcluster.log\E.*)/; + $logfile = $1; # untaint + my $f = strrepl ($logfile, $oldcluster, $newcluster); + rename "$logdir/$logfile", "$logdir/$f" or error "rename $logdir/$logfile: $!"; + } + closedir LOG; +} + +# notify systemd about the new cluster +if (not exists $ENV{'PG_CLUSTER_CONF_ROOT'} and -d '/run/systemd/system') { + if ($> == 0) { + system 'systemctl daemon-reload'; + } elsif (-t 1) { + print "Warning: systemd does not know about the new cluster yet. Operations like \"service postgresql start\" will not handle it. To fix, run:\n"; + print " sudo systemctl daemon-reload\n"; + } +} + +# start cluster if it was running before +if ($info{'running'}) { + print "Starting cluster $version $newcluster ...\n"; + my @argv = ('pg_ctlcluster', $version, $newcluster, 'start'); + error "Could not start cluster" if system @argv; +} + +__END__ + +=head1 NAME + +pg_renamecluster - rename a PostgreSQL cluster + +=head1 SYNOPSIS + +B I I I + +=head1 DESCRIPTION + +B changes the name of a PostgreSQL cluster, i. e. the name of +the config directory in /etc/postgresql/I/ along with the data +directory in /var/lib/postgresql/I/. Existing log files in +/var/log/postgresql/ are also renamed. The cluster is stopped and started for +the operation. + +The following B config options are updated to refer to the +changed path names: B, B, B, +B, B, B. + +=head1 OPTIONS + +None. + +=head1 SEE ALSO + +L, L, L, L + +=head1 AUTHOR + +Christoph Berg Lmyon@debian.orgE> -- cgit v1.2.3