blob: 9bfbd1001dcae4bbe7f7e60bab9a5681f6545001 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
#!/bin/bash
# Create a throw-away PostgreSQL environment for running regression tests.
# This does not interfere with existing clusters.
#
# (C) 2005-2012 Martin Pitt <mpitt@debian.org>
# (C) 2012-2017 Christoph Berg <myon@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.
set -e # no -u here as that breaks PGCONF_OPTS[@]
# wrap ourselves in newpid if requested
if [ "$PG_VIRTUALENV_NEWPID" ]; then
unset PG_VIRTUALENV_NEWPID
exec newpid $0 "$@"
fi
# wrap ourselves in unshare if requested
if [ "$PG_VIRTUALENV_UNSHARE" ]; then
export _PG_VIRTUALENV_UNSHARE="$PG_VIRTUALENV_UNSHARE"
unset PG_VIRTUALENV_UNSHARE
exec unshare $_PG_VIRTUALENV_UNSHARE -- $0 "$@"
fi
if [ "$_PG_VIRTUALENV_UNSHARE" ]; then
unset _PG_VIRTUALENV_UNSHARE
# start localhost interface
if [ -x /bin/ip ]; then
ip link set dev lo up || true
else
ifconfig lo up || true
fi
fi
help ()
{
echo "pg_virtualenv: Create throw-away PostgreSQL environment for regression tests"
echo "Syntax: $0 [options] [command]"
echo " -a use all installed server versions"
echo " -v 'version ...' list of PostgreSQL versions to run [default: latest]"
echo " -c 'options' extra options to pass to pg_createcluster"
echo " -i 'initdb opts' extra initdb options to pass to pg_createcluster"
echo " -o 'guc=value' postgresql.conf options to pass to pg_createcluster"
echo " -s open a shell when command fails"
echo " -t use a temporary cluster directory even as root"
exit ${1:-0}
}
# option parsing
PGBINROOT="/usr/lib/postgresql/"
#redhat# PGBINROOT="/usr/pgsql-"
PG_VERSIONS=""
PGCONF_OPTS=()
while getopts "ac:i:ho:stv:" opt ; do
case $opt in
a) for d in $PGBINROOT*/bin/pg_ctl; do
# prepend version so latest ends up first (i.e. on port 5432)
dir=${d%%/bin/pg_ctl}
PG_VERSIONS="${dir#$PGBINROOT} ${PG_VERSIONS:-}"
done ;;
c) CREATE_OPTS="$OPTARG" ;;
i) INITDB_OPTS="$OPTARG" ;;
h) help ;;
o) PGCONF_OPTS+=("--pgoption" "$OPTARG") ;;
s) run_shell=1 ;;
t) NONROOT=1 ;;
v) PG_VERSIONS="$OPTARG" ;;
*) help 1 ;;
esac
done
if [ -z "$PG_VERSIONS" ]; then
# use latest version
d=$(ls -v $PGBINROOT*/bin/pg_ctl 2> /dev/null | tail -1)
if [ -z "$d" ]; then
echo "Could not determine PostgreSQL version, are any PostgreSQL server packages installed?" >&2
exit 2
fi
dir=${d%%/bin/pg_ctl}
PG_VERSIONS="${dir#$PGBINROOT}"
fi
# shift away args
shift $(($OPTIND - 1))
# if no command is given, open a shell
[ "${1:-}" ] || set -- ${SHELL:-/bin/sh}
# generate a password
if [ -x /usr/bin/pwgen ]; then
export PGPASSWORD=$(pwgen 20 1)
else
export PGPASSWORD=$(dd if=/dev/urandom bs=1k count=1 2>/dev/null | md5sum - | awk '{ print $1 }')
fi
# we are not root
if [ "$(id -u)" != 0 ]; then
NONROOT=1
fi
# we aren't really root in fakeroot
case ${LD_PRELOAD:-} in
*fakeroot*) NONROOT=1 ;;
esac
# non-root operation: create a temp dir where we store everything
if [ "${NONROOT:-}" ]; then
WORKDIR=$(mktemp -d -t pg_virtualenv.XXXXXX)
if [ $(id -u) = 0 ]; then
chown postgres:postgres $WORKDIR
umask 022
fi
export PG_CLUSTER_CONF_ROOT="$WORKDIR/postgresql"
export PGUSER="${USER:-${LOGNAME:-$(id -un)}}"
[ "$PGUSER" = "root" ] && PGUSER="postgres"
PGSYSCONFDIR="$WORKDIR/postgresql-common" # no export yet so pg_createcluster uses the original createcluster.conf
mkdir "$PGSYSCONFDIR" "$WORKDIR/log"
PWFILE="$PGSYSCONFDIR/pwfile"
LOGDIR="$WORKDIR/log"
echo "$PGPASSWORD" > "$PWFILE"
cleanup () {
set +e
for v in $PG_VERSIONS; do
# don't drop existing clusters named "regress"
[ -f $PG_CLUSTER_CONF_ROOT/$v/regress/.by_pg_virtualenv ] || continue
echo "Dropping cluster $v/regress ..."
pg_ctlcluster --mode immediate $v regress stop
done
rm -rf $WORKDIR
}
trap cleanup 0 HUP INT QUIT ILL ABRT PIPE TERM
# root: keep everything in the standard locations
else
for v in $PG_VERSIONS; do
if [ -d /etc/postgresql/$v/regress ]; then
echo "Cluster $v/regress exists, refusing to overwrite" >&2
exit 2
fi
done
: ${PGSYSCONFDIR:=/etc/postgresql-common}
pg_service="$PGSYSCONFDIR/pg_service.conf"
export PGUSER="postgres"
PWFILE=$(mktemp -t pgpassword.XXXXXX)
echo "$PGPASSWORD" > "$PWFILE" # write password before chowning the file
chown postgres:postgres "$PWFILE"
cleanup () {
set +e
rm -f $PWFILE $pg_service
if [ -f $pg_service.pg_virtualenv-save.$$ ]; then
mv -f $pg_service.pg_virtualenv-save.$$ $pg_service
fi
for v in $PG_VERSIONS; do
# don't drop existing clusters named "regress"
[ -f /etc/postgresql/$v/regress/.by_pg_virtualenv ] || continue
echo "Dropping cluster $v/regress ..."
rm -f /etc/postgresql/$v/regress/.by_pg_virtualenv
pg_ctlcluster --mode immediate $v regress stop
pg_dropcluster $v regress
done
}
trap cleanup 0 HUP INT QUIT ILL ABRT PIPE TERM
if [ -f $pg_service ]; then
mv --no-clobber $pg_service $pg_service.pg_virtualenv-save.$$
fi
fi
# create postgres environments
for v in $PG_VERSIONS; do
# create temporary cluster
# we chdir to / so programs don't throw "could not change directory to ..."
(
cd /
case $v in
8*|9.0|9.1|9.2) : ;;
*) NOSYNC="--nosync" ;;
esac
pg_createcluster \
${PGPORT:+-p "$PGPORT"} \
${NONROOT:+-d "$WORKDIR/data/$v/regress"} \
${NONROOT:+-l "$WORKDIR/log/postgresql-$v-regress.log"} \
${CREATE_OPTS:-} --pgoption fsync=off "${PGCONF_OPTS[@]}" --start $v regress -- \
--username="$PGUSER" --pwfile="$PWFILE" $NOSYNC ${INITDB_OPTS:-}
# in fakeroot, the username will likely default to "postgres" otherwise
echo "This is a temporary throw-away cluster" > ${PG_CLUSTER_CONF_ROOT:-/etc/postgresql}/$v/regress/.by_pg_virtualenv
)
port=$(pg_conftool -s $v regress show port)
# record cluster information in service file
cat >> $PGSYSCONFDIR/pg_service.conf <<EOF
[$v]
host=localhost
port=$port
dbname=postgres
user=$PGUSER
password=$PGPASSWORD
EOF
done
export PGSYSCONFDIR
export PGHOST="localhost"
export PGDATABASE="postgres"
case $PG_VERSIONS in
*\ *) ;; # multiple versions: do not set PGPORT because that breaks --cluster
*)
export PGPORT="$port"
export PG_CONFIG="$PGBINROOT$PG_VERSIONS/bin/pg_config"
;;
esac
# run program
echo
"$@" || EXIT="$?"
if [ ${EXIT:-0} -gt 0 ]; then
for log in ${LOGDIR:-/var/log/postgresql}/*.log; do
echo "*** $log (last 100 lines) ***"
tail -100 $log
done
if [ "${run_shell:-}" ]; then
echo "pg_virtualenv: command exited with status $EXIT, dropping you into a shell"
${SHELL:-/bin/sh}
fi
fi
exit ${EXIT:-0}
|