Skip to content

Commit 377fb0e

Browse files
authored
Merge pull request #2685 from kkimurak/install-pgsql-client-based-on-server-version
Use a version of `postgresql-client` that matches the server version
2 parents d35c73c + 110a8d7 commit 377fb0e

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-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 \

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,30 @@ GitLab uses a database backend to store its data. You can configure this image t
240240

241241
#### PostgreSQL
242242

243+
**Important note:** This image is shipped with different versions of the `postgresql-client`.
244+
245+
During the startup of the container, the major version of the database system is checked based on the specified connection destination. Only the version of the `postgresql-client`, that matches the major version of the Postgres database is used. If the major version of any version of the included clients does not match, the latest client is used (but may causes issues). All other versions of the `postgresql-client` are deleted at runtime.
246+
247+
This behavior can be checked using the command `docker logs` and an output like the following should be available:
248+
249+
````sh
250+
251+
Configuring gitlab::database
252+
- Installing postgresql client to avoid version mismatch on dumping
253+
-- Detected server version: 140007
254+
- Generating /home/git/.postgresqlrc
255+
14 postgresql:5432 gitlabhq_production
256+
- Uninstalling unused client(s): postgresql-client-12 postgresql-client-13 postgresql-client-15
257+
258+
````
259+
260+
Please note furthermore, that only combatible versions of the `postgresql-client` to GitLab are shipped with this image. Currently these belogn to
261+
262+
- `postgresql-client-12`,
263+
- `postgresql-client-13`,
264+
- `postgresql-client-14`,
265+
- and `postgresql-client-15`.
266+
243267
*NOTE:* version 13.7.0 and later requires PostgreSQL version 12.x
244268

245269
##### External PostgreSQL Server

assets/runtime/functions

Lines changed: 79 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,89 @@ 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+
223+
gitlab_uninstall_unused_database_client() {
224+
if [[ -f "/home/${GITLAB_USER}/.postgresqlrc" ]]; then
225+
# refer /home/${GITLAB_USER}/.postgresqlrc and pick up versions in use
226+
# .postgresqlrc contains following information per line
227+
# database_major_version host:port database_name
228+
# - ignore lines starts with # by specifying pattern /^[^#]/
229+
# - first field is the version number in use.
230+
# - cocnat whole lines into single string. convert newline to \|
231+
# this is escaped regex "OR"
232+
# now we got the following regex that can be used as an option to grep:
233+
# \|-12\|-13
234+
DB_CLIENT_VERSIONS_IN_USE="$(awk '/^[^#]/ {printf("\|-%s",$1)}' "/home/${GITLAB_USER}/.postgresqlrc")"
235+
236+
# we also need to keep postgresql-client-common package to switch based on ~/.postgresqlrc
237+
REGEX_DB_CLIENT_VERSIONS_IN_USE="-common${DB_CLIENT_VERSIONS_IN_USE}"
238+
239+
# remove unused client using regex above
240+
UNUSED_DB_CLIENTS=$(apt-cache pkgnames postgresql-client | grep -v -e "${REGEX_DB_CLIENT_VERSIONS_IN_USE}" | tr '\n' ' ')
241+
echo "- Uninstalling unused client(s): ${UNUSED_DB_CLIENTS}"
242+
DEBIAN_FRONTEND=noninteractive apt-get -qq remove -- ${UNUSED_DB_CLIENTS} >/dev/null
243+
fi
244+
}
245+
170246
gitlab_configure_database() {
171247
echo -n "Configuring gitlab::database"
172248

173249
gitlab_finalize_database_parameters
174250
gitlab_check_database_connection
251+
gitlab_generate_postgresqlrc
252+
gitlab_uninstall_unused_database_client
175253

176254
update_template ${GITLAB_DATABASE_CONFIG} \
177255
DB_ENCODING \

0 commit comments

Comments
 (0)