From 0c9da028e6ea68c1d451513f9333364e092aaec9 Mon Sep 17 00:00:00 2001 From: Dominika Hodovska Date: Fri, 24 Nov 2017 12:10:23 +0100 Subject: [PATCH] Enable s2i --- 9.4/Dockerfile | 11 +++- 9.4/Dockerfile.rhel7 | 11 +++- 9.4/root/usr/bin/run-postgresql | 5 +- .../container-scripts/postgresql/README.md | 39 +++++++++++++ .../container-scripts/postgresql/common.sh | 44 ++++++++++----- .../postgresql/postgresql-init/set-config.sh | 14 +++++ .../postgresql-start-hook/set_passwords.sh | 14 +++++ 9.4/s2i/bin/assemble | 14 +++++ 9.4/s2i/bin/run | 1 + 9.4/s2i/bin/usage | 1 + 9.5/Dockerfile | 11 +++- 9.5/Dockerfile.rhel7 | 11 +++- 9.5/root/usr/bin/run-postgresql | 5 +- .../container-scripts/postgresql/README.md | 39 +++++++++++++ .../container-scripts/postgresql/common.sh | 44 ++++++++++----- .../postgresql/postgresql-init/set-config.sh | 14 +++++ .../postgresql-start-hook/set_passwords.sh | 14 +++++ 9.5/s2i/bin/assemble | 14 +++++ 9.5/s2i/bin/run | 1 + 9.5/s2i/bin/usage | 1 + Dockerfile.template | 11 +++- .../postgresql-config/s2i-extending.conf | 4 ++ .../postgresql-start-hook/set_passwords.sh | 4 ++ latest/Dockerfile | 11 +++- latest/Dockerfile.rhel7 | 11 +++- latest/root/usr/bin/run-postgresql | 5 +- .../container-scripts/postgresql/README.md | 39 +++++++++++++ .../container-scripts/postgresql/common.sh | 44 ++++++++++----- .../postgresql/postgresql-init/set-config.sh | 14 +++++ .../postgresql-start-hook/set_passwords.sh | 14 +++++ latest/s2i/bin/assemble | 14 +++++ latest/s2i/bin/run | 1 + latest/s2i/bin/usage | 1 + specs/multispec.yml | 2 + test/run_test | 55 +++++++++++++++++++ test/test-app/postgresql-init/backup_user.sh | 8 +++ 36 files changed, 484 insertions(+), 62 deletions(-) create mode 100644 9.4/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh create mode 100644 9.4/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh create mode 100755 9.4/s2i/bin/assemble create mode 120000 9.4/s2i/bin/run create mode 100755 9.4/s2i/bin/usage create mode 100644 9.5/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh create mode 100644 9.5/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh create mode 100755 9.5/s2i/bin/assemble create mode 120000 9.5/s2i/bin/run create mode 100755 9.5/s2i/bin/usage create mode 100644 examples/extending-image/postgresql-config/s2i-extending.conf create mode 100644 examples/extending-image/postgresql-start-hook/set_passwords.sh create mode 100644 latest/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh create mode 100644 latest/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh create mode 100755 latest/s2i/bin/assemble create mode 120000 latest/s2i/bin/run create mode 100755 latest/s2i/bin/usage create mode 100644 test/test-app/postgresql-init/backup_user.sh diff --git a/9.4/Dockerfile b/9.4/Dockerfile index bd2ec725..f343e348 100644 --- a/9.4/Dockerfile +++ b/9.4/Dockerfile @@ -1,4 +1,4 @@ -FROM centos:centos7 +FROM centos/s2i-core-centos7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM centos:centos7 ENV POSTGRESQL_VERSION=9.4 \ POSTGRESQL_PREV_VERSION=9.2 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -55,6 +56,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql94 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -65,6 +67,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/9.4/Dockerfile.rhel7 b/9.4/Dockerfile.rhel7 index eb0f38ff..33f30c0c 100644 --- a/9.4/Dockerfile.rhel7 +++ b/9.4/Dockerfile.rhel7 @@ -1,4 +1,4 @@ -FROM rhel7 +FROM rhscl/s2i-core-rhel7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM rhel7 ENV POSTGRESQL_VERSION=9.4 \ POSTGRESQL_PREV_VERSION=9.2 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -60,6 +61,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql94 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -70,6 +72,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/9.4/root/usr/bin/run-postgresql b/9.4/root/usr/bin/run-postgresql index af6ac4a1..896e6899 100755 --- a/9.4/root/usr/bin/run-postgresql +++ b/9.4/root/usr/bin/run-postgresql @@ -24,10 +24,13 @@ fi pg_ctl -w start -o "-h ''" if $PG_INITIALIZED ; then + process_extending_files ${APP_DATA}/src/postgresql-init ${CONTAINER_SCRIPTS_PATH}/postgresql-init migrate_db create_users fi -set_passwords + +process_extending_files ${APP_DATA}/src/postgresql-start-hook ${CONTAINER_SCRIPTS_PATH}/postgresql-start-hook + pg_ctl stop unset_env_vars diff --git a/9.4/root/usr/share/container-scripts/postgresql/README.md b/9.4/root/usr/share/container-scripts/postgresql/README.md index a38e2efa..42984af2 100644 --- a/9.4/root/usr/share/container-scripts/postgresql/README.md +++ b/9.4/root/usr/share/container-scripts/postgresql/README.md @@ -235,6 +235,45 @@ enough space for the copy; upgrade failure because of not enough space might lead to data loss. +Extending image +---------------- + +This image can be extended using +[source-to-image](https://github.com/openshift/source-to-image). + +For example to build customized image `new-postgresql` +with configuration in `~/image-configuration/` run: + + +``` +$ s2i build ~/image-configuration/ postgresql new-postgresql +``` + +The directory passed to `s2i build` should contain one or more of the +following directories: + +##### `postgresql-config/` + +contained configuration files (`*.conf`) will be included at the end of image postgresql.conf file during database initialization + + +##### `postgresql-init/` + +contained shell scripts (`*.sh`) are sourced once, when database is initialized + +##### `postgresql-start-hook/` + +contained shell scripts (`*.sh`) are sourced before every start + +---------------------------------------------- + +During `s2i build` all provided files are copied into `/opt/app-root/src` +directory in the new image. Only one +file with the same name can be used for customization and user provided files +are preferred over default files in `/usr/share/container-scripts/`- +so it is possible to overwrite them. + + Troubleshooting --------------- At first the postgres daemon writes its logs to the standard output, so these are available in the container log. The log can be examined by running: diff --git a/9.4/root/usr/share/container-scripts/postgresql/common.sh b/9.4/root/usr/share/container-scripts/postgresql/common.sh index cd1aed8f..6ba804a5 100644 --- a/9.4/root/usr/share/container-scripts/postgresql/common.sh +++ b/9.4/root/usr/share/container-scripts/postgresql/common.sh @@ -190,21 +190,6 @@ function create_users() { fi } -function set_passwords() { - if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then - psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" - fi - - if [ -v POSTGRESQL_MASTER_USER ]; then - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" - fi - - if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then - psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" - fi -} - migrate_db () { test "$postinitdb_actions" = ",migration" || return 0 @@ -413,3 +398,32 @@ try_pgupgrade () run_pgupgrade } + +# get_matched_files finds file for image extending +function get_matched_files() { + local custom_dir default_dir + custom_dir="$1" + default_dir="$2" + files_matched="$3" + find "$default_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" + [ -d "$custom_dir" ] && find "$custom_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" +} + +# process_extending_files process extending files in $1 and $2 directories +# - source all *.sh files +# (if there are files with same name source only file from $1) +function process_extending_files() { + local custom_dir default_dir + custom_dir=$1 + default_dir=$2 + + while read filename ; do + echo "=> sourcing $filename ..." + # Custom file is prefered + if [ -f $custom_dir/$filename ]; then + source $custom_dir/$filename + elif [ -f $default_dir/$filename ]; then + source $default_dir/$filename + fi + done <<<"$(get_matched_files "$custom_dir" "$default_dir" '*.sh' | sort -u)" +} diff --git a/9.4/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh b/9.4/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh new file mode 100644 index 00000000..a087a687 --- /dev/null +++ b/9.4/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +shopt -s nullglob + +cat >> "$PGDATA/postgresql.conf" <> $PGDATA/postgresql.conf +done diff --git a/9.4/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh b/9.4/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh new file mode 100644 index 00000000..f14ff46a --- /dev/null +++ b/9.4/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then +psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" +fi + +if [ -v POSTGRESQL_MASTER_USER ]; then +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" +fi + +if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then +psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" +fi diff --git a/9.4/s2i/bin/assemble b/9.4/s2i/bin/assemble new file mode 100755 index 00000000..c1472bdc --- /dev/null +++ b/9.4/s2i/bin/assemble @@ -0,0 +1,14 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +shopt -s dotglob +echo "---> Installing application source ..." + + +mv /tmp/src/* ./ + +# Fix source directory permissions +/usr/libexec/fix-permissions ./ diff --git a/9.4/s2i/bin/run b/9.4/s2i/bin/run new file mode 120000 index 00000000..a7f4076b --- /dev/null +++ b/9.4/s2i/bin/run @@ -0,0 +1 @@ +/usr/bin/run-postgresql \ No newline at end of file diff --git a/9.4/s2i/bin/usage b/9.4/s2i/bin/usage new file mode 100755 index 00000000..9f413123 --- /dev/null +++ b/9.4/s2i/bin/usage @@ -0,0 +1 @@ +groff -t -man -ETascii /help.1 diff --git a/9.5/Dockerfile b/9.5/Dockerfile index f1a2dbc8..ee9cfe50 100644 --- a/9.5/Dockerfile +++ b/9.5/Dockerfile @@ -1,4 +1,4 @@ -FROM centos:centos7 +FROM centos/s2i-core-centos7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM centos:centos7 ENV POSTGRESQL_VERSION=9.5 \ POSTGRESQL_PREV_VERSION=9.4 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -55,6 +56,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql95 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -65,6 +67,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/9.5/Dockerfile.rhel7 b/9.5/Dockerfile.rhel7 index a7e5eeb9..3e70d2f3 100644 --- a/9.5/Dockerfile.rhel7 +++ b/9.5/Dockerfile.rhel7 @@ -1,4 +1,4 @@ -FROM rhel7 +FROM rhscl/s2i-core-rhel7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM rhel7 ENV POSTGRESQL_VERSION=9.5 \ POSTGRESQL_PREV_VERSION=9.4 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -60,6 +61,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql95 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -70,6 +72,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/9.5/root/usr/bin/run-postgresql b/9.5/root/usr/bin/run-postgresql index af6ac4a1..896e6899 100755 --- a/9.5/root/usr/bin/run-postgresql +++ b/9.5/root/usr/bin/run-postgresql @@ -24,10 +24,13 @@ fi pg_ctl -w start -o "-h ''" if $PG_INITIALIZED ; then + process_extending_files ${APP_DATA}/src/postgresql-init ${CONTAINER_SCRIPTS_PATH}/postgresql-init migrate_db create_users fi -set_passwords + +process_extending_files ${APP_DATA}/src/postgresql-start-hook ${CONTAINER_SCRIPTS_PATH}/postgresql-start-hook + pg_ctl stop unset_env_vars diff --git a/9.5/root/usr/share/container-scripts/postgresql/README.md b/9.5/root/usr/share/container-scripts/postgresql/README.md index ac5c05a2..b2ceb8aa 100644 --- a/9.5/root/usr/share/container-scripts/postgresql/README.md +++ b/9.5/root/usr/share/container-scripts/postgresql/README.md @@ -235,6 +235,45 @@ enough space for the copy; upgrade failure because of not enough space might lead to data loss. +Extending image +---------------- + +This image can be extended using +[source-to-image](https://github.com/openshift/source-to-image). + +For example to build customized image `new-postgresql` +with configuration in `~/image-configuration/` run: + + +``` +$ s2i build ~/image-configuration/ postgresql new-postgresql +``` + +The directory passed to `s2i build` should contain one or more of the +following directories: + +##### `postgresql-config/` + +contained configuration files (`*.conf`) will be included at the end of image postgresql.conf file during database initialization + + +##### `postgresql-init/` + +contained shell scripts (`*.sh`) are sourced once, when database is initialized + +##### `postgresql-start-hook/` + +contained shell scripts (`*.sh`) are sourced before every start + +---------------------------------------------- + +During `s2i build` all provided files are copied into `/opt/app-root/src` +directory in the new image. Only one +file with the same name can be used for customization and user provided files +are preferred over default files in `/usr/share/container-scripts/`- +so it is possible to overwrite them. + + Troubleshooting --------------- At first the postgres daemon writes its logs to the standard output, so these are available in the container log. The log can be examined by running: diff --git a/9.5/root/usr/share/container-scripts/postgresql/common.sh b/9.5/root/usr/share/container-scripts/postgresql/common.sh index 14413ea4..5fa871be 100644 --- a/9.5/root/usr/share/container-scripts/postgresql/common.sh +++ b/9.5/root/usr/share/container-scripts/postgresql/common.sh @@ -190,21 +190,6 @@ function create_users() { fi } -function set_passwords() { - if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then - psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" - fi - - if [ -v POSTGRESQL_MASTER_USER ]; then - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" - fi - - if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then - psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" - fi -} - migrate_db () { test "$postinitdb_actions" = ",migration" || return 0 @@ -413,3 +398,32 @@ try_pgupgrade () run_pgupgrade } + +# get_matched_files finds file for image extending +function get_matched_files() { + local custom_dir default_dir + custom_dir="$1" + default_dir="$2" + files_matched="$3" + find "$default_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" + [ -d "$custom_dir" ] && find "$custom_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" +} + +# process_extending_files process extending files in $1 and $2 directories +# - source all *.sh files +# (if there are files with same name source only file from $1) +function process_extending_files() { + local custom_dir default_dir + custom_dir=$1 + default_dir=$2 + + while read filename ; do + echo "=> sourcing $filename ..." + # Custom file is prefered + if [ -f $custom_dir/$filename ]; then + source $custom_dir/$filename + elif [ -f $default_dir/$filename ]; then + source $default_dir/$filename + fi + done <<<"$(get_matched_files "$custom_dir" "$default_dir" '*.sh' | sort -u)" +} diff --git a/9.5/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh b/9.5/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh new file mode 100644 index 00000000..a087a687 --- /dev/null +++ b/9.5/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +shopt -s nullglob + +cat >> "$PGDATA/postgresql.conf" <> $PGDATA/postgresql.conf +done diff --git a/9.5/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh b/9.5/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh new file mode 100644 index 00000000..f14ff46a --- /dev/null +++ b/9.5/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then +psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" +fi + +if [ -v POSTGRESQL_MASTER_USER ]; then +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" +fi + +if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then +psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" +fi diff --git a/9.5/s2i/bin/assemble b/9.5/s2i/bin/assemble new file mode 100755 index 00000000..c1472bdc --- /dev/null +++ b/9.5/s2i/bin/assemble @@ -0,0 +1,14 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +shopt -s dotglob +echo "---> Installing application source ..." + + +mv /tmp/src/* ./ + +# Fix source directory permissions +/usr/libexec/fix-permissions ./ diff --git a/9.5/s2i/bin/run b/9.5/s2i/bin/run new file mode 120000 index 00000000..a7f4076b --- /dev/null +++ b/9.5/s2i/bin/run @@ -0,0 +1 @@ +/usr/bin/run-postgresql \ No newline at end of file diff --git a/9.5/s2i/bin/usage b/9.5/s2i/bin/usage new file mode 100755 index 00000000..9f413123 --- /dev/null +++ b/9.5/s2i/bin/usage @@ -0,0 +1 @@ +groff -t -man -ETascii /help.1 diff --git a/Dockerfile.template b/Dockerfile.template index ece6ead3..dca37509 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -1,4 +1,4 @@ -FROM {{ config.docker.from }} +FROM {{ spec.s2i_base }} # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM {{ config.docker.from }} ENV POSTGRESQL_VERSION={{ spec.version }} \ POSTGRESQL_PREV_VERSION={{ spec.prev_version }} \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -67,6 +68,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS={{ spec.enabled_collection }} COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -77,6 +79,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/examples/extending-image/postgresql-config/s2i-extending.conf b/examples/extending-image/postgresql-config/s2i-extending.conf new file mode 100644 index 00000000..668142b2 --- /dev/null +++ b/examples/extending-image/postgresql-config/s2i-extending.conf @@ -0,0 +1,4 @@ +log_destination = 'stderr' +logging_collector = on +log_directory = 'pg_log' +log_filename = 'postgresql.log' diff --git a/examples/extending-image/postgresql-start-hook/set_passwords.sh b/examples/extending-image/postgresql-start-hook/set_passwords.sh new file mode 100644 index 00000000..9388e5b3 --- /dev/null +++ b/examples/extending-image/postgresql-start-hook/set_passwords.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# postgresql image encrypts user passwords at service start +# the functionality can be disabled by providing this file (postgresql-start-hook/set_passwords.sh) in s2i build diff --git a/latest/Dockerfile b/latest/Dockerfile index fadd1f64..2c71ee14 100644 --- a/latest/Dockerfile +++ b/latest/Dockerfile @@ -1,4 +1,4 @@ -FROM centos:centos7 +FROM centos/s2i-core-centos7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM centos:centos7 ENV POSTGRESQL_VERSION=9.6 \ POSTGRESQL_PREV_VERSION=9.5 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -57,6 +58,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql96 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -67,6 +69,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/latest/Dockerfile.rhel7 b/latest/Dockerfile.rhel7 index b8b6a094..d3580098 100644 --- a/latest/Dockerfile.rhel7 +++ b/latest/Dockerfile.rhel7 @@ -1,4 +1,4 @@ -FROM rhel7 +FROM rhscl/s2i-core-rhel7 # PostgreSQL image for OpenShift. # Volumes: @@ -13,7 +13,8 @@ FROM rhel7 ENV POSTGRESQL_VERSION=9.6 \ POSTGRESQL_PREV_VERSION=9.5 \ HOME=/var/lib/pgsql \ - PGUSER=postgres + PGUSER=postgres \ + APP_DATA=/opt/app-root ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \ DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \ @@ -60,6 +61,7 @@ ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql \ ENABLED_COLLECTIONS=rh-postgresql96 COPY root / +COPY ./s2i/bin/ $STI_SCRIPTS_PATH # When bash is started non-interactively, to run a shell script, for example it # looks for this variable and source the content of this file. This will enable @@ -70,6 +72,11 @@ ENV BASH_ENV=${CONTAINER_SCRIPTS_PATH}/scl_enable \ VOLUME ["/var/lib/pgsql/data"] +# {APP_DATA} needs to be accessed by postgres user while s2i assembling +# postgres user changes permissions of files in APP_DATA during assembling +RUN /usr/libexec/fix-permissions ${APP_DATA} && \ + usermod -a -G root postgres + USER 26 ENTRYPOINT ["container-entrypoint"] diff --git a/latest/root/usr/bin/run-postgresql b/latest/root/usr/bin/run-postgresql index af6ac4a1..896e6899 100755 --- a/latest/root/usr/bin/run-postgresql +++ b/latest/root/usr/bin/run-postgresql @@ -24,10 +24,13 @@ fi pg_ctl -w start -o "-h ''" if $PG_INITIALIZED ; then + process_extending_files ${APP_DATA}/src/postgresql-init ${CONTAINER_SCRIPTS_PATH}/postgresql-init migrate_db create_users fi -set_passwords + +process_extending_files ${APP_DATA}/src/postgresql-start-hook ${CONTAINER_SCRIPTS_PATH}/postgresql-start-hook + pg_ctl stop unset_env_vars diff --git a/latest/root/usr/share/container-scripts/postgresql/README.md b/latest/root/usr/share/container-scripts/postgresql/README.md index 9bb5d352..a2395ec9 100644 --- a/latest/root/usr/share/container-scripts/postgresql/README.md +++ b/latest/root/usr/share/container-scripts/postgresql/README.md @@ -235,6 +235,45 @@ enough space for the copy; upgrade failure because of not enough space might lead to data loss. +Extending image +---------------- + +This image can be extended using +[source-to-image](https://github.com/openshift/source-to-image). + +For example to build customized image `new-postgresql` +with configuration in `~/image-configuration/` run: + + +``` +$ s2i build ~/image-configuration/ postgresql new-postgresql +``` + +The directory passed to `s2i build` should contain one or more of the +following directories: + +##### `postgresql-config/` + +contained configuration files (`*.conf`) will be included at the end of image postgresql.conf file during database initialization + + +##### `postgresql-init/` + +contained shell scripts (`*.sh`) are sourced once, when database is initialized + +##### `postgresql-start-hook/` + +contained shell scripts (`*.sh`) are sourced before every start + +---------------------------------------------- + +During `s2i build` all provided files are copied into `/opt/app-root/src` +directory in the new image. Only one +file with the same name can be used for customization and user provided files +are preferred over default files in `/usr/share/container-scripts/`- +so it is possible to overwrite them. + + Troubleshooting --------------- At first the postgres daemon writes its logs to the standard output, so these are available in the container log. The log can be examined by running: diff --git a/latest/root/usr/share/container-scripts/postgresql/common.sh b/latest/root/usr/share/container-scripts/postgresql/common.sh index 5f13d5c7..59c87e69 100644 --- a/latest/root/usr/share/container-scripts/postgresql/common.sh +++ b/latest/root/usr/share/container-scripts/postgresql/common.sh @@ -190,21 +190,6 @@ function create_users() { fi } -function set_passwords() { - if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then - psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" - fi - - if [ -v POSTGRESQL_MASTER_USER ]; then - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" - psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" - fi - - if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then - psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" - fi -} - migrate_db () { test "$postinitdb_actions" = ",migration" || return 0 @@ -413,3 +398,32 @@ try_pgupgrade () run_pgupgrade } + +# get_matched_files finds file for image extending +function get_matched_files() { + local custom_dir default_dir + custom_dir="$1" + default_dir="$2" + files_matched="$3" + find "$default_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" + [ -d "$custom_dir" ] && find "$custom_dir" -maxdepth 1 -type f -name "$files_matched" -printf "%f\n" +} + +# process_extending_files process extending files in $1 and $2 directories +# - source all *.sh files +# (if there are files with same name source only file from $1) +function process_extending_files() { + local custom_dir default_dir + custom_dir=$1 + default_dir=$2 + + while read filename ; do + echo "=> sourcing $filename ..." + # Custom file is prefered + if [ -f $custom_dir/$filename ]; then + source $custom_dir/$filename + elif [ -f $default_dir/$filename ]; then + source $default_dir/$filename + fi + done <<<"$(get_matched_files "$custom_dir" "$default_dir" '*.sh' | sort -u)" +} diff --git a/latest/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh b/latest/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh new file mode 100644 index 00000000..a087a687 --- /dev/null +++ b/latest/root/usr/share/container-scripts/postgresql/postgresql-init/set-config.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +shopt -s nullglob + +cat >> "$PGDATA/postgresql.conf" <> $PGDATA/postgresql.conf +done diff --git a/latest/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh b/latest/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh new file mode 100644 index 00000000..f14ff46a --- /dev/null +++ b/latest/root/usr/share/container-scripts/postgresql/postgresql-start-hook/set_passwords.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then +psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';" +fi + +if [ -v POSTGRESQL_MASTER_USER ]; then +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;" +psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';" +fi + +if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then +psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';" +fi diff --git a/latest/s2i/bin/assemble b/latest/s2i/bin/assemble new file mode 100755 index 00000000..c1472bdc --- /dev/null +++ b/latest/s2i/bin/assemble @@ -0,0 +1,14 @@ +#!/bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +shopt -s dotglob +echo "---> Installing application source ..." + + +mv /tmp/src/* ./ + +# Fix source directory permissions +/usr/libexec/fix-permissions ./ diff --git a/latest/s2i/bin/run b/latest/s2i/bin/run new file mode 120000 index 00000000..a7f4076b --- /dev/null +++ b/latest/s2i/bin/run @@ -0,0 +1 @@ +/usr/bin/run-postgresql \ No newline at end of file diff --git a/latest/s2i/bin/usage b/latest/s2i/bin/usage new file mode 100755 index 00000000..9f413123 --- /dev/null +++ b/latest/s2i/bin/usage @@ -0,0 +1 @@ +groff -t -man -ETascii /help.1 diff --git a/specs/multispec.yml b/specs/multispec.yml index 8b997b40..7ac2a6cc 100644 --- a/specs/multispec.yml +++ b/specs/multispec.yml @@ -5,6 +5,7 @@ specs: centos: distros: - centos-7-x86_64 + s2i_base: centos/s2i-core-centos7 org: "centos" prod: "centos7" repo_enable_reason: "" @@ -17,6 +18,7 @@ specs: rhel7: distros: - rhel-7-x86_64 + s2i_base: rhscl/s2i-core-rhel7 org: "rhscl" prod: "rhel7" repo_enable_reason: |- diff --git a/test/run_test b/test/run_test index a1f2f9b8..8c645812 100755 --- a/test/run_test +++ b/test/run_test @@ -24,6 +24,7 @@ run_change_password_test run_replication_test run_master_restart_test run_doc_test +run_s2i_test " test $# -eq 1 -a "${1-}" == --list && echo "$TEST_LIST" && exit 0 @@ -34,6 +35,8 @@ test -n "${OS-}" || false 'make sure $OS is defined' CIDFILE_DIR=$(mktemp --suffix=postgresql_test_cidfiles -d) volumes_to_clean= +s2i_test_app_dir="$(mktemp -d)" +test_dir="$(readlink -f "$(dirname "$0")")" function cleanup() { for cidfile in $CIDFILE_DIR/* ; do @@ -53,6 +56,8 @@ function cleanup() { rmdir $CIDFILE_DIR ct_path_foreach "$volumes_to_clean" cleanup_volume_dir + + test -d "$s2i_test_app_dir" && rm -rf "$s2i_test_app_dir" } trap cleanup EXIT @@ -558,6 +563,56 @@ run_doc_test() { echo } +_s2i_test_image() { + local container_name="$1" + local mount_opts="$2" + echo " Testing s2i app image with invalid configuration" + assert_container_creation_fails -e POSTGRESQL_PASSWORD=pass -e POSTGRESQL_DATABASE=db + echo " Testing s2i app image with correct configuration" + + DOCKER_ARGS=" +-e POSTGRESQL_DATABASE=db +-e POSTGRESQL_USER=user +-e POSTGRESQL_PASSWORD=password +-e POSTGRESQL_ADMIN_PASSWORD=password +-e POSTGRESQL_BACKUP_USER=backuser +-e POSTGRESQL_BACKUP_PASSWORD=pass +${mount_opts} +" create_container "$container_name" + + + # need to set these because `postgresql_cmd` relies on global variables + PGUSER=user + PASS=password + + # need this to wait for the container to start up + CONTAINER_IP=$(get_container_ip "${container_name}") + test_connection "$container_name" + + docker stop "$(get_cid $container_name)" >/dev/null +} + +run_s2i_test() { + echo " Testing s2i usage" + s2i usage --pull-policy=never "${IMAGE_NAME}" &>/dev/null + + echo " Testing s2i build" + s2i build "file://${test_dir}/test-app" "${IMAGE_NAME}" "${IMAGE_NAME}-testapp" + local image_name_backup="${IMAGE_NAME}" + export IMAGE_NAME="${IMAGE_NAME}-testapp" + + local container_name=s2i_config_build + _s2i_test_image "s2i_config_build" "" + + # return back original value for IMAGE_NAME + export IMAGE_NAME="${image_name_backup}" + + echo " Testing s2i mount" + cp -Lr "${test_dir}/test-app" "${s2i_test_app_dir}/" + _s2i_test_image "_s2i_test_mount" "-v ${s2i_test_app_dir}/test-app:/opt/app-root/src/:z" + echo " Success!" +} + function run_general_tests() { PGUSER=user PASS=pass POSTGRESQL_MAX_CONNECTIONS=42 POSTGRESQL_MAX_PREPARED_TRANSACTIONS=42 POSTGRESQL_SHARED_BUFFERS=64MB run_tests no_admin PGUSER=user1 PASS=pass1 ADMIN_PASS=r00t run_tests admin diff --git a/test/test-app/postgresql-init/backup_user.sh b/test/test-app/postgresql-init/backup_user.sh new file mode 100644 index 00000000..a1ac6535 --- /dev/null +++ b/test/test-app/postgresql-init/backup_user.sh @@ -0,0 +1,8 @@ +# Check that user credentials for backup is set + +[[ -v POSTGRESQL_BACKUP_USER && -v POSTGRESQL_BACKUP_PASSWORD ]] || usage "You have to set all variables for user for doing backup: POSTGRESQL_BACKUP_USER, POSTGRESQL_BACKUP_PASSWORD" + +# create backup user + +psql -c "CREATE USER $POSTGRESQL_BACKUP_USER SUPERUSER password '$POSTGRESQL_BACKUP_PASSWORD';" +psql -c "ALTER USER $POSTGRESQL_BACKUP_USER set default_transaction_read_only = on;"