diff --git a/README b/README deleted file mode 100644 index 6bc0a46..0000000 --- a/README +++ /dev/null @@ -1,18 +0,0 @@ ----------------- -postgresql-setup ----------------- - -BuildRequires: - - m4 - - docbook-utils - - help2man - - elinks (pretty README.rpm-dist) - -Requires: - - coreutils - -Suggested BuildRequires: - - util-linux (mountpoint utility) - -Maintainer's BuildRequires: - - autoconf, automake, autoconf-archive diff --git a/README.md b/README.md new file mode 100644 index 0000000..a4af8dd --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# postgresql-setup + +## Requires + +### BuildRequires +- make +- m4 +- docbook-utils +- help2man +- elinks (pretty README.rpm-dist) +- postgresql-server (detect current version) + +Installable on Fedora with\ +`sudo dnf install m4 docbook-utils help2man elinks postgresql-server` + +### Requires +- coreutils + +### Suggested BuildRequires +- util-linux (mountpoint utility) + +### Maintainer's BuildRequires +- autoconf +- automake +- autoconf-archive + +## Usage +This script is used as a wrapper around PostgreSQL initialization and upgrade +commands. It also parses init system service files and/or environment files to +correctly find datadir based on current system. + +### Initialization +To initialize new PostgreSQL data directory use `./postgresql-setup --initdb`. + +### Upgrade +To upgrade existing PostgreSQL data directory to use newer PostgreSQL version +use `./postgresql-setup --upgrade`. + +If your distribution doesn't include this +script with PostgreSQL and you are using this on your own, please update +`./etc/postgresql-setup/upgrade/postgresql.conf` to reflect your setup. + +### Running without systemd/init system +Your setup might not include systemd as the init system or include any +init system at all. This would be the case in most of the base container images +for example. This script will try to compensate by parsing systemd +service file in preconfigured path directly. By default the path is +`/lib/systemd/system`. + +If there is no systemd service file, or for whatever reason the script is unable +to find valid PostgreSQL data directory, you can still provide PostgreSQL data +directory path manually by using `--datadir` argument. For example when +initializing new data directory use `postgresql-setup --initdb --datadir=/my/path`. + +This feature is most beneficial when using this script inside container images, +as it gives you the most control with least dependencies. + +## Maintainer notes +Be careful about paths. You might need to tweak paths either in the configure + files, or in code based on your environment. +- Line 49 of `./bin/postgresql-setup.in` in function `builddir_source ()` has to + be changed to location of your project otherwise you won't be able to run your + build without full installation into system paths + - For example line should be `. "/postgresql-setup/$file"` if your + working project is located at `/postgresql-setup` + - *Do NOT commit/merge this change* + +### Build instructions +1. `autoreconf -vfi` +2. `./configure --prefix=/usr` + - Prefix needed for fedora environment - one of the path tweaks that are needed +3. `make` + +After aforementioned steps, you should be able to run freshly built +postgresql-setup script directly from /bin folder in this repo. + +If no init system is present, PostgreSQL server can be run after initialization +via `/usr/bin/pg_ctl -D /var/lib/pgsql/data -l /var/lib/pgsql/logfile start` \ No newline at end of file diff --git a/bin/postgresql-setup.in b/bin/postgresql-setup.in index cf9ed24..9626dd9 100644 --- a/bin/postgresql-setup.in +++ b/bin/postgresql-setup.in @@ -85,16 +85,11 @@ Options: string). When no UNIT_NAME is explicitly passed, the 'postgresql' string is used by default. --port=PORT port where the initialized server will listen for - connections" - -test 0 -eq @WANT_SYSVINIT@ && \ -USAGE_STRING+=" - --new-systemd-unit We dropped this option for security reasons. - Nowadays, please use the root-only script - @sbindir@/@NAME_BINARYBASE@-new-systemd-unit. - --datadir Dropped with --new-systemd-unit." - -USAGE_STRING+=" + connections + --datadir Override automatic detection of PostgreSQL data + directory. If your system is using systemd as init + system, it is advisable to change data directory + path in service file instead. --upgrade-from-unit=UNIT Select proper unit name to upgrade from. This has similar semantics as --unit option. --upgrade-ids Print list of available IDs of upgrade scenarios to @@ -401,6 +396,37 @@ handle_service_env() done } +handle_service_file() +{ + local service_file="$1" + local line var_name var_value + debug "Parsing ${service_file}" + local systemd_env="$(cat "${service_file}")" \ + || { return; } + + while IFS= read -r line; do + # Only lines starting with Environment= + [[ "$line" =~ ^Environment= ]] || continue + + # Remove 'Environment=' prefix + line="${line#Environment=}" + + for env_val in $line; do + var_name="${env_val%%=*}" + var_value="${env_val#*=}" + debug "Found environment variable: $var_name=$var_value" + + case "$var_name" in + PGDATA) + unit_pgdata="$var_value" + ;; + PGPORT) + unit_pgport="$var_value" + ;; + esac + done + done <<< "$systemd_env" +} handle_envfile() { @@ -418,6 +444,7 @@ handle_envfile() # Note that the env file parser in systemd does not perform exactly the # same job. unset PGPORT PGDATA + # Source the file, loading the variables in it . "$file" envfile_pgdata="$PGDATA" envfile_pgport="$PGPORT" @@ -503,11 +530,23 @@ service_configuration() && set_var "$datavar" "@PGDATADIR@" handle_envfile "@initscriptsconfdir@/$service" else - # We ship two service files, @NAME_SERVICE@.service and - # @NAME_SERVICE@@.service. The former has PGDATA set by default - # similarly to sysvinit case. - handle_service_env "$service" - handle_service_envfiles "$option_mode" "$service" + if grep -q systemd /proc/1/comm; then + # If booted with systemd as PID 1, we try to find the variables + # using systemctl show -p Environment= @NAME_SERVICE@.service + # We ship two service files, @NAME_SERVICE@.service and + # @NAME_SERVICE@@.service. The former has PGDATA set by default + # similarly to sysvinit case. + debug "System booted with systemd as PID 1, using systemctl to find"\ + "service configuration for $service" + handle_service_env "$service" + handle_service_envfiles "$option_mode" "$service" + else + # If not booted with systemd, we try to find the service file in + # predefined path and parse it manually. + warn "System not booted with systemd as PID 1. Manually parsing service"\ + "file @INIT_SYSTEM_SERVICE_PATH@/$service.service" + handle_service_file "@INIT_SYSTEM_SERVICE_PATH@/$service.service" + fi fi # EnvironmentFile beats Environment configuration in systemd. In sysvinit @@ -515,6 +554,11 @@ service_configuration() # than unit_pgdata. test -n "$unit_pgdata" && set_var "$datavar" "$unit_pgdata" test -n "$envfile_pgdata" && set_var "$datavar" "$envfile_pgdata" + # If the user specified --datadir, take priority over all + if [ -n "${option_datadir}" ]; then + info $"Using datadir from --datadir: $option_datadir" + set_var "$datavar" "$option_datadir" + fi # skip for the first run test initdb = "$mode" && return @@ -571,6 +615,7 @@ option_service="@NAME_SERVICE@" option_port= option_debug=0 option_upgradefrom_unit= +option_datadir= # Content of EnvironmentFile= files fills those: envfile_pgdata= @@ -626,10 +671,9 @@ while true; do shift 2 ;; - --datadir|--new-systemd-unit) - error $"Removed option --new-systemd-unit/--datadir, please use" - error_q $"@sbindir@/@NAME_BINARYBASE@-new-systemd-unit script" - exit 1 + --datadir) + option_datadir="$2" + shift 2 ;; --debug) @@ -698,7 +742,7 @@ debug "service name: $option_service" service_configuration initdb pgdata UNUSED "$option_service" test "$pgdata" = default \ - && die $"no db datadir (PGDATA) configured for '$option_service$srvsuff' unit" + && die $"no db datadir (PGDATA) found, try using --datadir option" [[ "$pgdata" =~ ^/.* ]] \ || die $"the PostgreSQL datadir not absolute path: '$pgdata', try --debug" @@ -775,7 +819,10 @@ fi ## LAST CHECK THE SETUP ## -check_daemon_reload +if grep -q systemd /proc/1/comm; then + # Check only if we are running under systemd. + check_daemon_reload +fi # These variables are read by underlying utilites, rather export them. export PGDATA=$pgdata diff --git a/configure.ac b/configure.ac index 459eb46..9f1daef 100755 --- a/configure.ac +++ b/configure.ac @@ -20,9 +20,11 @@ _AX_TEXT_TPL_SUBST([TEST_GEN_FILES_LIST], [.generated_files]) WANT_SYSVINIT=0 INIT_SYSTEM=systemd +INIT_SYSTEM_SERVICE_PATH=/lib/systemd/system test -d /usr/lib/systemd/system/ || { INIT_SYSTEM=sysvinit WANT_SYSVINIT=1 + INIT_SYSTEM_SERVICE_PATH= } AM_CONDITIONAL([WANT_SYSVINIT], [test "$WANT_SYSVINIT" -eq 1]) _AX_TEXT_TPL_SUBST([WANT_SYSVINIT]) @@ -221,6 +223,7 @@ _AX_TEXT_TPL_SUBST([NAME_BINARYBASE]) _AX_TEXT_TPL_SUBST([NAME_PACKAGE]) _AX_TEXT_TPL_SUBST([NAME_SERVICE]) _AX_TEXT_TPL_SUBST([NAME_SERVICE_VARNAME]) +_AX_TEXT_TPL_SUBST([INIT_SYSTEM_SERVICE_PATH]) AC_MSG_CHECKING([whether to install compat %pgtest_* macros]) # This hack shouldn't be removed sooner than once the F27 postgresql is EOL, @@ -235,10 +238,11 @@ AC_OUTPUT AC_MSG_NOTICE([Configured the folowing way: - PostgreSQL version: $PGVERSION - PGDATADIR: $PGDATADIR - PostgreSQL service: $NAME_SERVICE - PostgreSQL package: $NAME_PACKAGE - PostgreSQL bin_pfx: $NAME_BINARYBASE - Init system: $INIT_SYSTEM + PostgreSQL version: $PGVERSION + PGDATADIR: $PGDATADIR + PostgreSQL service: $NAME_SERVICE + PostgreSQL package: $NAME_PACKAGE + PostgreSQL bin_pfx: $NAME_BINARYBASE + Init system: $INIT_SYSTEM + Init system services: $INIT_SYSTEM_SERVICE_PATH ])