Skip to content

Commit dd509d6

Browse files
committed
Allow initdb and upgrade without systemd running
Adds argument --datadir as a possible fallback for user that would like to set custom data directory. Adds usage section to readme. Fixes: #26
1 parent cbe0997 commit dd509d6

File tree

3 files changed

+95
-34
lines changed

3 files changed

+95
-34
lines changed

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@
2020
- automake
2121
- autoconf-archive
2222

23+
## Usage
24+
This script is used as a wrapper around PostgreSQL initialization and upgrade
25+
commands. It also parses init system service files and/or enviroment files to
26+
correctly find datadir based on current system.
27+
28+
### Initialization
29+
To initialize new PostgreSQL data directory use `./postgresql-setup --initdb`.
30+
31+
### Upgrade
32+
To upgrade existing PostgreSQL data directory to use newer PostgreSQL version
33+
use `./postgresql-setup --upgrade`.
34+
35+
If your distribution doesn't include this
36+
script with PostgreSQL and you are using this on your own, please update
37+
`etc/postgresql-setup/upgrade/postgresql.conf` to reflect your setup.
38+
2339
## Maintainer notes
2440
Be careful about paths. Your might need to tweak paths either in configure
2541
files, or in code based on your environment.
@@ -29,12 +45,6 @@ Be careful about paths. Your might need to tweak paths either in configure
2945
- For example line should be `. "/postgresql-setup/$file"` if your
3046
working project is located at `/postgresql-setup`
3147
- *Do NOT commit/merge this change*
32-
- Line 69 of `share/postgresql-setup/library.sh.in` in function
33-
`parse_upgrade_setup()` has to be changed to reflect location of your project.
34-
- For example line should be `local
35-
upgrade_confdir="/postgresql-setup/etc/@NAME_BINARYBASE@-setup/upgrade"` if your
36-
working project is located at `/postgresql-setup`
37-
- *Do NOT commit/merge this change*
3848

3949
### Build instructions
4050
1. `autoreconf -vfi`
@@ -46,4 +56,4 @@ After aforementioned steps, you should be able to run freshly built
4656
postgresql-setup script directly from /bin folder in this repo.
4757

4858
If no init system is present, PostgreSQL server can be run after initialization
49-
via `/usr/bin/pg_ctl -D /var/lib/pgsql/data -l /var/lib/pgsql/srv.log start`
59+
via `/usr/bin/pg_ctl -D /var/lib/pgsql/data -l /var/lib/pgsql/logfile start`

bin/postgresql-setup.in

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,11 @@ Options:
8585
string). When no UNIT_NAME is explicitly passed,
8686
the 'postgresql' string is used by default.
8787
--port=PORT port where the initialized server will listen for
88-
connections"
89-
90-
test 0 -eq @WANT_SYSVINIT@ && \
91-
USAGE_STRING+="
92-
--new-systemd-unit We dropped this option for security reasons.
93-
Nowadays, please use the root-only script
94-
@sbindir@/@NAME_BINARYBASE@-new-systemd-unit.
95-
--datadir Dropped with --new-systemd-unit."
96-
97-
USAGE_STRING+="
88+
connections
89+
--datadir Override automatic detection of PostgreSQL data
90+
directory. If your system is using systemd as init
91+
system, it is advisable to change data directory
92+
path in service file instead.
9893
--upgrade-from-unit=UNIT Select proper unit name to upgrade from. This
9994
has similar semantics as --unit option.
10095
--upgrade-ids Print list of available IDs of upgrade scenarios to
@@ -401,6 +396,37 @@ handle_service_env()
401396
done
402397
}
403398

399+
handle_service_file()
400+
{
401+
local service_file="$1"
402+
local line var_name var_value
403+
debug "Parsing ${service_file}"
404+
local systemd_env="$(cat "${service_file}")" \
405+
|| { return; }
406+
407+
while IFS= read -r line; do
408+
# Only lines starting with Environment=
409+
[[ "$line" =~ ^Environment= ]] || continue
410+
411+
# Remove 'Environment=' prefix
412+
line="${line#Environment=}"
413+
414+
for env_val in $line; do
415+
var_name="${env_val%%=*}"
416+
var_value="${env_val#*=}"
417+
debug "Found environment variable: $var_name=$var_value"
418+
419+
case "$var_name" in
420+
PGDATA)
421+
unit_pgdata="$var_value"
422+
;;
423+
PGPORT)
424+
unit_pgport="$var_value"
425+
;;
426+
esac
427+
done
428+
done <<< "$systemd_env"
429+
}
404430

405431
handle_envfile()
406432
{
@@ -418,6 +444,7 @@ handle_envfile()
418444
# Note that the env file parser in systemd does not perform exactly the
419445
# same job.
420446
unset PGPORT PGDATA
447+
# Source the file, loading the variables in it
421448
. "$file"
422449
envfile_pgdata="$PGDATA"
423450
envfile_pgport="$PGPORT"
@@ -503,18 +530,35 @@ service_configuration()
503530
&& set_var "$datavar" "@PGDATADIR@"
504531
handle_envfile "@initscriptsconfdir@/$service"
505532
else
506-
# We ship two service files, @[email protected] and
507-
# @NAME_SERVICE@@.service. The former has PGDATA set by default
508-
# similarly to sysvinit case.
509-
handle_service_env "$service"
510-
handle_service_envfiles "$option_mode" "$service"
533+
if grep -q systemd /proc/1/comm; then
534+
# If booted with systemd as PID 1, we try to find the variables
535+
# using systemctl show -p Environment= @[email protected]
536+
# We ship two service files, @[email protected] and
537+
# @NAME_SERVICE@@.service. The former has PGDATA set by default
538+
# similarly to sysvinit case.
539+
debug "System booted with systemd as PID 1, using systemctl to find"\
540+
"service configuration for $service"
541+
handle_service_env "$service"
542+
handle_service_envfiles "$option_mode" "$service"
543+
else
544+
# If not booted with systemd, we try to find the service file in
545+
# predefined path and parse it manually.
546+
warn "System not booted with systemd as PID 1. Manually parsing service"\
547+
"file @INIT_SYSTEM_SERVICE_PATH@/$service.service"
548+
handle_service_file "@INIT_SYSTEM_SERVICE_PATH@/$service.service"
549+
fi
511550
fi
512551

513552
# EnvironmentFile beats Environment configuration in systemd. In sysvinit
514553
# there is no "unit_pgdata". So make sure the envfile_gpdata is used later
515554
# than unit_pgdata.
516555
test -n "$unit_pgdata" && set_var "$datavar" "$unit_pgdata"
517556
test -n "$envfile_pgdata" && set_var "$datavar" "$envfile_pgdata"
557+
# If the user specified --datadir, take priority over all
558+
if [ -n "${option_datadir}" ]; then
559+
info $"Using datadir from --datadir: $option_datadir"
560+
set_var "$datavar" "$option_datadir"
561+
fi
518562

519563
# skip for the first run
520564
test initdb = "$mode" && return
@@ -571,6 +615,7 @@ option_service="@NAME_SERVICE@"
571615
option_port=
572616
option_debug=0
573617
option_upgradefrom_unit=
618+
option_datadir=
574619

575620
# Content of EnvironmentFile= files fills those:
576621
envfile_pgdata=
@@ -626,10 +671,9 @@ while true; do
626671
shift 2
627672
;;
628673

629-
--datadir|--new-systemd-unit)
630-
error $"Removed option --new-systemd-unit/--datadir, please use"
631-
error_q $"@sbindir@/@NAME_BINARYBASE@-new-systemd-unit script"
632-
exit 1
674+
--datadir)
675+
option_datadir="$2"
676+
shift 2
633677
;;
634678

635679
--debug)
@@ -698,7 +742,7 @@ debug "service name: $option_service"
698742
service_configuration initdb pgdata UNUSED "$option_service"
699743

700744
test "$pgdata" = default \
701-
&& die $"no db datadir (PGDATA) configured for '$option_service$srvsuff' unit"
745+
&& die $"no db datadir (PGDATA) found, try using --datadir option"
702746

703747
[[ "$pgdata" =~ ^/.* ]] \
704748
|| die $"the PostgreSQL datadir not absolute path: '$pgdata', try --debug"
@@ -775,7 +819,10 @@ fi
775819

776820
## LAST CHECK THE SETUP ##
777821

778-
check_daemon_reload
822+
if grep -q systemd /proc/1/comm; then
823+
# Check only if we are running under systemd.
824+
check_daemon_reload
825+
fi
779826

780827
# These variables are read by underlying utilites, rather export them.
781828
export PGDATA=$pgdata

configure.ac

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ _AX_TEXT_TPL_SUBST([TEST_GEN_FILES_LIST], [.generated_files])
2020

2121
WANT_SYSVINIT=0
2222
INIT_SYSTEM=systemd
23+
INIT_SYSTEM_SERVICE_PATH=/lib/systemd/system
2324
test -d /usr/lib/systemd/system/ || {
2425
INIT_SYSTEM=sysvinit
2526
WANT_SYSVINIT=1
27+
INIT_SYSTEM_SERVICE_PATH=
2628
}
2729
AM_CONDITIONAL([WANT_SYSVINIT], [test "$WANT_SYSVINIT" -eq 1])
2830
_AX_TEXT_TPL_SUBST([WANT_SYSVINIT])
@@ -221,6 +223,7 @@ _AX_TEXT_TPL_SUBST([NAME_BINARYBASE])
221223
_AX_TEXT_TPL_SUBST([NAME_PACKAGE])
222224
_AX_TEXT_TPL_SUBST([NAME_SERVICE])
223225
_AX_TEXT_TPL_SUBST([NAME_SERVICE_VARNAME])
226+
_AX_TEXT_TPL_SUBST([INIT_SYSTEM_SERVICE_PATH])
224227

225228
AC_MSG_CHECKING([whether to install compat %pgtest_* macros])
226229
# This hack shouldn't be removed sooner than once the F27 postgresql is EOL,
@@ -235,10 +238,11 @@ AC_OUTPUT
235238

236239
AC_MSG_NOTICE([Configured the folowing way:
237240
238-
PostgreSQL version: $PGVERSION
239-
PGDATADIR: $PGDATADIR
240-
PostgreSQL service: $NAME_SERVICE
241-
PostgreSQL package: $NAME_PACKAGE
242-
PostgreSQL bin_pfx: $NAME_BINARYBASE
243-
Init system: $INIT_SYSTEM
241+
PostgreSQL version: $PGVERSION
242+
PGDATADIR: $PGDATADIR
243+
PostgreSQL service: $NAME_SERVICE
244+
PostgreSQL package: $NAME_PACKAGE
245+
PostgreSQL bin_pfx: $NAME_BINARYBASE
246+
Init system: $INIT_SYSTEM
247+
Init system services: $INIT_SYSTEM_SERVICE_PATH
244248
])

0 commit comments

Comments
 (0)