Compare commits

..

23 commits

Author SHA1 Message Date
Karsten Hopp
0afe31547e update master hashes 2017-10-20 12:44:21 +02:00
Karsten Hopp
b8b9571938 switch to f27 stream requirements 2017-10-18 10:35:30 +02:00
Karsten Hopp
7541816442 Revert "use older hast for mbs/pdc sync tests"
This reverts commit 5d9488e143.
2017-10-12 13:14:15 +02:00
Karsten Hopp
e733195a45 Revert "use an even older hash for mbs/pdc sync tests"
This reverts commit 8adcc7910f.
2017-10-12 13:13:27 +02:00
Karsten Hopp
8adcc7910f use an even older hash for mbs/pdc sync tests 2017-10-12 12:00:54 +02:00
Karsten Hopp
5d9488e143 use older hast for mbs/pdc sync tests 2017-10-12 11:55:55 +02:00
Karsten Hopp
de62aeaeb5 bump 2017-10-12 11:50:28 +02:00
Karsten Hopp
fce1b50a7a bump and rebuild 2017-10-12 11:16:44 +02:00
Karsten Hopp
71e7d7e417 provide server profile as requested by sct 2017-10-09 16:07:25 +02:00
Nils Philippsen
74b97eac49 remove bogus platform-placeholder dependency 2017-08-25 12:47:05 +02:00
Nils Philippsen
e26462750c pull component packages from f27 2017-08-25 10:54:54 +02:00
Nils Philippsen
a61016ef1a make the description a proper sentence 2017-08-25 10:53:50 +02:00
Nils Philippsen
83452c25e6 reindent again (grrr, tabs) 2017-08-25 10:46:24 +02:00
Nils Philippsen
e090c6f0fe re-add api, profiles 2017-08-25 10:41:03 +02:00
Nils Philippsen
6cdab777aa reindent 2017-08-25 10:40:55 +02:00
Nils Philippsen
0603455e67 import modulemd generated by dependency-report 2017-08-25 10:34:51 +02:00
Radoslav Pitonak
ba9d082c94 Dockerfile based on BRT, test suite for module 2017-05-04 10:50:54 +02:00
Petr "Stone" Hracek
398481abed Add elinks to private-f27-modules
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-24 15:58:56 +02:00
Petr "Stone" Hracek
f964690315 Add common-build-dependencies-bootstrap
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-24 12:25:13 +02:00
Petr "Stone" Hracek
14f7b4ae61 Fix perl dependencies
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-21 11:02:17 +02:00
Petr "Stone" Hracek
ea0fe5cee5 Using proper tag.
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-20 12:29:55 +02:00
Petr "Stone" Hracek
864a6140dc Add perl dependency
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
2017-04-20 12:28:38 +02:00
Nils Philippsen
d30059bccc initial version of the postgresql modulemd file 2017-04-19 20:50:33 +02:00
23 changed files with 1048 additions and 0 deletions

51
Dockerfile Normal file
View file

@ -0,0 +1,51 @@
FROM baseruntime/baseruntime:latest
# PostgreSQL image for OpenShift.
# Volumes:
# * /var/lib/psql/data - Database cluster for PostgreSQL
# Environment:
# * $POSTGRESQL_USER - Database user name
# * $POSTGRESQL_PASSWORD - User's password
# * $POSTGRESQL_DATABASE - Name of the database to create
# * $POSTGRESQL_ADMIN_PASSWORD (Optional) - Password for the 'postgres'
# PostgreSQL administrative account
ENV POSTGRESQL_VERSION=9.5 \
HOME=/var/lib/pgsql \
PGUSER=postgres
LABEL io.k8s.description="PostgreSQL is an advanced Object-Relational database management system" \
io.k8s.display-name="PostgreSQL 9.5" \
io.openshift.expose-services="5432:postgresql" \
io.openshift.tags="database,postgresql,postgresql95" \
com.redhat.component="postgresql" \
maintainer="Pavel Raiskup <praiskup@redhat.com>" \
name="$FCG/postgresql" \
version="0" \
release="1.$DISTTAG" \
architecture="x86_64" \
usage="Run without arguments to get usage info." \
help="/help.1"
EXPOSE 5432
ADD root /
COPY repos/* /etc/yum.repos.d/
RUN microdnf --nodocs --enablerepo postgresql install -y postgresql postgresql-server postgresql-contrib && \
microdnf --nodocs --enablerepo fedora install -y rsync tar gettext bind-utils nss_wrapper findutils python && \
microdnf clean all && \
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/data"]
USER 26
CMD ["run-postgresql"]

15
Makefile Normal file
View file

@ -0,0 +1,15 @@
IMAGE_NAME = postgresql
MODULEMDURL=file://postgresql.yaml
default: run
build:
docker build --tag=$(IMAGE_NAME) .
run: build
docker run -d $(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
postgresql.yaml Normal file
View file

@ -0,0 +1,41 @@
document: modulemd
version: 1
data:
summary: postgresql module
description: This postgresql module has been generated.
license:
module: [ MIT ]
dependencies:
buildrequires:
bootstrap: master
requires:
platform: master
references:
community: https://docs.pagure.org/modularity/
documentation: https://github.com/modularity-modules/postgresql
tracker: https://github.com/modularity-modules/postgresql
api:
rpms:
- postgresql
profiles:
default:
rpms:
- postgresql-server
server:
rpms:
- postgresql-server
client:
rpms:
- postgresql
filter: {}
components:
rpms:
# postgresql-10.0-3.fc28
postgresql:
rationale: Generated.
ref: 07894e0da4b994092abd0084fba982e075ccf3f3
# uuid-1.6.2-39.fc27
uuid:
rationale: Generated.
ref: 43c916caff937bdf8a97ded1abff3e01df4895f4

5
repos/fedora.repo Normal file
View file

@ -0,0 +1,5 @@
[fedora]
name=fedora
baseurl=https://mirrors.nic.cz/fedora/linux/development/26/Everything/x86_64/os/
enabled=0

4
repos/postgresql.repo Normal file
View file

@ -0,0 +1,4 @@
[postgresql]
name=postgresql
baseurl=https://kojipkgs.fedoraproject.org/repos/module-5a0a295c9673c2a1/latest/x86_64/
enabled=0

190
root/help.1 Normal file
View file

@ -0,0 +1,190 @@
.\"t
.\" WARNING: Do not edit this file manually, it is generated from README.md automatically.
.\"
.\"t
.\" Automatically generated by Pandoc 1.16.0.2
.\"
.TH "POSTGRESQL\-95\-RHEL7" "1" "February 22, 2017" "Container Image Pages" ""
.hy
.SH PostgreSQL Docker image
.PP
This repository contains Dockerfiles for PostgreSQL images for general
usage and OpenShift.
Users can choose between RHEL and CentOS based images.
.SS Environment variables and volumes
.PP
The image recognizes the following environment variables that you can
set during initialization by passing \f[C]\-e\ VAR=VALUE\f[] to the
Docker run command.
.PP
.TS
tab(@);
lw(26.7n) lw(43.3n).
T{
Variable name
T}@T{
Description
T}
_
T{
\f[C]POSTGRESQL_USER\f[]
T}@T{
User name for PostgreSQL account to be created
T}
T{
\f[C]POSTGRESQL_PASSWORD\f[]
T}@T{
Password for the user account
T}
T{
\f[C]POSTGRESQL_DATABASE\f[]
T}@T{
Database name
T}
T{
\f[C]POSTGRESQL_ADMIN_PASSWORD\f[]
T}@T{
Password for the \f[C]postgres\f[] admin account (optional)
T}
.TE
.PP
The following environment variables influence the PostgreSQL
configuration file.
They are all optional.
.PP
.TS
tab(@);
lw(15.7n) lw(37.6n) lw(16.7n).
T{
Variable name
T}@T{
Description
T}@T{
Default
T}
_
T{
\f[C]POSTGRESQL_MAX_CONNECTIONS\f[]
T}@T{
The maximum number of client connections allowed
T}@T{
100
T}
T{
\f[C]POSTGRESQL_MAX_PREPARED_TRANSACTIONS\f[]
T}@T{
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
T}@T{
0
T}
T{
\f[C]POSTGRESQL_SHARED_BUFFERS\f[]
T}@T{
Sets how much memory is dedicated to PostgreSQL to use for caching data
T}@T{
32M
T}
T{
\f[C]POSTGRESQL_EFFECTIVE_CACHE_SIZE\f[]
T}@T{
Set to an estimate of how much memory is available for disk caching by
the operating system and within the database itself
T}@T{
128M
T}
.TE
.PP
You can also set the following mount points by passing the
\f[C]\-v\ /host:/container\f[] flag to Docker.
.PP
.TS
tab(@);
l l.
T{
Volume mount point
T}@T{
Description
T}
_
T{
\f[C]/var/lib/pgsql/data\f[]
T}@T{
PostgreSQL database cluster directory
T}
.TE
.PP
\f[B]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.\f[]
.SS Usage
.PP
For this, we will assume that you are using the
\f[C]openshift/postgresql\-92\-centos7\f[] image.
If you want to set only the mandatory environment variables and not
store the database in a host directory, execute the following command:
.IP
.nf
\f[C]
$\ 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
\f[]
.fi
.PP
This will create a container named \f[C]postgresql_database\f[] running
PostgreSQL with database \f[C]db\f[] and user with credentials
\f[C]user:pass\f[].
Port 5432 will be exposed and mapped to the host.
If you want your database to be persistent across container executions,
also add a \f[C]\-v\ /host/db/path:/var/lib/pgsql/data\f[] argument.
This will be the PostgreSQL database cluster directory.
.PP
If the database cluster directory is not initialized, the entrypoint
script will first run
\f[C]initdb\f[] (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,
\f[C]postgres\f[] (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
\f[C]docker\ stop\ postgresql_database\f[].
.SS PostgreSQL auto\-tuning
.PP
When the PostgreSQL image is run with the \f[C]\-\-memory\f[] parameter
set and if there are no values provided for
\f[C]POSTGRESQL_SHARED_BUFFERS\f[] and
\f[C]POSTGRESQL_EFFECTIVE_CACHE_SIZE\f[] those values are automatically
calculated based on the value provided in the \f[C]\-\-memory\f[]
parameter.
.PP
The values are calculated based on the
upstream (https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server)
formulas.
For the \f[C]shared_buffers\f[] we use 1/4 of given memory and for the
\f[C]effective_cache_size\f[] we set the value to 1/2 of the given
memory.
.SS PostgreSQL admin account
.PP
The admin account \f[C]postgres\f[] has no password set by default, only
allowing local connections.
You can set it by setting the \f[C]POSTGRESQL_ADMIN_PASSWORD\f[]
environment variable when initializing your container.
This will allow you to login to the \f[C]postgres\f[] account remotely.
Local connections will still not require a password.
.SS Changing passwords
.PP
Since passwords are part of the image configuration, the only supported
method to change passwords for the database user
(\f[C]POSTGRESQL_USER\f[]) and \f[C]postgres\f[] admin user is by
changing the environment variables \f[C]POSTGRESQL_PASSWORD\f[] and
\f[C]POSTGRESQL_ADMIN_PASSWORD\f[], respectively.
.PP
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.
.SH AUTHORS
Red Hat.

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

@ -0,0 +1,92 @@
#!/usr/bin/python
"""
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 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
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.
"""
from __future__ import print_function
import sys
def _read_file(path):
try:
with open(path, 'r') as f:
return f.read().strip()
except IOError:
return None
def get_memory_limit():
"""
Read memory limit, in bytes.
"""
limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes')
if limit is None or not limit.isdigit():
print("Warning: Can't detect memory limit from cgroups",
file=sys.stderr)
return None
return int(limit)
def get_number_of_cores():
"""
Read number of CPU cores.
"""
core_count = 0
line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus')
if line is None:
print("Warning: Can't detect number of CPU cores from cgroups",
file=sys.stderr)
return None
for group in line.split(','):
core_ids = list(map(int, group.split('-')))
if len(core_ids) == 2:
core_count += core_ids[1] - core_ids[0] + 1
else:
core_count += 1
return core_count
if __name__ == "__main__":
env_vars = {
"MAX_MEMORY_LIMIT_IN_BYTES": 9223372036854775807,
"MEMORY_LIMIT_IN_BYTES": get_memory_limit(),
"NUMBER_OF_CORES": get_number_of_cores()
}
env_vars = {k: v for k, v in env_vars.items() if v is not None}
if env_vars.get("MEMORY_LIMIT_IN_BYTES", 0) >= 92233720368547:
env_vars["NO_MEMORY_LIMIT"] = "true"
for key, value in env_vars.items():
print("{0}={1}".format(key, value))

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,220 @@
# 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}" ]]; then
export POSTGRESQL_SHARED_BUFFERS=${POSTGRESQL_SHARED_BUFFERS:-32MB}
export POSTGRESQL_EFFECTIVE_CACHE_SIZE=${POSTGRESQL_EFFECTIVE_CACHE_SIZE:-128MB}
else
# Use 1/4 of given memory for shared buffers
shared_buffers_computed="$(($MEMORY_LIMIT_IN_BYTES/1024/1024/4))MB"
# Setting effective_cache_size to 1/2 of total memory would be a normal conservative setting,
effective_cache="$(($MEMORY_LIMIT_IN_BYTES/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)

14
tests/config.yaml Normal file
View file

@ -0,0 +1,14 @@
document: modularity-testing
version: 1
name: postgresql
modulemd-url: https://src.fedoraproject.org/cgit/modules/postgresql.git/plain/postgresql.yaml
service:
port: 5432
module:
docker:
start: "docker run -it -e POSTGRESQL_USER=user -e POSTGRESQL_PASSWORD=p -e POSTGRESQL_DATABASE=db -e LC_ALL=C -p 5432:5432"
container: postgresql
rpm:
start: run-postgresql
repos:
- http://mirror.vutbr.cz/fedora/releases/26/Everything/x86_64/os/

56
tests/rpmvalidator.py Normal file
View file

@ -0,0 +1,56 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This Modularity Testing Framework helps you to write tests for modules
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# he Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors: Jan Scotka <jscotka@redhat.com>
#
from avocado import main
from moduleframework import module_framework
class ExampleRpmValidation(module_framework.AvocadoTest):
"""
:avocado: enable
"""
fhs_base_paths = [
'/bin',
'/boot',
'/dev',
'/etc',
'/home',
'/lib',
'/lib64',
'/media',
'/mnt',
'/opt',
'/proc',
'/root',
'/run',
'/sbin',
'/sys',
'/srv',
'/tmp',
'/usr/bin'
]
def testPaths(self):
self.start()
for directory in self.fhs_base_paths:
self.run("test -d %s" % directory)

46
tests/sanity1.py Normal file
View file

@ -0,0 +1,46 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This Modularity Testing Framework helps you to write tests for modules
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# he Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors: Rado Pitonak <rpitonak@redhat.com>
#
from avocado import main
from avocado.core import exceptions
from moduleframework import module_framework
class SanityCheck1(module_framework.AvocadoTest):
"""
:avocado: enable
"""
def test1(self):
self.start()
self.run("ls / | grep bin")
# check if perl is installed in the right version.
def test2PostgresVersion(self):
postgresVersion = "9.6"
self.start()
self.run("postgres --version | grep " + postgresVersion)
if __name__ == '__main__':
main()

47
tests/sanity2.py Normal file
View file

@ -0,0 +1,47 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This Modularity Testing Framework helps you to write tests for modules
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# he Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors: Rado Pitonak <rpitonak@redhat.com>
#
from avocado import main
from avocado.core import exceptions
from moduleframework import module_framework
import time
class SanityCheck2(module_framework.AvocadoTest):
"""
:avocado: enable
"""
def testConnectToDB(self):
self.start()
time.sleep(5)
self.run("psql -U $POSTGRESQL_USER -d $POSTGRESQL_DATABASE -c 'SELECT 1'")
def testCreateTable(self):
self.start()
time.sleep(5)
self.run("psql -U $POSTGRESQL_USER -d $POSTGRESQL_DATABASE -c 'CREATE TABLE mytable(ID INT PRIMARY KEY NOT NULL);'")
if __name__ == '__main__':
main()

47
tests/simpleTest.py Normal file
View file

@ -0,0 +1,47 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This Modularity Testing Framework helps you to write tests for modules
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# he Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Authors: Jan Scotka <jscotka@redhat.com>
#
from moduleframework import module_framework
import os
class simpleTests(module_framework.AvocadoTest):
"""
:avocado: enable
"""
def testPath(self):
print ">>>>>>>>>>>>>> ", module_framework.__file__
print ">>>>>>>>>>>>>> ", __file__
def testAssertIn(self):
self.start()
self.assertIn("sbin", self.run("ls /").stdout)
def testInsideModule(self):
self.start()
self.assertEqual("a", self.run("echo a").stdout.strip())
def testCommandOnHost(self):
self.start()
self.assertEqual("a", self.runHost("echo a").stdout.strip())