Skip to content

Commit 260f548

Browse files
committed
Ship with multiple versions of postgresql-client
It is intended to work even in environments without an internet connection. - Use latest version of pg_isready on checking database connection - Switch postgresql-client version checking server on startup - If the server versions do not match exactly, use the latest installed client and warn on docker log From postgresql documentation: https://www.postgresql.org/docs/15/app-pgdump.html#PG-DUMP-NOTES > Also, it is not guaranteed that pg_dump's output can be loaded > into a server of an older major version — not even if the dump > was taken from a server of that version. To switch client version, generate a file ~/.postgresqlrc with content like: {server side major version} {server hostname}:{server port} {default database} See detail on: https://manpages.ubuntu.com/manpages/bionic/man5/postgresqlrc.5.html Following messages appear on docker log: - Detected server version: 140007 - Generating /home/git/.postgresqlrc
1 parent d35c73c commit 260f548

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ RUN set -ex && \
4444
&& apt-get update \
4545
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
4646
sudo supervisor logrotate locales curl \
47-
nginx openssh-server postgresql-client-12 postgresql-contrib-12 redis-tools \
47+
nginx openssh-server postgresql-contrib redis-tools \
48+
postgresql-client-12 postgresql-client-13 postgresql-client-14 postgresql-client-15 \
4849
python3 python3-docutils nodejs yarn gettext-base graphicsmagick \
4950
libpq5 zlib1g libyaml-0-2 libssl1.1 \
5051
libgdbm6 libreadline8 libncurses5 libffi7 \

assets/runtime/functions

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ gitlab_finalize_database_parameters() {
149149

150150
gitlab_check_database_connection() {
151151

152-
prog=$(find /usr/lib/postgresql/ -name pg_isready)
152+
prog=$(find /usr/lib/postgresql/ -name pg_isready -type f | sort | tail -n1)
153153
prog="${prog} -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} -t 1"
154154

155155
timeout=60
@@ -167,11 +167,65 @@ gitlab_check_database_connection() {
167167
echo
168168
}
169169

170+
gitlab_generate_postgresqlrc() {
171+
echo "Configuring /home/${GITLAB_USER}/.postgresqlrc to avoid version mismatch on dumping"
172+
# server_version_num property is a number built from version string:
173+
# https://www.postgresql.org/docs/15/libpq-status.html#LIBPQ-PQSERVERVERSION
174+
# > The result is formed by multiplying the server's major version number by 10000 and adding the minor version number.
175+
# > For example, version 10.1 will be returned as 100001, and version 11.0 will be returned as 110000. Zero is returned if the connection is bad.
176+
# >
177+
# > Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version.
178+
# > For those versions, PQserverVersion uses two digits for each part;
179+
# > for example version 9.1.5 will be returned as 90105, and version 9.2.0 will be returned as 90200.
180+
#
181+
# This difference also appends to apt package name.
182+
# For example, in ubuntu:focal, postgresql-client-{8.2, 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10, 11, 12, 13, 14, 15} are available.
183+
#
184+
DB_SERVER_VERSION=$(PGPASSWORD=${DB_PASS} psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -Atw -c "SHOW server_version_num")
185+
if [[ "${DB_SERVER_VERSION}" -eq 0 ]]; then
186+
echo
187+
echo "Could not retrieve database server version correctly. Aborting..."
188+
return 1
189+
fi
190+
191+
echo "- Detected server version: ${DB_SERVER_VERSION}"
192+
193+
# Anyway, we can get major version (8, 9, 10 and so on) by dividing by 10000.
194+
# DB_SERVER_VERSION_MAJOR=${DB_SERVER_VERSION%%.*}
195+
DB_SERVER_VERSION_MAJOR=$((DB_SERVER_VERSION/10000))
196+
DB_CLIENT_VERSION_PACKAGE_NAME=
197+
198+
if [[ "${DB_SERVER_VERSION_MAJOR}" -ge 10 ]]; then
199+
# v10 or later: use "rought major version" as version number in package name
200+
DB_CLIENT_VERSION_PACKAGE_NAME=${DB_SERVER_VERSION_MAJOR}
201+
else
202+
# prior to v10: convert
203+
# FIXME: rough implementation
204+
# It exploits the fact that there is no version such as 9.10, and it lacks versatility.
205+
# divide by 100, then replace first 0 to comma
206+
DB_CLIENT_VERSION_PACKAGE_NAME=$((DB_SERVER_VERSION/100))
207+
DB_CLIENT_VERSION_PACKAGE_NAME=${DB_CLIENT_VERSION_PACKAGE_NAME/0/.}
208+
fi
209+
210+
# if exact-match client not found, select latest version from installed clients
211+
if [[ "$(apt-cache pkgnames postgresql-client | grep -e "-${DB_CLIENT_VERSION_PACKAGE_NAME}" | wc -l)" -ne 1 ]]; then
212+
LATEST_CLIENT="$(apt-cache pkgnames postgresql-client | grep -v -e "-common" | sort --version-sort | tail -n1)"
213+
DB_CLIENT_VERSION_PACKAGE_NAME=${LATEST_CLIENT/postgresql-client-/}
214+
echo "gitlab_generate_postgresqlrc(): WARNING - Suitable client not installed. postgresql-client-${DB_CLIENT_VERSION_PACKAGE_NAME} will be used but you may face issue (database in backup will be empty, for example)"
215+
fi
216+
217+
# generate ~/.postgresqlrc to switch client version
218+
GITLAB_USER_POSTGRESQLRC="/home/${GITLAB_USER}/.postgresqlrc"
219+
echo "- Generating ${GITLAB_USER_POSTGRESQLRC}"
220+
echo "${DB_CLIENT_VERSION_PACKAGE_NAME} ${DB_HOST}:${DB_PORT} ${DB_NAME}" | exec_as_git tee "${GITLAB_USER_POSTGRESQLRC}"
221+
}
222+
170223
gitlab_configure_database() {
171224
echo -n "Configuring gitlab::database"
172225

173226
gitlab_finalize_database_parameters
174227
gitlab_check_database_connection
228+
gitlab_generate_postgresqlrc
175229

176230
update_template ${GITLAB_DATABASE_CONFIG} \
177231
DB_ENCODING \

0 commit comments

Comments
 (0)