summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Raiskup <praiskup@redhat.com>2015-02-24 13:37:52 +0100
committerPavel Raiskup <praiskup@redhat.com>2015-02-25 13:26:07 +0100
commit243dcab83ed93c3afd9867b3e5d014efdd0f840f (patch)
tree64186eb94b62cc4f9e071e7dbd439d7c923ab1da
parentcc56924c20a4081880f86165c03e03323522cacd (diff)
downloadpostgresql-setup-243dcab83ed93c3afd9867b3e5d014efdd0f840f.tar.gz
postgresql-setup-243dcab83ed93c3afd9867b3e5d014efdd0f840f.tar.xz
postgresql-setup-243dcab83ed93c3afd9867b3e5d014efdd0f840f.zip
postgresql-setup: multi-upgrade configuration
Turns out we need to support upgrade from more than one previous database versions. The plan is to make this as general as easily possible, "run-time" configurable without need to recompile. * postgresql-setup.in: Add options --upgrade-from and --upgrade-ids. Require root access (as late as possible). ($USAGE_STRING): Adjust help output accordingly. ($PGMAJORVERSION, $PREVMAJORVERSION) ($PREVPGENGINE): Remove newly useless globals. ($option_upgradefrom): New option default. (set_var, root_prereq): New helper functions. (parse_upgrade_setup): Helper function to parse upgrade configuration. (print_version): Don't print PREVMAJORVERSION as it is (with configuration) useless. (upgrade): Create new $inplace local to handle in-place and copy-like migrations differently. Use the variable set generated by parse_upgrade_setup() function. Small err message fixes. (handle_service_env, handle_pgconf): Remove the MODE argument. (parse_configuration): Generalize operations which needed to be done on two places. * upgrade_config.template: Example of ./configure time config file. Based on files like this the run-time is generated. * share/postgresql-setup/.gitignore: New file. * share/postgresql-setup/Makefile.inc: New file. * build-helpers/build-config: New file, generator of configuration files. * build-helpers/Makefile.inc: New file. * Makefile.am: Distribute upgrade_config.template. Start the conversion to flat Makefile and include two new Makefile.inc snippets. * configure.ac: New --with-upgrade-config option. Propagate the rawpkgdatadir and UPGRADE_CONFIG_LIST variables into Makefile. (INSTANTIATE): Enhance to create the leading path also. (INSTANTIATE_CONV): Convenience helper for leading path of target creation. * auxdir/install_local: New (just-for-git) installation helper. * .gitignore: Don't hide share/postgresql-setup. * TODO: Mention that KDE folks would like to migrate somehow.
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am10
-rw-r--r--TODO2
-rwxr-xr-xauxdir/install_local10
-rw-r--r--build-helpers/Makefile.inc7
-rwxr-xr-xbuild-helpers/build-config11
-rw-r--r--configure.ac16
-rw-r--r--postgresql-setup.in220
-rw-r--r--share/postgresql-setup/.gitignore1
-rw-r--r--share/postgresql-setup/Makefile.inc16
-rw-r--r--upgrade_config.template16
11 files changed, 253 insertions, 58 deletions
diff --git a/.gitignore b/.gitignore
index 2c74bc7..40c1e13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,7 +19,7 @@ package.m4
postgresql*-check-db-dir
postgresql*-ctl
postgresql*.service
-postgresql*-setup
+/postgresql*-setup
postgresql*-setup.1
README.rpm-dist
testsuite
diff --git a/Makefile.am b/Makefile.am
index d303110..bf0cb60 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,9 @@
pkgname = postgresql$(DISTSUFF)
+EXTRA_DIST =
+
+include $(srcdir)/build-helpers/Makefile.inc
+
SUBDIRS = . doc tests
bin_SCRIPTS = postgresql$(DISTSUFF)-setup
@@ -57,7 +61,9 @@ postgresql$(DISTSUFF).service: postgresql.service.in $(c_s)
$(README_DIST_BASENAME): $(README_DIST_BASENAME).in $(c_s)
$(INSTANTIATE)
-EXTRA_DIST = $(srcdir)/*.in
+EXTRA_DIST += \
+ $(srcdir)/*.in \
+ upgrade_config.template
GENERATED_FILES = $(bin_SCRIPTS) \
$(libexec_SCRIPTS) \
@@ -69,6 +75,8 @@ GENERATED_FILES = $(bin_SCRIPTS) \
CLEANFILES = $(GENERATED_FILES) $(TEST_GEN_FILES_LIST)
+include $(srcdir)/share/postgresql-setup/Makefile.inc
+
$(TEST_GEN_FILES_LIST): $(GENERATED_FILES)
$(AM_V_GEN)rm -rf $(TEST_GEN_FILES_LIST) && \
for i in $(GENERATED_FILES); do \
diff --git a/TODO b/TODO
index 989138c..8e234d4 100644
--- a/TODO
+++ b/TODO
@@ -20,3 +20,5 @@
* build system
- generate the binary scripts outside '$(srcdir)' as maintainer tends to
edit generated file instead its '*.in' parent
+
+* Allow guys from KDE upgrade the PG stack somehow.
diff --git a/auxdir/install_local b/auxdir/install_local
new file mode 100755
index 0000000..1c06a6e
--- /dev/null
+++ b/auxdir/install_local
@@ -0,0 +1,10 @@
+#! /bin/bash
+
+source <(cat config.status | grep ^ac_cs_config)
+
+./configure --prefix=/usr --with-upgrade-config=upgrade_config.template \
+ && make clean \
+ && make \
+ && sudo make install
+
+eval "./configure $ac_cs_config"
diff --git a/build-helpers/Makefile.inc b/build-helpers/Makefile.inc
new file mode 100644
index 0000000..d54d239
--- /dev/null
+++ b/build-helpers/Makefile.inc
@@ -0,0 +1,7 @@
+config_builder = $(top_srcdir)/%D%/build-config
+
+noinst_SCRIPT = $(config_builder)
+
+EXTRA_DIST += $(noinst_SCRIPT)
+
+# vim: ft=automake noet
diff --git a/build-helpers/build-config b/build-helpers/build-config
new file mode 100755
index 0000000..27841f2
--- /dev/null
+++ b/build-helpers/build-config
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+# For easier parsing in postgresql-setup, we want to have each upgrade scenario
+# configured on separate line.
+
+eval set -- "$1"
+while test -n "$1"
+do
+ echo $(cat "$1" | grep -v ^# )
+ shift
+done
diff --git a/configure.ac b/configure.ac
index a793a07..d6476f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,6 +27,15 @@ AC_ARG_WITH([sysvinit],
[WANT_SYSVINIT=0]
)
+AC_ARG_WITH([upgrade-config],
+ AS_HELP_STRING([--with-upgrade-config=/file/path,/path2],
+ [List of files to be used as an upgrade configuration]),
+ [UPGRADE_CONFIG_LIST="$withval"],
+ [UPGRADE_CONFIG_LIST="upgrade_config.template"]
+)
+
+AC_SUBST([UPGRADE_CONFIG_LIST])
+
AM_CONDITIONAL([WANT_SYSVINIT], [test "$WANT_SYSVINIT" -eq 1])
# Instatiating generated files by sed instead of config.status.
@@ -54,23 +63,28 @@ sed_subst_var_pattern(pkgname)
sed_subst_var_pattern(POSTGRES_HOMEDIR)
sed_subst_var_pattern(PREVMAJORVERSION)
sed_subst_var_pattern(PREVPGENGINE)
+sed_subst_var_pattern(rawpkgdatadir)
sed_subst_var_pattern(README_DIST)
sed_subst_var_pattern(SU_POSTGRES)
sed_subst_var_pattern(systemdunitsdir)
sed_subst_var_pattern(userunitsdir)
sed_subst_var_pattern(TEST_GEN_FILES_LIST)
sed_subst_var_pattern(VERSION)
+sed_subst_var_pattern(UPGRADE_CONFIG_LIST)
-e 's|@__FILE__[[@]]|\$@|g'"
SED_CALL="\$(SED) \$(SED_RULES)"
m4_pattern_allow(AM_V_GEN)
-INSTANTIATE="\$(AM_V_GEN)\$(SED_CALL) \$< > \$@"
+
+INSTANTIATE_CONV="\$(AM_V_GEN)rm -rf \$@; \$(MKDIR_P) \$(@D)"
+INSTANTIATE="\$(INSTANTIATE_CONV) && \$(SED_CALL) \$< > \$@ && chmod -w \$@"
INSTANTIATE_SCRIPT="\$(INSTANTIATE) && chmod +x \$@"
c_s='$(top_builddir)/config.status'
AC_SUBST([SED_RULES])
AC_SUBST([SED_CALL])
AC_SUBST([INSTANTIATE])
+AC_SUBST([INSTANTIATE_CONV])
AC_SUBST([INSTANTIATE_SCRIPT])
AC_SUBST([c_s])
diff --git a/postgresql-setup.in b/postgresql-setup.in
index 4940da1..43294f9 100644
--- a/postgresql-setup.in
+++ b/postgresql-setup.in
@@ -6,18 +6,9 @@ test -z "$PATH" && export PATH="/sbin:/usr/sbin:/bin:/usr/bin"
test x"$PGSETUP_DEBUG" != x && set -x && PS4='${LINENO}: '
-# Major version of PostgreSQL, e.g. 9.0
-PGMAJORVERSION=@PGMAJORVERSION@
-
# Directory containing the postmaster executable
PGENGINE=@PGENGINE@
-# Previous major version, e.g., 8.4, for upgrades
-PREVMAJORVERSION=@PREVMAJORVERSION@
-
-# Directory containing the previous postmaster executable
-PREVPGENGINE=@PREVPGENGINE@
-
# Distribution README file
README_DIST=@README_DIST@
@@ -30,6 +21,8 @@ SU_POSTGRES="@SU_POSTGRES@"
# The where PostgreSQL server listens by default
PGPORT_DEF=5432
+option_upgradefrom="postgresql"
+
USAGE_STRING=$"\
Usage: $0 MODE_OPTION [--unit=UNIT_NAME] [OPTION...]
@@ -44,8 +37,7 @@ Available operation mode:
--initdb Create a new PostgreSQL database cluster. This is usually the
first action you perform after PostgreSQL server installation.
--upgrade Upgrade database cluster for new major version of PostgreSQL
- server. This installation is configured to perform upgrade
- from $PREVMAJORVERSION.X to $PGMAJORVERSION.X.
+ server. See the --upgrade-from option for more info.
Options:
--unit=UNIT_NAME The UNIT_NAME is used to select proper systemd's
@@ -56,11 +48,18 @@ Options:
explicitly passed, the 'postgresql' string is used
by default.
--port=PORT port where the server will listen for connections
- --datadir=PATH specify absolute path to DB data directory
+ --datadir=PATH Specify absolute path to DB data directory, only
+ use with --new-systemd-unit.
--new-systemd-unit Pre-generate system'd configuration in drop-in
directory if the unit is not yet configured,
requires non-default --unit specified and explicit
--datadir and --port.
+ --upgrade-ids Print list of available IDs of upgrade scenarios to
+ standard output.
+ --upgrade-from=ID Specify id \"old\" postgresql stack to upgrade
+ from. List of available IDs can be listed by
+ --upgrade-ids. Default is '$option_upgradefrom'.
+
Other options:
--help show this help
--version show version of this package
@@ -90,11 +89,73 @@ info_q() { echo >&2 $" $@" ; }
debug() { test "$option_debug" = "1" && echo >&2 $"DEBUG: $@"; }
+set_var()
+{
+ # TODO compare implementation with other tools.
+ eval "$1=\"$2\""
+}
+
+
+root_prereq()
+{
+ test "$(id -u)" -eq 0 || die "$0 requires root access for this action"
+}
+
+parse_upgrade_setup()
+{
+ local action="$1"
+ local expected_id="$2"
+ local id temp_major temp_engine temp_data_default temp_description
+
+ while read line; do
+ eval set -- "$line --"
+
+ id="$1"
+ shift
+
+ while true; do
+ case "$1" in
+ --)
+ break
+ ;;
+ major|engine|data_default|description)
+ set_var "temp_$1" "$2"
+ shift 2
+ ;;
+ *)
+ die "unused upgrade config option '$1'"
+ ;;
+ esac
+ done
+
+ case "$action" in
+ help)
+ echo "$id - $temp_description"
+ ;;
+ config)
+ test "$id" = "$expected_id" || continue
+ for i in major engine data_default description; do
+ set_var "upgradefrom_$i" "\$temp_$i"
+ done
+ debug "used configuration '$id', $upgradefrom_engine"
+ return 0
+ ;;
+ esac
+ done < "@rawpkgdatadir@/upgrade.conf"
+
+ case "$action" in
+ help)
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+
print_version()
{
echo "postgresql@DISTSUFF@-setup @VERSION@"
- echo $"Built against PostgreSQL version @PGVERSION@ and configured"
- echo $"to upgrade from PostgreSQL version @PREVMAJORVERSION@.X."
+ echo $"Built against PostgreSQL version @PGVERSION@."
}
@@ -175,12 +236,18 @@ initdb()
upgrade()
{
+ local inplace=false
+ test "$pgdata" = "$upgradefrom_data" && inplace=true
+
+ debug "running inplace upgrade: $inplace"
+
# must see previous version in PG_VERSION
- if [ ! -f "$pgdata/PG_VERSION" -o \
- x`cat "$pgdata/PG_VERSION"` != x"$PREVMAJORVERSION" ]
+ local old_data_version="`cat "$upgradefrom_data/PG_VERSION"`"
+ if [ ! -f "$upgradefrom_data/PG_VERSION" -o \
+ x"$old_data_version" != x"$upgradefrom_major" ]
then
- error $"Cannot upgrade because the database in $pgdata is not of"
- error_q $"compatible previous version $PREVMAJORVERSION."
+ error $"Cannot upgrade because the database in $upgradefrom_data is of"
+ error_q $"version $old_data_version but it should be $upgradefrom_major"
exit 1
fi
if [ ! -x "$PGENGINE/pg_upgrade" ]; then
@@ -190,15 +257,21 @@ upgrade()
# Set up log file for pg_upgrade
rm -f "$upgrade_log"
- touch "$upgrade_log" || exit 1
+ touch "$upgrade_log" || die "can't write into $upgrade_log file"
+
chown postgres:postgres "$upgrade_log"
chmod go-rwx "$upgrade_log"
[ -x /sbin/restorecon ] && /sbin/restorecon "$upgrade_log"
# Move old DB to pgdataold
- pgdataold="${pgdata}-old"
- rm -rf "$pgdataold"
- mv "$pgdata" "$pgdataold" || exit 1
+
+ if $inplace; then
+ pgdataold="${pgdata}-old"
+ rm -rf "$pgdataold"
+ mv "$pgdata" "$pgdataold" || exit 1
+ else
+ pgdataold="$upgradefrom_data"
+ fi
# Create configuration file for upgrade process
HBA_CONF_BACKUP="$pgdataold/pg_hba.conf.postgresql-setup.`date +%s`"
@@ -220,7 +293,7 @@ upgrade()
if perform_initdb; then
# Do the upgrade
$SU_POSTGRES -c "$PGENGINE/pg_upgrade \
- '--old-bindir=$PREVPGENGINE' \
+ '--old-bindir=$upgradefrom_engine' \
'--new-bindir=$PGENGINE' \
'--old-datadir=$pgdataold' \
'--new-datadir=$pgdata' \
@@ -249,9 +322,9 @@ upgrade()
warn $"The previous configuration and data are stored in folder"
warn $pgdataold.
else
- # Clean up after failure
+ # Clean up after failure.
rm -rf "$pgdata"
- mv "$pgdataold" "$pgdata"
+ $inplace && mv "$pgdataold" "$pgdata"
error $"failed"
fi
info $"See $upgrade_log for details."
@@ -284,8 +357,7 @@ EOF
handle_service_env()
{
- local mode="$1"
- local service="$2"
+ local service="$1"
local systemd_env="$(systemctl show -p Environment "${service}.service")" \
|| { return; }
@@ -345,12 +417,9 @@ handle_service_envfiles()
handle_pgconf()
{
- local mode="$1"
- local datadir="$2"
+ local datadir="$1"
local conffile="$datadir/postgresql.conf"
- test "$mode" = initdb && return 0
-
debug "postgresql.conf: $conffile"
test -r "$conffile" || {
@@ -368,6 +437,41 @@ handle_pgconf()
}
+parse_configuration()
+{
+ local data=
+ local port=
+ local unit_pgport=
+ local unit_pgdata=
+ local envfile_pgport=
+ local envfile_pgdata=
+ local mode="$1" datavar="$2" portvar="$3" service="$4"
+
+ debug "running parse_configuration() for $mode"
+
+ # Well, until the bug #1139148 is not resolved somehow, we need to stay ugly
+ # and parse Environment= and EnvironmentFile= statements.
+ local service="$service"
+ test upgrade = "$mode" && service="$option_upgradefrom"
+
+ handle_service_env "$service"
+ handle_service_envfiles "$option_mode" "$service"
+
+ test -n "$unit_pgdata" && set_var "$datavar" "$unit_pgdata"
+ test -n "$envfile_pgdata" && set_var "$datavar" "$envfile_pgdata"
+
+ # skip for the first run
+ test initdb = "$mode" && return
+
+ set_var data "\$$datavar"
+ handle_pgconf "$data"
+
+ test -n "$conf_pgport" && set_var "$portvar" "$conf_pgport"
+ test -n "$unit_pgport" && set_var "$portvar" "$unit_pgport"
+ test -n "$envfile_pgport" && set_var "$portvar" "$envfile_pgport"
+}
+
+
# <Compat>
# Alow users to use the old style arguments like
# 'postgresql-setup initdb $SERVICE_NAME'.
@@ -436,8 +540,8 @@ pgport=default
short_opts=""
long_opts="\
initdb,upgrade,\
-new-systemd-unit,\
-unit:,service:,port:,datadir:,\
+new-systemd-unit,upgrade-ids,\
+unit:,service:,port:,datadir:,upgrade-from:,\
debug,\
version,help,usage"
@@ -487,6 +591,16 @@ while true; do
exit 0
;;
+ --upgrade-from)
+ option_upgradefrom="$2"
+ shift 2
+ ;;
+
+ --upgrade-ids)
+ parse_upgrade_setup help
+ exit 0
+ ;;
+
--version)
print_version
exit 0
@@ -509,6 +623,12 @@ test $parse_fail -ne 0 && die "can't parse arguments"
test "$option_mode" = none \
&& die "no mode specified, use --initdb or --upgrade, or --help"
+if ! parse_upgrade_setup config "$option_upgradefrom"; then
+ if test upgrade = "$option_mode"; then
+ die $"bad --upgrade-from parameter '$option_upgradefrom'"
+ fi
+fi
+
## GATHER THE SETUP FIRST ##
initdb_log="$POSTGRES_HOMEDIR/initdb_${option_service}.log"
@@ -517,16 +637,10 @@ upgrade_log="$POSTGRES_HOMEDIR/upgrade_${option_service}.log"
debug "mode used: $option_mode"
debug "service name: $option_service"
-# Well, until the bug #1139148 is not resolved somehow, we need to stay ugly
-# and parse Environment= and EnvironmentFile= statements.
-handle_service_env "$option_mode" "$option_service"
-handle_service_envfiles "$option_mode" "$option_service"
+root_prereq
-## DEAL WITH PGDATA ##
-
-# EnvironmentFile has bigger priority then Environment in systemd
-test -n "$unit_pgdata" && pgdata="$unit_pgdata"
-test -n "$envfile_pgdata" && pgdata="$envfile_pgdata"
+# load service's pgdata
+parse_configuration initdb pgdata UNUSED "$option_service"
# Check that nothing breaks --new-systemd-unit
if test "$option_systemd_config" = yes; then
@@ -534,7 +648,7 @@ if test "$option_systemd_config" = yes; then
die $"Default unit 'postgresql.service' should not need --new-systemd-unit"
elif test "$pgdata" != default; then
die $"Option --new-systemd-unit failed, is '$option_service.service'"\
- $"already configured?"
+ $"already configured to '$pgdata'?"
elif test -z "$option_pgdata"; then
die $"Option --new-systemd-unit requires --datadir"
fi
@@ -558,18 +672,14 @@ test "$option_systemd_config" = yes \
## GATHER DATA FROM INITIALIZED DATADIR ##
-# for upgrade only
-handle_pgconf "$option_mode" "$pgdata" || die "can not parse postgresql.conf"
-
-## DEAL WITH PGPORT ##
-
test -n "$option_port" && pgport=$option_port
-test -n "$conf_pgport" && pgport="$conf_pgport"
-test -n "$unit_pgport" && pgport="$unit_pgport"
-test -n "$envfile_pgport" && pgport="$envfile_pgport"
-test -n "$option_port" -a "$option_port" != "$pgport" \
- && warn $"--pgport ignored, by configuration pgport='$pgport'"
+if test upgrade = "$option_mode"; then
+ upgradefrom_data="$upgradefrom_data_default"
+ parse_configuration upgrade upgradefrom_data pgport "$option_upgradefrom"
+ test -n "$option_port" -a "$option_port" != "$pgport" \
+ && warn "Old pgport $pgport has bigger priority than --pgport value."
+fi
# We expect that for upgrade - the previous stack was in working state (thus
# running on the default port).
@@ -577,8 +687,8 @@ test "$option_mode" = upgrade -a "$pgport" = default \
&& pgport=$PGPORT_DEF
# This is mostly for 'initdb'. We assume that the default port is $PGPORT_DEF
-# if not set explicitly (only for default service name 'postgresql').
-if test "$pgport" = default -a $option_service == postgresql; then
+# if not set explicitly for default service name 'postgresql'.
+if test "$pgport" = default -a "$option_service" = postgresql; then
debug $"Using the default port '$PGPORT_DEF'"
pgport=$PGPORT_DEF
fi
diff --git a/share/postgresql-setup/.gitignore b/share/postgresql-setup/.gitignore
new file mode 100644
index 0000000..d9c09a5
--- /dev/null
+++ b/share/postgresql-setup/.gitignore
@@ -0,0 +1 @@
+upgrade.conf
diff --git a/share/postgresql-setup/Makefile.inc b/share/postgresql-setup/Makefile.inc
new file mode 100644
index 0000000..d202fc6
--- /dev/null
+++ b/share/postgresql-setup/Makefile.inc
@@ -0,0 +1,16 @@
+upgrade_config = %D%/upgrade.conf
+
+rawpkgdatadir = $(datadir)/postgresql-setup
+rawpkgdata_DATA = \
+ $(upgrade_config)
+
+$(UPGRADE_CONFIG_LIST):
+ @echo " error: config file '$@' does not exist" && false
+
+$(upgrade_config): $(UPGRADE_CONFIG_LIST) $(c_s)
+ $(INSTANTIATE_CONV) \
+ && $(config_builder) "$(UPGRADE_CONFIG_LIST)" > $@
+
+GENERATED_FILES += $(upgrade_config)
+
+# vim: ft=automake noet
diff --git a/upgrade_config.template b/upgrade_config.template
new file mode 100644
index 0000000..4ce2bd9
--- /dev/null
+++ b/upgrade_config.template
@@ -0,0 +1,16 @@
+# Consider those are to shell strings, so wrap those by quotes when needed
+
+# ID
+postgresql
+
+# Version of the previous stack
+major 9.2
+
+# Location of default data
+data_default "/var/lib/pgsql/data"
+
+# Location of binaries
+engine /usr/bin
+
+# Just to feed ./postgresql-setup --upgrade-ids help output
+description "In-place upgrade from Fedora 19 (PostgreSQL 9.2)"