Compare commits

...
Sign in to create a new pull request.

27 commits

Author SHA1 Message Date
Nils Philippsen
0b7e8de26c remove docbook-utils build dependency
This and related packages have been moved to common-build-dependencies.

closes #1
2017-06-20 17:00:27 +02:00
Nils Philippsen
a2bd981032 tests/rpm: use Fedora 26 Boltron Server repo 2017-05-31 15:43:54 +02:00
Nils Philippsen
a2eef8062b tests/rpm: initialize database first 2017-05-31 15:43:35 +02:00
Nils Philippsen
e0dc694125 add tcl-pgtcl:f26 (runtime dep for postgresql-pltcl) 2017-05-30 11:06:36 +02:00
Nils Philippsen
5157eada71 add Makefiles 2017-05-26 15:32:57 +02:00
Nils Philippsen
fcb7466f35 tests: hold off until daemon is available
The postgresql container initializes DB files e.a. in these tests, this
can take a couple of seconds. Try contacting it for up to 20 seconds,
and only then run the tests: create a table, store something in it and
retrieve it again.
2017-05-24 16:35:30 +02:00
Nils Philippsen
f3e435ec35 tests: check for up to 20s if postgresql is running
Grep for the whole path of the binary because its basename is the same
as the name of the user all this is running under.
2017-05-24 16:35:30 +02:00
Nils Philippsen
b4193a89b7 tests/rpm: check status of correct service 2017-05-24 16:35:30 +02:00
Petr Šabata
14eb0cd14c Rebuilding for f26 signing
Signed-off-by: Petr Šabata <contyk@redhat.com>
2017-05-24 10:56:04 +02:00
Nils Philippsen
9c069c4141 add files for modularity-testing-framework based tests
Currently there seems to be an issue with passing the test command line
to the shell in the container, though.
2017-05-19 19:31:05 +02:00
Nils Philippsen
1ae18a54f9 bring in line with github.com/container-images
- use baseruntime:latest as base image
- reimplement cgroup-limits in shell
- take real memory size into account for configuration
- don't use nss_wrapper.so
- don't reference separate shared-userspace repo
- fix usage label
- get rid of /var/lib/psql <-> .../data distinction
- drop a few unused files from root/
2017-05-19 11:46:10 +02:00
Nils Philippsen
058779a5d5 weed out unnecessary components
Several components are carried by modules lower in the stack now
(shared-userspace, common-build-dependencies, base-runtime).
2017-05-18 11:37:07 +02:00
Nils Philippsen
fa7e7e5dec add files for building containter artifacts
Lifted in large parts from version 9.5 of the SCL postgresql container.

https://github.com/sclorg/postgresql-container
2017-05-11 17:34:28 +02:00
Nils Philippsen
8161155280 use perl:f26 again 2017-04-27 18:11:34 +02:00
Nils Philippsen
9362e1ab03 use perl:master until we have a working f26 module
The perl module built fine in f26, but isn't flagged as 'active' in PDC,
i.e. not available for subsequent builds. This needs to be reverted and
requires a rebuild when PDC is fixed.
2017-04-27 15:29:20 +02:00
Nils Philippsen
1e402a48e3 amend postgresql private branch comment 2017-04-27 11:18:52 +02:00
Nils Philippsen
c0f73c53af tidy up build order 2017-04-27 10:41:19 +02:00
Nils Philippsen
e7715dc4ea remove elinks-induced cruft 2017-04-27 10:40:06 +02:00
Nils Philippsen
c3172dfc8f drill down the dependency rabbit hole 2017-04-27 10:37:36 +02:00
Nils Philippsen
7575406d3a use shared-userspace module for python2 dep 2017-04-27 10:37:36 +02:00
Nils Philippsen
9fe61a6e45 use modularity-tainted branch of postgresql
It doesn't need systemtap for building, which pulls in lots of other crud.
2017-04-27 10:37:13 +02:00
Nils Philippsen
b7e34e62a9 mention source package in rationale 2017-04-27 10:37:13 +02:00
Nils Philippsen
966765906b actually add the postgresql component, d'oh 2017-04-27 10:37:13 +02:00
Nils Philippsen
036b9515cb require c-b-d-bootstrap module for building 2017-04-27 10:37:13 +02:00
Nils Philippsen
0c4a8d07ca make uuid find perl-Data-UUID
Tack a buildorder on uuid and sort the components by build order.
2017-04-27 10:36:02 +02:00
Nils Philippsen
9e73316a6c add perl-Data-UUID as component
uuid needs it for building
2017-04-27 10:36:02 +02:00
Petr "Stone" Hracek
21ae3f4ea0 Using f26 tags
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-20 12:49:17 +02:00
19 changed files with 819 additions and 6 deletions

99
Dockerfile Normal file
View file

@ -0,0 +1,99 @@
# Container artifact for the PostgreSQL module
# This should probably rather be something like...:
# FROM registry.fedoraproject.org/module-base-runtime:26
# ...and probably would:
# - not have any repositories configured
# - need a shared-userspace module repo enabled
FROM baseruntime/baseruntime:latest
# PostgreSQL container image
# Exposed ports:
# * 5432/tcp - postgres
# Volumes:
# * /var/lib/psql/data - Database cluster for PostgreSQL
ENV NAME=postgresql \
VERSION=0 \
RELEASE=1 \
ARCH=x86_64 \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
POSTGRESQL_VERSION=9.6 \
HOME=/var/lib/pgsql \
PGUSER=postgres \
POSTGRESQL_MODULE_HASH=d87b0b15567e47f3
LABEL summary = "PostgreSQL is an object-relational DBMS." \
name = "$FGC/$NAME" \
version = "$VERSION" \
release="$RELEASE.$DISTTAG" \
architecture = "$ARCH" \
maintainer = "Nils Philippsen <nils@redhat.com>" \
description = "PostgreSQL is an advanced Object-Relational database management system (DBMS). This container contains the programs needed to create and run a PostgreSQL server, which will in turn allow you to create and maintain PostgreSQL databases." \
vendor="Fedora Project" \
com.redhat.component="$NAME" \
org.fedoraproject.component="postgresql" \
authoritative-source-url="registry.fedoraproject.org" \
usage="docker run -v <dbroot_path>:/var/lib/pgsql:Z -p 5432:5432 -e POSTGRESQL_USER=<user> -e POSTGRESQL_PASSWORD=<password> -e POSTGRESQL_DATABASE=<database> modularitycontainers/postgresql" \
io.k8s.description = "PostgreSQL is an advanced Object-Relational database management system (DBMS). This container contains the programs needed to create and run a PostgreSQL server, which will in turn allow you to create and maintain PostgreSQL databases." \
io.k8s.display-name="PostgreSQL ${POSTGRESQL_VERSION}" \
io.openshift.tags="database,postgresql,postgresql96" \
io.openshift.expose-services="5432/tcp:postgres"
EXPOSE 5432
ADD root /
COPY module-postgresql.repo.in /tmp/module-postgresql.repo.in
COPY run_tests.sh /usr/bin/run_tests.sh
# Install the postgresql server component.
#
# This image must forever use UID 26 for postgres user so our volumes are
# safe in the future. This should *never* change, the last test is there
# to make sure of that.
# Notes about the below:
# - first sed cmd: don't ask
# - rpm -e ... microdnf install systemd: workaround to missing
# microdnf downgrade/distro-sync
# - Update packages so everything available is current
# - Need to have charset files, disable normal repo(s), enable module repo(s)
# ORCHESTRATION:
# - Newer versions of the shared-userspace module are supposed to have
# findutils, not there yet
# - gettext: /usr/bin/envsubst
# - no working python module yet
RUN \
sed -i 's|/jkaluza/|/ralph/|g' /etc/yum.repos.d/build.repo && \
rpm -e --justdb --nodeps systemd-libs && \
microdnf install -y --setopt=tsflags=nodocs systemd && \
# microdnf update -y --setopt=tsflags=nodocs && \
# microdnf install -y glibc-locale-source && \
microdnf install -y findutils && \
microdnf install -y gettext && \
# microdnf install -y nss_wrapper && \
# microdnf install -y /usr/bin/python && \
sed 's|@POSTGRESQL_MODULE_HASH@|'${POSTGRESQL_MODULE_HASH}'|g; s|${basearch}|'${ARCH}'|g' < /tmp/module-postgresql.repo.in > /etc/yum.repos.d/module-postgresql.repo && rm -f /tmp/module-postgresql.repo.in && \
INSTALL_PKGS="postgresql postgresql-server" && \
microdnf install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
rpm -V $INSTALL_PKGS && \
microdnf -y clean all && \
# localedef -f UTF-8 -i en_US en_US.UTF-8 && \
test "$(id postgres)" = "uid=26(postgres) gid=26(postgres) groups=26(postgres)" && \
mkdir -p /var/lib/pgsql/data && \
/usr/libexec/fix-permissions /var/lib/pgsql && \
/usr/libexec/fix-permissions /var/run/postgresql
# Get prefix path and path to scripts rather than hard-code them in scripts
ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql
VOLUME ["/var/lib/pgsql"]
USER 26
ENTRYPOINT ["container-entrypoint"]
CMD ["run-postgresql"]

15
Makefile Normal file
View file

@ -0,0 +1,15 @@
IMAGE_NAME = modularitycontainers/postgresql
MODULEMDURL=file://postgresql.yaml
default: run
build:
docker build --tag=$(IMAGE_NAME) .
run: build
docker run -it -p 80:80 $(IMAGE_NAME)
test: build
cd tests; MODULE=docker MODULEMD=$(MODULEMDURL) URL="docker=$(IMAGE_NAME)" make all
cd tests; MODULE=rpm MODULEMD=$(MODULEMDURL) URL="docker=$(IMAGE_NAME)" make all

41
README.md Normal file
View file

@ -0,0 +1,41 @@
# PostgreSQL
PostgreSQL is an object-relational Database Management System.
This is based on the SCL container image for version 9.5 at:
https://github.com/sclorg/postgresql-container
## Configuration
You must either specify the following environment variables:
* POSTGRESQL_USER
* POSTGRESQL_PASSWORD
* POSTGRESQL_DATABASE
Or the following environment variable:
* POSTGRESQL_ADMIN_PASSWORD
Or both.
Optional settings:
* POSTGRESQL_MAX_CONNECTIONS (default: 100)
* POSTGRESQL_MAX_PREPARED_TRANSACTIONS (default: 0)
* POSTGRESQL_SHARED_BUFFERS (default: 32MB)
## Running in docker
```
docker run -v <dbroot_path>:/var/lib/pgsql:Z -p 5432:5432 -e POSTGRESQL_USER=<user> -e POSTGRESQL_PASSWORD=<password> -e POSTGRESQL_DATABASE=<database> modularitycontainers/postgresql
```
Substitute these placeholders with real values:
* `dbroot_path` - path to the database root on the host which should be mounted
on `/var/lib/pgsql` in the container. Note that the `postgres` user (uid 26)
needs to be able to read and write in that directory.
* `user`, `password`, `database` - details with which a database and user
should be created if the database cluster directory isn't initialized yet.

View file

@ -0,0 +1,5 @@
[module-postgresql]
name=Repository for the PostgreSQL module
baseurl=https://kojipkgs.fedoraproject.org/repos/module-@POSTGRESQL_MODULE_HASH@-build/latest/${basearch}/
enabled=1
gpgcheck=0

View file

@ -18,11 +18,13 @@ data:
- PostgreSQL - PostgreSQL
dependencies: dependencies:
buildrequires: buildrequires:
base-runtime: master base-runtime: f26
common-build-dependencies: master common-build-dependencies: f26
perl: master common-build-dependencies-bootstrap: f26
shared-userspace: f26
perl: f26
requires: requires:
base-runtime: master base-runtime: f26
api: api:
rpms: rpms:
- postgresql - postgresql
@ -36,8 +38,44 @@ data:
filter: {} filter: {}
components: components:
rpms: rpms:
# part of base-runtime:
# gettext
# part of common-build-dependencies: # part of common-build-dependencies:
# multilib-rpm-config, gettext # autoconf(uuid), multilib-rpm-config, docbook-utils
# part of shared-userspace:
# docbook-dtds, docbook-style-dsssl, libxslt, perl-SGMLSpm, python2, tcl
oniguruma:
rationale: 'Build dependency (for slang)'
ref: f26
perl-Data-UUID:
rationale: 'Build dependency (for uuid)'
ref: f26
rsh:
rationale: 'Build dependency (for lynx)'
ref: f26
telnet:
rationale: 'Build dependency (for lynx)'
ref: f26
slang:
buildorder: 1
rationale: 'Build dependency (for lynx)'
ref: f26
uuid: uuid:
rationale: 'Build dependency (for postgresql-contrib).' buildorder: 1
rationale: 'Build dependency (for postgresql).'
ref: f26
lynx:
buildorder: 2
rationale: >-
Build dependency (for postgresql),
ref: f26
postgresql:
buildorder: 3
rationale: 'The API we want to provide.'
# This branch doesn't BR: systemtap(-devel), elinks which pulls in
# loads of other junk
ref: private-f27-modules
tcl-pgtcl:
buildorder: 4
rationale: 'Runtime dependency (for postgresql-pltcl)'
ref: f26 ref: f26

99
root/usr/bin/cgroup-limits Executable file
View file

@ -0,0 +1,99 @@
#!/bin/bash
# Script for parsing cgroup information
#
# This script will read some limits from the cgroup system and parse
# them, printing out "VARIABLE=VALUE" on each line for every limit that is
# successfully read. Output of this script can be directly fed into
# bash's export command. Recommended usage from a bash script:
#
# set -o errexit
# export_vars=$(cgroup-limits) ; export $export_vars
#
# Variables currently supported:
# MAX_MEMORY_LIMIT_IN_BYTES
# Maximum possible limit MEMORY_LIMIT_IN_BYTES can have. This is
# currently a constant value of 9223372036854775807.
# MEMORY_LIMIT_IN_BYTES
# Maximum amount of user memory in bytes. If this value is set
# to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that
# there is no limit set. The value is taken from
# /sys/fs/cgroup/memory/memory.limit_in_bytes
# RAM_SIZE_IN_BYTES
# Available memory in bytes. The value is taken from /proc/meminfo.
# NUMBER_OF_CORES
# Number of detected CPU cores that can be used. This value is
# calculated from /sys/fs/cgroup/cpuset/cpuset.cpus
# NO_MEMORY_LIMIT
# Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller
# can act as if no memory limit was set. Undefined otherwise.
get_memory_limit() {
local limit="$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)"
if [ $? -eq 0 ]; then
echo "$limit"
else
echo "Warning: Can't detect memory limit from cgroups" >&2
fi
}
get_meminfo_ram_size() {
local limit="$(cat /proc/meminfo | while read key val unit rest; do if [ "$key" = "MemTotal:" ]; then echo "$val $unit"; break; fi; done)"
if [ $? -eq 0 ]; then
local val="${limit/ *}"
local unit="${limit/* }"
case "$unit" in
kB)
val=$(($val * 1024))
;;
MB)
val=$(($val * 1024 * 1024))
;;
GB)
val=$(($val * 1024 * 1024 * 1024))
;;
esac
echo "$val"
else
echo "Warning: Can't detect RAM site from /proc/meminfo." >&2
fi
}
get_number_of_cores() {
local core_count=0
local group
local sysfs_cpus="$(cat /sys/fs/cgroup/cpuset/cpuset.cpus)"
if [ $? -eq 0 ]; then
for group in ${sysfs_cpus//,/ }; do
local from="${group%-*}"
local to="${group#*-}"
core_count=$(($core_count + $to - $from + 1))
done
echo "$core_count"
else
echo "Warning: Can't detect number of CPU cores from cgroups" >&2
fi
}
MAX_MEMORY_LIMIT_IN_BYTES=9223372036854775807
MEMORY_LIMIT_IN_BYTES="$(get_memory_limit)"
RAM_SIZE_IN_BYTES="$(get_meminfo_ram_size)"
NUMBER_OF_CORES="$(get_number_of_cores)"
echo "MAX_MEMORY_LIMIT_IN_BYTES=$MAX_MEMORY_LIMIT_IN_BYTES"
if [ -n "$MEMORY_LIMIT_IN_BYTES" ]; then
echo "MEMORY_LIMIT_IN_BYTES=$MEMORY_LIMIT_IN_BYTES"
if [ "$MEMORY_LIMIT_IN_BYTES" -ge "$MAX_MEMORY_LIMIT_IN_BYTES" ]; then
echo "NO_MEMORY_LIMIT=true"
fi
fi
if [ -n "$RAM_SIZE_IN_BYTES" ]; then
echo "RAM_SIZE_IN_BYTES=$RAM_SIZE_IN_BYTES"
fi
if [ -n "$NUMBER_OF_CORES" ]; then
echo "NUMBER_OF_CORES=$NUMBER_OF_CORES"
fi

View file

@ -0,0 +1,3 @@
#!/bin/bash
exec "$@"

28
root/usr/bin/run-postgresql Executable file
View file

@ -0,0 +1,28 @@
#!/bin/bash
export ENABLE_REPLICATION=${ENABLE_REPLICATION:-false}
set -eu
export_vars=$(cgroup-limits) ; export $export_vars
source "${CONTAINER_SCRIPTS_PATH}/common.sh"
set_pgdata
check_env_vars
generate_passwd_file
generate_postgresql_config
if [ ! -f "$PGDATA/postgresql.conf" ]; then
initialize_database
NEED_TO_CREATE_USERS=yes
fi
pg_ctl -w start -o "-h ''"
if [ "${NEED_TO_CREATE_USERS:-}" == "yes" ]; then
create_users
fi
set_passwords
pg_ctl stop
unset_env_vars
exec postgres "$@"

View file

@ -0,0 +1,5 @@
#!/bin/bash
export ENABLE_REPLICATION=true
exec run-postgresql "$@"

View file

@ -0,0 +1,36 @@
#!/bin/bash
export ENABLE_REPLICATION=true
set -eu
export_vars=$(cgroup-limits) ; export $export_vars
source "$CONTAINER_SCRIPTS_PATH"/common.sh
set_pgdata
function initialize_replica() {
echo "Initializing PostgreSQL slave ..."
# TODO: Validate and reuse existing data?
rm -rf $PGDATA
PGPASSWORD="${POSTGRESQL_MASTER_PASSWORD}" pg_basebackup -x --no-password --pgdata ${PGDATA} --host=${MASTER_FQDN} --port=5432 -U "${POSTGRESQL_MASTER_USER}"
# PostgreSQL recovery configuration.
generate_postgresql_recovery_config
cat >> "$PGDATA/recovery.conf" <<EOF
# Custom OpenShift recovery configuration:
include '${POSTGRESQL_RECOVERY_FILE}'
EOF
}
check_env_vars
generate_passwd_file
generate_postgresql_config
wait_for_postgresql_master
export MASTER_FQDN=$(postgresql_master_addr)
initialize_replica
unset_env_vars
exec postgres "$@"

View file

@ -0,0 +1,7 @@
#!/bin/sh
# Fix permissions on the given directory to allow group read/write of
# regular files and execute of directories.
find "$1" -exec chown postgres {} \;
find "$1" -exec chgrp 0 {} \;
find "$1" -exec chmod g+rw {} \;
find "$1" -type d -exec chmod g+x {} +

View file

@ -0,0 +1,98 @@
PostgreSQL Docker image
=======================
This repository contains Dockerfiles for PostgreSQL images for general usage and OpenShift.
Users can choose between RHEL and CentOS based images.
Environment variables and volumes
----------------------------------
The image recognizes the following environment variables that you can set during
initialization by passing `-e VAR=VALUE` to the Docker run command.
| Variable name | Description |
| :--------------------------- | ---------------------------------------------- |
| `POSTGRESQL_USER` | User name for PostgreSQL account to be created |
| `POSTGRESQL_PASSWORD` | Password for the user account |
| `POSTGRESQL_DATABASE` | Database name |
| `POSTGRESQL_ADMIN_PASSWORD` | Password for the `postgres` admin account (optional) |
The following environment variables influence the PostgreSQL configuration file. They are all optional.
| Variable name | Description | Default
| :---------------------------- | ----------------------------------------------------------------------- | -------------------------------
| `POSTGRESQL_MAX_CONNECTIONS` | The maximum number of client connections allowed | 100
| `POSTGRESQL_MAX_PREPARED_TRANSACTIONS` | Sets the maximum number of transactions that can be in the "prepared" state. If you are using prepared transactions, you will probably want this to be at least as large as max_connections | 0
| `POSTGRESQL_SHARED_BUFFERS` | Sets how much memory is dedicated to PostgreSQL to use for caching data | 32M
| `POSTGRESQL_EFFECTIVE_CACHE_SIZE` | Set to an estimate of how much memory is available for disk caching by the operating system and within the database itself | 128M
You can also set the following mount points by passing the `-v /host:/container` flag to Docker.
| Volume mount point | Description |
| :----------------------- | ------------------------------------- |
| `/var/lib/pgsql/data` | PostgreSQL database cluster directory |
**Notice: When mouting a directory from the host into the container, ensure that the mounted
directory has the appropriate permissions and that the owner and group of the directory
matches the user UID or name which is running inside the container.**
Usage
----------------------
For this, we will assume that you are using the `openshift/postgresql-92-centos7` image.
If you want to set only the mandatory environment variables and not store the database
in a host directory, execute the following command:
```
$ docker run -d --name postgresql_database -e POSTGRESQL_USER=user -e POSTGRESQL_PASSWORD=pass -e POSTGRESQL_DATABASE=db -p 5432:5432 openshift/postgresql-92-centos7
```
This will create a container named `postgresql_database` running PostgreSQL with
database `db` and user with credentials `user:pass`. Port 5432 will be exposed
and mapped to the host. If you want your database to be persistent across container
executions, also add a `-v /host/db/path:/var/lib/pgsql/data` argument. This will be
the PostgreSQL database cluster directory.
If the database cluster directory is not initialized, the entrypoint script will
first run [`initdb`](http://www.postgresql.org/docs/9.2/static/app-initdb.html)
and setup necessary database users and passwords. After the database is initialized,
or if it was already present, [`postgres`](http://www.postgresql.org/docs/9.2/static/app-postgres.html)
is executed and will run as PID 1. You can stop the detached container by running
`docker stop postgresql_database`.
PostgreSQL auto-tuning
--------------------
When the PostgreSQL image is run with the `--memory` parameter set and if there
are no values provided for `POSTGRESQL_SHARED_BUFFERS` and
`POSTGRESQL_EFFECTIVE_CACHE_SIZE` those values are automatically calculated
based on the value provided in the `--memory` parameter.
The values are calculated based on the
[upstream](https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server)
formulas. For the `shared_buffers` we use 1/4 of given memory and for the
`effective_cache_size` we set the value to 1/2 of the given memory.
PostgreSQL admin account
------------------------
The admin account `postgres` has no password set by default, only allowing local
connections. You can set it by setting the `POSTGRESQL_ADMIN_PASSWORD` environment
variable when initializing your container. This will allow you to login to the
`postgres` account remotely. Local connections will still not require a password.
Changing passwords
------------------
Since passwords are part of the image configuration, the only supported method
to change passwords for the database user (`POSTGRESQL_USER`) and `postgres`
admin user is by changing the environment variables `POSTGRESQL_PASSWORD` and
`POSTGRESQL_ADMIN_PASSWORD`, respectively.
Changing database passwords through SQL statements or any way other than through
the environment variables aforementioned will cause a mismatch between the
values stored in the variables and the actual passwords. Whenever a database
container starts it will reset the passwords to the values stored in the
environment variables.

View file

@ -0,0 +1,225 @@
# Configuration settings.
export POSTGRESQL_MAX_CONNECTIONS=${POSTGRESQL_MAX_CONNECTIONS:-100}
export POSTGRESQL_MAX_PREPARED_TRANSACTIONS=${POSTGRESQL_MAX_PREPARED_TRANSACTIONS:-0}
# Perform auto-tuning based on the container cgroups limits (only when the
# limits are set).
# Users can still override this by setting the POSTGRESQL_SHARED_BUFFERS
# and POSTGRESQL_EFFECTIVE_CACHE_SIZE variables.
if [[ "${NO_MEMORY_LIMIT:-}" == "true" || -z "${MEMORY_LIMIT_IN_BYTES:-}" || -z "${RAM_SIZE_IN_BYTES:-}" ]]; then
export POSTGRESQL_SHARED_BUFFERS=${POSTGRESQL_SHARED_BUFFERS:-32MB}
export POSTGRESQL_EFFECTIVE_CACHE_SIZE=${POSTGRESQL_EFFECTIVE_CACHE_SIZE:-128MB}
else
if [ "$MEMORY_LIMIT_IN_BYTES" -gt "$RAM_SIZE_IN_BYTES" ]; then
mem_limit="$RAM_SIZE_IN_BYTES"
else
mem_limit="$MEMORY_LIMIT_IN_BYTES"
fi
# Use 1/4 of given memory for shared buffers
shared_buffers_computed="$(($mem_limit/1024/1024/4))MB"
# Setting effective_cache_size to 1/2 of total memory would be a normal conservative setting,
effective_cache="$(($mem_limit/1024/1024/2))MB"
export POSTGRESQL_SHARED_BUFFERS=${POSTGRESQL_SHARED_BUFFERS:-$shared_buffers_computed}
export POSTGRESQL_EFFECTIVE_CACHE_SIZE=${POSTGRESQL_EFFECTIVE_CACHE_SIZE:-$effective_cache}
fi
export POSTGRESQL_RECOVERY_FILE=$HOME/openshift-custom-recovery.conf
export POSTGRESQL_CONFIG_FILE=$HOME/openshift-custom-postgresql.conf
postinitdb_actions=
psql_identifier_regex='^[a-zA-Z_][a-zA-Z0-9_]*$'
psql_password_regex='^[a-zA-Z0-9_~!@#$%^&*()-=<>,.?;:|]+$'
# match . files when moving userdata below
shopt -s dotglob
# extglob enables the !(userdata) glob pattern below.
shopt -s extglob
function usage() {
if [ $# == 1 ]; then
echo >&2 "error: $1"
fi
cat >&2 <<EOF
You must either specify the following environment variables:
POSTGRESQL_USER (regex: '$psql_identifier_regex')
POSTGRESQL_PASSWORD (regex: '$psql_password_regex')
POSTGRESQL_DATABASE (regex: '$psql_identifier_regex')
Or the following environment variable:
POSTGRESQL_ADMIN_PASSWORD (regex: '$psql_password_regex')
Or both.
Optional settings:
POSTGRESQL_MAX_CONNECTIONS (default: 100)
POSTGRESQL_MAX_PREPARED_TRANSACTIONS (default: 0)
POSTGRESQL_SHARED_BUFFERS (default: 32MB)
For more information see /usr/share/container-scripts/postgresql/README.md
within the container or visit https://github.com/openshift/postgresql.
EOF
exit 1
}
function check_env_vars() {
if [[ -v POSTGRESQL_USER || -v POSTGRESQL_PASSWORD || -v POSTGRESQL_DATABASE ]]; then
# one var means all three must be specified
[[ -v POSTGRESQL_USER && -v POSTGRESQL_PASSWORD && -v POSTGRESQL_DATABASE ]] || usage
[[ "$POSTGRESQL_USER" =~ $psql_identifier_regex ]] || usage
[[ "$POSTGRESQL_PASSWORD" =~ $psql_password_regex ]] || usage
[[ "$POSTGRESQL_DATABASE" =~ $psql_identifier_regex ]] || usage
[ ${#POSTGRESQL_USER} -le 63 ] || usage "PostgreSQL username too long (maximum 63 characters)"
[ ${#POSTGRESQL_DATABASE} -le 63 ] || usage "Database name too long (maximum 63 characters)"
postinitdb_actions+=",simple_db"
fi
if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then
[[ "$POSTGRESQL_ADMIN_PASSWORD" =~ $psql_password_regex ]] || usage
postinitdb_actions+=",admin_pass"
fi
case ",$postinitdb_actions," in
*,admin_pass,*|*,simple_db,*) ;;
*) usage ;;
esac
}
# Make sure env variables don't propagate to PostgreSQL process.
function unset_env_vars() {
unset POSTGRESQL_{DATABASE,USER,PASSWORD,ADMIN_PASSWORD}
}
# postgresql_master_addr lookups the 'postgresql-master' DNS and get list of the available
# endpoints. Each endpoint is a PostgreSQL container with the 'master' PostgreSQL running.
function postgresql_master_addr() {
local service_name=${POSTGRESQL_MASTER_SERVICE_NAME:-postgresql-master}
local endpoints=$(dig ${service_name} A +search | grep ";${service_name}" | cut -d ';' -f 2 2>/dev/null)
# FIXME: This is for debugging (docker run)
if [ -v POSTGRESQL_MASTER_IP ]; then
endpoints=${POSTGRESQL_MASTER_IP:-}
fi
if [ -z "$endpoints" ]; then
>&2 echo "Failed to resolve PostgreSQL master IP address"
exit 3
fi
echo -n "$(echo $endpoints | cut -d ' ' -f 1)"
}
# New config is generated every time a container is created. It only contains
# additional custom settings and is included from $PGDATA/postgresql.conf.
function generate_postgresql_config() {
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-postgresql.conf.template" \
> "${POSTGRESQL_CONFIG_FILE}"
if [ "${ENABLE_REPLICATION}" == "true" ]; then
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-postgresql-replication.conf.template" \
>> "${POSTGRESQL_CONFIG_FILE}"
fi
}
function generate_postgresql_recovery_config() {
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-recovery.conf.template" \
> "${POSTGRESQL_RECOVERY_FILE}"
}
# Generate passwd file based on current uid
function generate_passwd_file() {
export USER_ID=$(id -u)
export GROUP_ID=$(id -g)
grep -v ^postgres /etc/passwd > "$HOME/passwd"
echo "postgres:x:${USER_ID}:${GROUP_ID}:PostgreSQL Server:${HOME}:/bin/bash" >> "$HOME/passwd"
#export LD_PRELOAD=libnss_wrapper.so
export NSS_WRAPPER_PASSWD=${HOME}/passwd
export NSS_WRAPPER_GROUP=/etc/group
}
function initialize_database() {
# Initialize the database cluster with utf8 support enabled by default.
# This might affect performance, see:
# http://www.postgresql.org/docs/9.5/static/locale.html
LANG=${LANG:-en_US.utf8} initdb
# PostgreSQL configuration.
cat >> "$PGDATA/postgresql.conf" <<EOF
# Custom OpenShift configuration:
include '${POSTGRESQL_CONFIG_FILE}'
EOF
# Access control configuration.
# FIXME: would be nice-to-have if we could allow connections only from
# specific hosts / subnet
cat >> "$PGDATA/pg_hba.conf" <<EOF
#
# Custom OpenShift configuration starting at this point.
#
# Allow connections from all hosts.
host all all all md5
# Allow replication connections from all hosts.
host replication all all md5
EOF
}
function create_users() {
if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then
createuser "$POSTGRESQL_USER"
createdb --owner="$POSTGRESQL_USER" "$POSTGRESQL_DATABASE"
fi
if [ -v POSTGRESQL_MASTER_USER ]; then
createuser "$POSTGRESQL_MASTER_USER"
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
}
function set_pgdata ()
{
# backwards compatibility case, we used to put the data here,
# move it into our new expected location (userdata)
if [ -e ${HOME}/data/PG_VERSION ]; then
mkdir -p "${HOME}/data/userdata"
pushd "${HOME}/data"
# move everything except the userdata directory itself, into the userdata directory.
mv !(userdata) "userdata"
popd
else
# create a subdirectory that the user owns
mkdir -p "${HOME}/data/userdata"
fi
export PGDATA=$HOME/data/userdata
# ensure sane perms for postgresql startup
chmod 700 "$PGDATA"
}
function wait_for_postgresql_master() {
while true; do
master_fqdn=$(postgresql_master_addr)
echo "Waiting for PostgreSQL master (${master_fqdn}) to accept connections ..."
if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then
PGPASSWORD=${POSTGRESQL_ADMIN_PASSWORD} psql "postgresql://postgres@${master_fqdn}" -c "SELECT 1;" && return 0
else
PGPASSWORD=${POSTGRESQL_PASSWORD} psql "postgresql://${POSTGRESQL_USER}@${master_fqdn}/${POSTGRESQL_DATABASE}" -c "SELECT 1;" && return 0
fi
sleep 1
done
}

View file

@ -0,0 +1,7 @@
# required on master for replication
wal_level = hot_standby # minimal, archive, hot_standby, or logical
max_wal_senders = 6 # max number of walsender processes
wal_keep_segments = 400 # in logfile segments, 16MB each; 0 disables
# required on replicas for replication
hot_standby = on

View file

@ -0,0 +1,21 @@
#
# Custom OpenShift configuration.
#
# NOTE: This file is rewritten every time the container is started!
# Changes to this file will be overwritten.
#
# Listen on all interfaces.
listen_addresses = '*'
# Determines the maximum number of concurrent connections to the database server. Default: 100
max_connections = ${POSTGRESQL_MAX_CONNECTIONS}
# Allow each connection to use a prepared transaction
max_prepared_transactions = ${POSTGRESQL_MAX_PREPARED_TRANSACTIONS}
# Sets the amount of memory the database server uses for shared memory buffers. Default: 32MB
shared_buffers = ${POSTGRESQL_SHARED_BUFFERS}
# Sets the planner's assumption about the effective size of the disk cache that is available to a single query
effective_cache_size = ${POSTGRESQL_EFFECTIVE_CACHE_SIZE}

View file

@ -0,0 +1,9 @@
#
# Custom OpenShift configuration.
#
# NOTE: This file is rewritten every time the container is started!
# Changes to this file will be overwritten.
#
standby_mode = on
primary_conninfo = 'host=${MASTER_FQDN} port=5432 user=${POSTGRESQL_MASTER_USER} password=${POSTGRESQL_MASTER_PASSWORD}'

6
tests/Makefile Normal file
View file

@ -0,0 +1,6 @@
MODULE_LINT=/usr/share/moduleframework/tools/modulelint.py
CMD=python -m avocado run --filter-by-tags=-WIP $(MODULE_LINT) *.py
#
all:
$(CMD)

66
tests/config.yaml Normal file
View file

@ -0,0 +1,66 @@
document: modularity-testing
version: 1
name: postgresql
modulemd-url: https://src.fedoraproject.org/cgit/modules/postgresql.git/tree/postgresql.yaml?h=f26
service:
port: 5432
packages:
rpms:
- postgresql-server
# seq
- coreutils
testdependecies:
rpms:
- postgresql
- systemd
module:
docker:
start: "docker run -it -p 5432:5432 -e POSTGRESQL_USER=mtftest -e POSTGRESQL_PASSWORD=mtftest -e POSTGRESQL_DATABASE=mtftest"
labels:
description: "PostgreSQL is an advanced Object-Relational database management system (DBMS)."
io.k8s.description: "PostgreSQL is an advanced Object-Relational database management system (DBMS)."
source: https://github.com/container-images/postgresql.git
container: docker.io/modularitycontainers/postgresql
rpm:
setup: postgresql-setup initdb
start: systemctl start postgresql
stop: systemctl stop postgresql
status: systemctl status postgresql
repos:
- https://kojipkgs.fedoraproject.org/compose/latest-Fedora-Modular-26/compose/Server/x86_64/os/
test:
process_running:
- |
up=0
for i in `seq 20`; do
echo "Checking for /usr/bin/postgres process... ($i)"
if ls /proc/*/exe -alh 2>/dev/null | grep /usr/bin/postgres; then
echo "Found."
up=1
break
else
sleep 1
fi
done
test "$up" -ne 0
testhost:
db_usable:
- |
export PGPASSWORD=mtftest
PSQL="psql -h localhost -U mtftest -q"
up=0
for i in `seq 20`; do
echo "Pinging PostgreSQL ($i)"
if $PSQL -c "" >&/dev/null; then
up=1
break
else
sleep 1
fi
done
if [ "$up" -eq 1 ]; then
$PSQL -f test.sql | egrep "anything|something"
else
echo "Unable to connect to database." >&2
false
fi

5
tests/test.sql Normal file
View file

@ -0,0 +1,5 @@
CREATE TABLE mtftest (id SERIAL NOT NULL, anything VARCHAR(255) NOT NULL);
INSERT INTO mtftest (anything) VALUES ('something');
SELECT anything FROM mtftest;