diff options
Diffstat (limited to 'run-upgrade-scripts')
-rwxr-xr-x | run-upgrade-scripts | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/run-upgrade-scripts b/run-upgrade-scripts new file mode 100755 index 0000000..aae3e90 --- /dev/null +++ b/run-upgrade-scripts @@ -0,0 +1,114 @@ +#!/usr/bin/perl -w +# Run all upgrade scripts. +# +# (C) 2005-2009 Martin Pitt <mpitt@debian.org> +# +# 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 PgCommon; + +error "Usage: $0 <version upgraded from>" if $#ARGV != 0; + +# Return the cluster's databases that match the given scope. +# Arguments: <version> <cluster> <scope> +sub dbs_from_scope { + my ($v, $c, $scope) = @_; + my @dbs = get_cluster_databases $v, $c; + unless (defined $dbs[0]) { + print ' Error: cluster is not running'; + return (); + } + + # filter out the postgres database + @dbs = grep { $_ ne 'postgres' } @dbs; + + return @dbs if $scope eq 't0'; + return grep { $_ ne 'template0' } @dbs if $scope eq 't1'; + return grep { $_ ne 'template0' && $_ ne 'template1' } @dbs if $scope eq 'db'; + return grep { $_ eq 'template1' } @dbs if $scope eq 'cluster'; +} + +# Arguments: <script> <scope> <version> <cluster> <database> +sub call_sql { + if (my $child = fork) { # parent + waitpid $child, 0; + return; + } + + # child code + my ($script, $scope, $version, $cluster, $db) = @_; + $cluster =~ s/'/''/g; # escape ' in cluster name + my $orig_euid = $>; + $< = $> = (stat (PgCommon::cluster_data_directory $version, $cluster))[4]; + + # temporarily enable connections + my $conallow = `psql --cluster '$version/$cluster' template1 -AXtqc "select datallowconn from pg_database where datname='$db'"`; + chomp $conallow; + if ($conallow eq 'f') { + system "psql --cluster '$version/$cluster' template1 -AXtqc \"update pg_database set datallowconn = 't' where datname='$db'\""; + } + + my $out = `ON_ERROR_STOP=1 psql --cluster '$version/$cluster' -f '$script' '$db' 2>&1`; + + # reset allowconn + if ($conallow eq 'f') { + system "psql --cluster '$version/$cluster' template1 -AXtqc \"update pg_database set datallowconn = 'f' where datname='$db'\""; + } + print "[FAIL]\n$out" if $?; + + exit 0; +} + +# Arguments: <script> <scope> <version> <cluster> <database> +sub call_script { + my ($script, $scope, $version, $cluster, $db) = @_; + $cluster =~ s/'/\\'/g; # escape ' in cluster name + my $out = `$script '$version' '$cluster' '$db' 2>&1`; + print "[FAIL]\n$out" if $?; +} + +my $upgraded_version = $ARGV[0]; + +# determine path of upgrade scripts +my @f = split(/\//, $0); +pop @f; +@f = ('.') if $#f == -1; +push @f, 'upgrade-scripts'; +my $scriptpath = join ('/', @f); + +opendir S, $scriptpath or error "Could not open script path '$scriptpath'"; +for my $script (sort readdir S) { + my ($fname, $ext) = split /\./, $script; + my ($version, $name, $scope) = split /_/, $fname; + my $is_sql = (defined $ext && $ext eq 'sql'); + next unless defined ($scope) && ($is_sql || -x "$scriptpath/$script"); + + next unless ($version eq 'all' || $upgraded_version <= $version); + print "Executing upgrade script $name...\n"; + + for my $v (get_versions) { + for my $c (get_version_clusters $v) { + print " cluster $v/$c:"; + for my $db (dbs_from_scope $v, $c, $scope) { + print " $db"; + if ($is_sql) { + call_sql "$scriptpath/$script", $scope, $v, $c, $db; + } else { + call_script "$scriptpath/$script", $scope, $v, $c, $db; + } + } + print "\n"; + } + } + +} +closedir S; |