Compare commits
27 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b7e8de26c | ||
|
|
a2bd981032 | ||
|
|
a2eef8062b | ||
|
|
e0dc694125 | ||
|
|
5157eada71 | ||
|
|
fcb7466f35 | ||
|
|
f3e435ec35 | ||
|
|
b4193a89b7 | ||
|
|
14eb0cd14c | ||
|
|
9c069c4141 | ||
|
|
1ae18a54f9 | ||
|
|
058779a5d5 | ||
|
|
fa7e7e5dec | ||
|
|
8161155280 | ||
|
|
9362e1ab03 | ||
|
|
1e402a48e3 | ||
|
|
c0f73c53af | ||
|
|
e7715dc4ea | ||
|
|
c3172dfc8f | ||
|
|
7575406d3a | ||
|
|
9fe61a6e45 | ||
|
|
b7e34e62a9 | ||
|
|
966765906b | ||
|
|
036b9515cb | ||
|
|
0c4a8d07ca | ||
|
|
9e73316a6c | ||
|
|
21ae3f4ea0 |
19 changed files with 819 additions and 6 deletions
99
Dockerfile
Normal file
99
Dockerfile
Normal 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
15
Makefile
Normal 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
41
README.md
Normal 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.
|
||||
5
module-postgresql.repo.in
Normal file
5
module-postgresql.repo.in
Normal 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
|
||||
|
|
@ -18,11 +18,13 @@ data:
|
|||
- PostgreSQL
|
||||
dependencies:
|
||||
buildrequires:
|
||||
base-runtime: master
|
||||
common-build-dependencies: master
|
||||
perl: master
|
||||
base-runtime: f26
|
||||
common-build-dependencies: f26
|
||||
common-build-dependencies-bootstrap: f26
|
||||
shared-userspace: f26
|
||||
perl: f26
|
||||
requires:
|
||||
base-runtime: master
|
||||
base-runtime: f26
|
||||
api:
|
||||
rpms:
|
||||
- postgresql
|
||||
|
|
@ -36,8 +38,44 @@ data:
|
|||
filter: {}
|
||||
components:
|
||||
rpms:
|
||||
# part of base-runtime:
|
||||
# gettext
|
||||
# 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:
|
||||
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
|
||||
|
|
|
|||
99
root/usr/bin/cgroup-limits
Executable file
99
root/usr/bin/cgroup-limits
Executable 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
|
||||
3
root/usr/bin/container-entrypoint
Executable file
3
root/usr/bin/container-entrypoint
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
exec "$@"
|
||||
28
root/usr/bin/run-postgresql
Executable file
28
root/usr/bin/run-postgresql
Executable 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 "$@"
|
||||
5
root/usr/bin/run-postgresql-master
Executable file
5
root/usr/bin/run-postgresql-master
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
export ENABLE_REPLICATION=true
|
||||
|
||||
exec run-postgresql "$@"
|
||||
36
root/usr/bin/run-postgresql-slave
Executable file
36
root/usr/bin/run-postgresql-slave
Executable 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 "$@"
|
||||
7
root/usr/libexec/fix-permissions
Executable file
7
root/usr/libexec/fix-permissions
Executable 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 {} +
|
||||
98
root/usr/share/container-scripts/postgresql/README.md
Normal file
98
root/usr/share/container-scripts/postgresql/README.md
Normal 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.
|
||||
|
||||
225
root/usr/share/container-scripts/postgresql/common.sh
Normal file
225
root/usr/share/container-scripts/postgresql/common.sh
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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}
|
||||
|
|
@ -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
6
tests/Makefile
Normal 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
66
tests/config.yaml
Normal 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
5
tests/test.sql
Normal 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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue