Compare commits

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

24 commits

Author SHA1 Message Date
Honza Horak
958f1b7b2d sources not used anymore for building fedora containers 2025-07-08 17:28:06 +02:00
Michal Schorm
7cc8795d0c Update for F31 base image 2020-03-10 10:29:11 +01:00
Michal Schorm
d988f448d2 Pull changes from upstream and rebase for: rebuild for latest MariaDB 10.3
created from upstream commit: 9a5d82c444b6f70f822d0280eebd6c73a3d64e31
2020-03-03 16:24:21 +01:00
Clement Verna
69f9b2cbd2 Fix the FROM line in the Dockerfile
Signed-off-by: Clement Verna <cverna@tutanota.com>
2018-08-29 16:16:46 +02:00
Clement Verna
fc4e117f96 Drop Release label in favor of OSBS release_bump plugin.
OSBS can automatically bump the release number, for that
we just need to drop the label from the Dockerfile

See https://pagure.io/ContainerSIG/container-sig/issue/1

Signed-off-by: Clement Verna <cverna@tutanota.com>
2018-08-27 09:27:30 +02:00
Michal Schorm
c2f62cdcc9 Merge branch 'master' into f27 2018-04-04 16:08:13 +02:00
Michal Schorm
27698bebfd Update metadata about the version of MariaDB 2018-04-04 16:07:12 +02:00
Mohan Boddu
c05f2e3290 "Bump RELEASE for automatic rebuild" 2018-03-29 14:11:53 +00:00
Mohan Boddu
b2b8007f1e "Bump RELEASE for automatic rebuild" 2018-03-15 15:30:51 +00:00
Mohan Boddu
d617ef5998 "Bump RELEASE for automatic rebuild" 2018-03-01 18:31:35 +00:00
Mohan Boddu
40a99dae73 "Bump RELEASE for automatic rebuild" 2018-03-01 17:01:07 +00:00
Honza Horak
8836600322 Do not verify ghost files, it's fine when they're missing 2018-03-01 10:45:09 +01:00
Mohan Boddu
4a9a5eb80a "Bump RELEASE for automatic rebuild" 2018-02-16 14:58:39 +00:00
Mohan Boddu
dead8b1195 "Bump RELEASE for automatic rebuild" 2018-01-18 23:25:02 +00:00
Mohan Boddu
27d5125f22 "Bump RELEASE for automatic rebuild" 2018-01-18 23:18:28 +00:00
Mohan Boddu
3421bdfac0 "Bump RELEASE for automatic rebuild" 2018-01-18 23:04:29 +00:00
Mohan Boddu
98fc7d674b "Bump RELEASE for automatic rebuild" 2018-01-18 22:35:35 +00:00
Mohan Boddu
1a981e0751 "Bump RELEASE for automatic rebuild" 2018-01-10 00:05:13 +00:00
Patrick Uiterwijk
919f612738 Build 27 from f27
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2018-01-10 01:03:48 +01:00
Mohan Boddu
c499da4502 "Bump RELEASE for automatic rebuild" 2018-01-09 22:37:54 +00:00
Mohan Boddu
d648871524 "Bump RELEASE for automatic rebuild" 2018-01-09 17:06:53 +00:00
Mohan Boddu
d07505b9c1 "Bump RELEASE for automatic rebuild" 2018-01-09 17:00:23 +00:00
Honza Horak
cc92471aa3 Change version in FROM to rawhide 2017-05-16 13:24:10 +02:00
Honza Horak
050cc62c7d Change version in FROM to 26 2017-05-16 11:44:20 +02:00
30 changed files with 1 additions and 1667 deletions

0
.gitignore vendored
View file

View file

@ -1,64 +0,0 @@
FROM fedora:25
LABEL MAINTAINER "Honza Horak" <hhorak@redhat.com>
# MariaDB image for OpenShift.
#
# Volumes:
# * /var/lib/mysql/data - Datastore for MariaDB
# Environment:
# * $MYSQL_USER - Database user name
# * $MYSQL_PASSWORD - User's password
# * $MYSQL_DATABASE - Name of the database to create
# * $MYSQL_ROOT_PASSWORD (Optional) - Password for the 'root' MySQL account
ENV MYSQL_VERSION=10.1 \
HOME=/var/lib/mysql
LABEL summary="MariaDB is a multi-user, multi-threaded SQL database server" \
io.k8s.description="MariaDB is a multi-user, multi-threaded SQL database server" \
io.k8s.display-name="MariaDB 10.1" \
io.openshift.expose-services="3306:mysql" \
io.openshift.tags="database,mysql,mariadb,mariadb101,galera"
ENV NAME=mariadb VERSION=10.1 RELEASE=9 ARCH=x86_64
LABEL BZComponent="$NAME" \
Name="$FGC/$NAME" \
Version="$VERSION" \
Release="$RELEASE.$DISTTAG" \
Architecture="$ARCH"
EXPOSE 3306
# This image must forever use UID 27 for mysql user so our volumes are
# safe in the future. This should *never* change, the last test is there
# to make sure of that.
RUN INSTALL_PKGS="rsync tar gettext hostname bind-utils mariadb-server policycoreutils" && \
dnf install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
rpm -V $INSTALL_PKGS && \
dnf clean all && \
mkdir -p /var/lib/mysql/data && chown -R mysql.0 /var/lib/mysql && \
test "$(id mysql)" = "uid=27(mysql) gid=27(mysql) groups=27(mysql)"
# On Fedora, we fake missing python binary. In case user installs the python2
# in the container, this hack will be removed by installing /usr/bin/python from RPM.
RUN ln -s /usr/bin/python3 /usr/bin/python
# Get prefix path and path to scripts rather than hard-code them in scripts
ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/mysql \
MYSQL_PREFIX=/usr
ADD root /
# this is needed due to issues with squash
# when this directory gets rm'd by the container-setup
# script.
RUN rm -rf /etc/my.cnf.d/*
RUN /usr/libexec/container-setup
VOLUME ["/var/lib/mysql/data"]
USER 27
ENTRYPOINT ["container-entrypoint"]
CMD ["run-mysqld"]

View file

@ -1 +0,0 @@
root/usr/share/container-scripts/mysql/README.md

1
dead.package Normal file
View file

@ -0,0 +1 @@
sources not used anymore for building fedora containers

View file

@ -1,12 +0,0 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links = 0
# http://www.percona.com/blog/2008/05/31/dns-achilles-heel-mysql-installation/
skip_name_resolve
# http://www.chriscalender.com/ignoring-the-lostfound-directory-in-your-datadir/
ignore-db-dir=lost+found
!includedir /etc/my.cnf.d

View file

@ -1,332 +0,0 @@
.\"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 "MARIADB\-101\-RHEL7" "1" "February 22, 2017" "Container Image Pages" ""
.hy
.SH MariaDB Docker image
.PP
This container image includes MariaDB server 10.1 for OpenShift and
general usage.
Users can choose between RHEL and CentOS based images.
.PP
Dockerfile for CentOS is called Dockerfile, Dockerfile for RHEL is
called Dockerfile.rhel7.
.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(@);
l l.
T{
Variable name
T}@T{
Description
T}
_
T{
\f[C]MYSQL_USER\f[]
T}@T{
User name for MySQL account to be created
T}
T{
\f[C]MYSQL_PASSWORD\f[]
T}@T{
Password for the user account
T}
T{
\f[C]MYSQL_DATABASE\f[]
T}@T{
Database name
T}
T{
\f[C]MYSQL_ROOT_PASSWORD\f[]
T}@T{
Password for the root user (optional)
T}
.TE
.PP
The following environment variables influence the MySQL configuration
file.
They are all optional.
.PP
.TS
tab(@);
lw(17.2n) lw(35.5n) lw(17.2n).
T{
Variable name
T}@T{
Description
T}@T{
Default
T}
_
T{
\f[C]MYSQL_LOWER_CASE_TABLE_NAMES\f[]
T}@T{
Sets how the table names are stored and compared
T}@T{
0
T}
T{
\f[C]MYSQL_MAX_CONNECTIONS\f[]
T}@T{
The maximum permitted number of simultaneous client connections
T}@T{
151
T}
T{
\f[C]MYSQL_MAX_ALLOWED_PACKET\f[]
T}@T{
The maximum size of one packet or any generated/intermediate string
T}@T{
200M
T}
T{
\f[C]MYSQL_FT_MIN_WORD_LEN\f[]
T}@T{
The minimum length of the word to be included in a FULLTEXT index
T}@T{
4
T}
T{
\f[C]MYSQL_FT_MAX_WORD_LEN\f[]
T}@T{
The maximum length of the word to be included in a FULLTEXT index
T}@T{
20
T}
T{
\f[C]MYSQL_AIO\f[]
T}@T{
Controls the \f[C]innodb_use_native_aio\f[] setting value in case the
native AIO is broken.
See http://help.directadmin.com/item.php?id=529
T}@T{
1
T}
T{
\f[C]MYSQL_TABLE_OPEN_CACHE\f[]
T}@T{
The number of open tables for all threads
T}@T{
400
T}
T{
\f[C]MYSQL_KEY_BUFFER_SIZE\f[]
T}@T{
The size of the buffer used for index blocks
T}@T{
32M (or 10% of available memory)
T}
T{
\f[C]MYSQL_SORT_BUFFER_SIZE\f[]
T}@T{
The size of the buffer used for sorting
T}@T{
256K
T}
T{
\f[C]MYSQL_READ_BUFFER_SIZE\f[]
T}@T{
The size of the buffer used for a sequential scan
T}@T{
8M (or 5% of available memory)
T}
T{
\f[C]MYSQL_INNODB_BUFFER_POOL_SIZE\f[]
T}@T{
The size of the buffer pool where InnoDB caches table and index data
T}@T{
32M (or 50% of available memory)
T}
T{
\f[C]MYSQL_INNODB_LOG_FILE_SIZE\f[]
T}@T{
The size of each log file in a log group
T}@T{
8M (or 15% of available available)
T}
T{
\f[C]MYSQL_INNODB_LOG_BUFFER_SIZE\f[]
T}@T{
The size of the buffer that InnoDB uses to write to the log files on
disk
T}@T{
8M (or 15% of available memory)
T}
T{
\f[C]MYSQL_DEFAULTS_FILE\f[]
T}@T{
Point to an alternative configuration file
T}@T{
/etc/my.cnf
T}
T{
\f[C]MYSQL_BINLOG_FORMAT\f[]
T}@T{
Set sets the binlog format, supported values are \f[C]row\f[] and
\f[C]statement\f[]
T}@T{
statement
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/mysql/data\f[]
T}@T{
MySQL data 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]rhscl/mariadb\-100\-rhel7\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\ mariadb_database\ \-e\ MYSQL_USER=user\ \-e\ MYSQL_PASSWORD=pass\ \-e\ MYSQL_DATABASE=db\ \-p\ 3306:3306\ rhscl/mariadb\-100\-rhel7
\f[]
.fi
.PP
This will create a container named \f[C]mariadb_database\f[] running
MySQL with database \f[C]db\f[] and user with credentials
\f[C]user:pass\f[].
Port 3306 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/mysql/data\f[] argument.
This will be the MySQL data directory.
.PP
If the database directory is not initialized, the entrypoint script will
first run
\f[C]mysql_install_db\f[] (https://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html)
and setup necessary database users and passwords.
After the database is initialized, or if it was already present,
\f[C]mysqld\f[] is executed and will run as PID 1.
You can stop the detached container by running
\f[C]docker\ stop\ mariadb_database\f[].
.SS MariaDB auto\-tuning
.PP
When the MySQL image is run with the \f[C]\-\-memory\f[] parameter set
and you didn\[aq]t specify value for some parameters, their values will
be automatically calculated based on the available memory.
.PP
.TS
tab(@);
l l l.
T{
Variable name
T}@T{
Configuration parameter
T}@T{
Relative value
T}
_
T{
\f[C]MYSQL_KEY_BUFFER_SIZE\f[]
T}@T{
\f[C]key_buffer_size\f[]
T}@T{
10%
T}
T{
\f[C]MYSQL_READ_BUFFER_SIZE\f[]
T}@T{
\f[C]read_buffer_size\f[]
T}@T{
5%
T}
T{
\f[C]MYSQL_INNODB_BUFFER_POOL_SIZE\f[]
T}@T{
\f[C]innodb_buffer_pool_size\f[]
T}@T{
50%
T}
T{
\f[C]MYSQL_INNODB_LOG_FILE_SIZE\f[]
T}@T{
\f[C]innodb_log_file_size\f[]
T}@T{
15%
T}
T{
\f[C]MYSQL_INNODB_LOG_BUFFER_SIZE\f[]
T}@T{
\f[C]innodb_log_buffer_size\f[]
T}@T{
15%
T}
.TE
.SS MySQL root user
.PP
The root user has no password set by default, only allowing local
connections.
You can set it by setting the \f[C]MYSQL_ROOT_PASSWORD\f[] environment
variable.
This will allow you to login to the root account remotely.
Local connections will still not require a password.
.PP
To disable remote root access, simply unset \f[C]MYSQL_ROOT_PASSWORD\f[]
and restart the container.
.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]MYSQL_USER\f[])
and root user is by changing the environment variables
\f[C]MYSQL_PASSWORD\f[] and \f[C]MYSQL_ROOT_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.
.SS Default my.cnf file
.PP
With environment variables we are able to customize a lot of different
parameters or configurations for the mysql bootstrap configurations.
If you\[aq]d prefer to use your own configuration file, you can override
the \f[C]MYSQL_DEFAULTS_FILE\f[] env variable with the full path of the
file you wish to use.
For example, the default location is \f[C]/etc/my.cnf\f[] but you can
change it to \f[C]/etc/mysql/my.cnf\f[] by setting
\f[C]MYSQL_DEFAULTS_FILE=/etc/mysql/my.cnf\f[]
.SS Changing the replication binlog_format
.PP
Some applications may wish to use \f[C]row\f[] binlog_formats (for
example, those built with change\-data\-capture in mind).
The default replication/binlog format is \f[C]statement\f[] but to
change it you can set the \f[C]MYSQL_BINLOG_FORMAT\f[] environment
variable.
For example \f[C]MYSQL_BINLOG_FORMAT=row\f[].
Now when you run the database with \f[C]master\f[] replication turned on
(ie, set the Docker/container \f[C]cmd\f[] to be
\f[C]run\-mysqld\-master\f[]) the binlog will emit the actual data for
the rows that change as opposed to the statements (ie, DML like
insert...) that caused the change.
.SH AUTHORS
Red Hat.

View file

@ -1,92 +0,0 @@
#!/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

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

View file

@ -1 +0,0 @@
run-mysqld-master

View file

@ -1 +0,0 @@
run-mysqld-slave

View file

@ -1,35 +0,0 @@
#!/bin/bash
export_vars=$(cgroup-limits); export $export_vars
source ${CONTAINER_SCRIPTS_PATH}/common.sh
set -eu
[ -f ${CONTAINER_SCRIPTS_PATH}/validate-variables.sh ] && source ${CONTAINER_SCRIPTS_PATH}/validate-variables.sh
# Process the MySQL configuration files
log_info 'Processing MySQL configuration files ...'
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-base.cnf.template > /etc/my.cnf.d/base.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-paas.cnf.template > /etc/my.cnf.d/paas.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-tuning.cnf.template > /etc/my.cnf.d/tuning.cnf
if [ ! -d "$MYSQL_DATADIR/mysql" ]; then
initialize_database "$@"
else
start_local_mysql "$@"
fi
if [ -f ${CONTAINER_SCRIPTS_PATH}/passwd-change.sh ]; then
log_info 'Setting passwords ...'
source ${CONTAINER_SCRIPTS_PATH}/passwd-change.sh
fi
if [ -f ${CONTAINER_SCRIPTS_PATH}/post-init.sh ]; then
log_info 'Sourcing post-init.sh ...'
source ${CONTAINER_SCRIPTS_PATH}/post-init.sh
fi
# Restart the MySQL server with public IP bindings
shutdown_local_mysql
unset_env_vars
log_volume_info $MYSQL_DATADIR
log_info 'Running final exec -- Only MySQL server logs after this point'
exec ${MYSQL_PREFIX}/libexec/mysqld --defaults-file=$MYSQL_DEFAULTS_FILE "$@" 2>&1

View file

@ -1,50 +0,0 @@
#!/bin/bash
#
# This is an entrypoint that runs the MySQL server in the 'master' mode.
#
export_vars=$(cgroup-limits); export $export_vars
source ${CONTAINER_SCRIPTS_PATH}/common.sh
set -eu
export MYSQL_RUNNING_AS_MASTER=1
[ -f ${CONTAINER_SCRIPTS_PATH}/validate_replication_variables.sh ] && source ${CONTAINER_SCRIPTS_PATH}/validate_replication_variables.sh
[ -f ${CONTAINER_SCRIPTS_PATH}/validate_variables.sh ] && source ${CONTAINER_SCRIPTS_PATH}/validate_variables.sh
# The 'server-id' for master needs to be constant
export MYSQL_SERVER_ID=1
log_info "The 'master' server-id is ${MYSQL_SERVER_ID}"
# Process the MySQL configuration files
log_info 'Processing MySQL configuration files ...'
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-base.cnf.template > /etc/my.cnf.d/base.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-paas.cnf.template > /etc/my.cnf.d/paas.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-master.cnf.template > /etc/my.cnf.d/master.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-repl-gtid.cnf.template > /etc/my.cnf.d/repl-gtid.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-tuning.cnf.template > /etc/my.cnf.d/tuning.cnf
if [ ! -d "$MYSQL_DATADIR/mysql" ]; then
initialize_database "$@"
else
start_local_mysql "$@"
fi
log_info 'Setting passwords ...'
[ -f ${CONTAINER_SCRIPTS_PATH}/passwd-change.sh ] && source ${CONTAINER_SCRIPTS_PATH}/passwd-change.sh
# Setup the 'master' replication on the MySQL server
mysql $mysql_flags <<EOSQL
GRANT REPLICATION SLAVE ON *.* TO '${MYSQL_MASTER_USER}'@'%' IDENTIFIED BY '${MYSQL_MASTER_PASSWORD}';
GRANT SELECT ON replication.* TO '${MYSQL_MASTER_USER}'@'%' IDENTIFIED BY '${MYSQL_MASTER_PASSWORD}';
FLUSH PRIVILEGES;
EOSQL
log_info 'Sourcing post-init.sh ...'
[ -f ${CONTAINER_SCRIPTS_PATH}/post-init.sh ] && source ${CONTAINER_SCRIPTS_PATH}/post-init.sh
# Restart the MySQL server with public IP bindings
shutdown_local_mysql
unset_env_vars
log_volume_info $MYSQL_DATADIR
log_info 'Running final exec -- Only MySQL server logs after this point'
exec ${MYSQL_PREFIX}/libexec/mysqld --defaults-file=$MYSQL_DEFAULTS_FILE "$@" 2>&1

View file

@ -1,60 +0,0 @@
#!/bin/bash
#
# This is an entrypoint that runs the MySQL server in the 'slave' mode.
#
export_vars=$(cgroup-limits); export $export_vars
source ${CONTAINER_SCRIPTS_PATH}/common.sh
set -eu
# Just run normal server if the data directory is already initialized
if [ -d "${MYSQL_DATADIR}/mysql" ]; then
exec /usr/bin/run-mysqld "$@"
fi
export MYSQL_RUNNING_AS_SLAVE=1
[ -f ${CONTAINER_SCRIPTS_PATH}/validate_replication_variables.sh ] && source ${CONTAINER_SCRIPTS_PATH}/validate_replication_variables.sh
# Generate the unique 'server-id' for this master
export MYSQL_SERVER_ID=$(server_id)
log_info "The 'slave' server-id is ${MYSQL_SERVER_ID}"
# Process the MySQL configuration files
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-base.cnf.template > /etc/my.cnf.d/base.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-paas.cnf.template > /etc/my.cnf.d/paas.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-slave.cnf.template > /etc/my.cnf.d/slave.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-repl-gtid.cnf.template > /etc/my.cnf.d/repl-gtid.cnf
envsubst < ${CONTAINER_SCRIPTS_PATH}/my-tuning.cnf.template > /etc/my.cnf.d/tuning.cnf
# Initialize MySQL database and wait for the MySQL master to accept
# connections.
initialize_database "$@"
wait_for_mysql_master
# Get binlog file and position from master
STATUS_INFO=$(mysql --host "$MYSQL_MASTER_SERVICE_NAME" "-u${MYSQL_MASTER_USER}" "-p${MYSQL_MASTER_PASSWORD}" replication -e 'SELECT gtid from replication limit 1\G')
GTID_VALUE=$(echo "$STATUS_INFO" | grep 'gtid:' | head -n 1 | sed -e 's/^\s*gtid: //')
# checking STATUS_INFO here because empty GTID_VALUE is valid value
if [ -z "${STATUS_INFO}" ] ; then
echo "Could not read GTID value from master"
exit 1
fi
mysql $mysql_flags <<EOSQL
STOP SLAVE;
SET GLOBAL gtid_slave_pos = "${GTID_VALUE}";
CHANGE MASTER TO MASTER_HOST='${MYSQL_MASTER_SERVICE_NAME}',MASTER_USER='${MYSQL_MASTER_USER}', MASTER_PASSWORD='${MYSQL_MASTER_PASSWORD}', MASTER_USE_GTID=slave_pos;
START SLAVE;
EOSQL
log_info 'Sourcing post-init.sh ...'
[ -f ${CONTAINER_SCRIPTS_PATH}/post-init.sh ] && source ${CONTAINER_SCRIPTS_PATH}/post-init.sh
# Restart the MySQL server with public IP bindings
shutdown_local_mysql
unset_env_vars
log_volume_info $MYSQL_DATADIR
log_info 'Running final exec -- Only MySQL server logs after this point'
exec ${MYSQL_PREFIX}/libexec/mysqld --defaults-file=$MYSQL_DEFAULTS_FILE \
--report-host=$(hostname -i) "$@" 2>&1

View file

@ -1,58 +0,0 @@
#!/bin/bash
# This function returns all config files that daemon uses and their path
# includes /opt. It is used to get correct path to the config file.
mysql_get_config_files_scl() {
scl enable ${ENABLED_COLLECTIONS} -- my_print_defaults --help --verbose | \
grep --after=1 '^Default options' | \
tail -n 1 | \
grep -o '[^ ]*opt[^ ]*my.cnf'
}
# This function picks the main config file that deamon uses and we ship in rpm
mysql_get_correct_config() {
# we use the same config in non-SCL packages, not necessary to guess
[ -z "${ENABLED_COLLECTIONS}" ] && echo -n "/etc/my.cnf" && return
# from all config files read by daemon, pick the first that exists
for f in `mysql_get_config_files_scl` ; do
[ -f "$f" ] && echo "$f"
done | head -n 1
}
export MYSQL_CONFIG_FILE=$(mysql_get_correct_config)
[ -z "$MYSQL_CONFIG_FILE" ] && echo "MYSQL_CONFIG_FILE is empty" && exit 1
unset -f mysql_get_correct_config mysql_get_config_files_scl
# we provide own config files for the container, so clean what rpm ships here
mkdir -p ${MYSQL_CONFIG_FILE}.d
rm -f ${MYSQL_CONFIG_FILE}.d/*
# we may add options during service init, so we need to have this dir writable by daemon user
chown -R mysql:0 ${MYSQL_CONFIG_FILE}.d ${MYSQL_CONFIG_FILE}
restorecon -R ${MYSQL_CONFIG_FILE}.d ${MYSQL_CONFIG_FILE}
# API of the container are standard paths /etc/my.cnf and /etc/my.cnf.d
# we already include own /etc/my.cnf for container, but for cases the
# actually used config file is not on standard path /etc/my.cnf, we
# need to move it to the location daemon expects it and create symlinks
if [ "$MYSQL_CONFIG_FILE" != "/etc/my.cnf" ] ; then
rm -rf /etc/my.cnf.d
mv /etc/my.cnf ${MYSQL_CONFIG_FILE}
ln -s ${MYSQL_CONFIG_FILE} /etc/my.cnf
ln -s ${MYSQL_CONFIG_FILE}.d /etc/my.cnf.d
fi
# setup directory for data
mkdir -p /var/lib/mysql/data
chown -R mysql:0 /var/lib/mysql
restorecon -R /var/lib/mysql
# Loosen permission bits for group to avoid problems running container with
# arbitrary UID
# When only specifying user, group is 0, that's why /var/lib/mysql must have
# owner mysql.0; that allows to avoid a+rwx for this dir
chmod g+w -R /var/lib/mysql ${MYSQL_CONFIG_FILE}.d

View file

@ -1,135 +0,0 @@
MariaDB Docker image
====================
This container image includes MariaDB server 10.1 for OpenShift and general usage.
Users can choose between RHEL and CentOS based images.
Dockerfile for CentOS is called Dockerfile, Dockerfile for RHEL is called
Dockerfile.rhel7.
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 |
| :--------------------- | ----------------------------------------- |
| `MYSQL_USER` | User name for MySQL account to be created |
| `MYSQL_PASSWORD` | Password for the user account |
| `MYSQL_DATABASE` | Database name |
| `MYSQL_ROOT_PASSWORD` | Password for the root user (optional) |
The following environment variables influence the MySQL configuration file. They are all optional.
| Variable name | Description | Default
| :------------------------------ | ----------------------------------------------------------------- | -------------------------------
| `MYSQL_LOWER_CASE_TABLE_NAMES` | Sets how the table names are stored and compared | 0
| `MYSQL_MAX_CONNECTIONS` | The maximum permitted number of simultaneous client connections | 151
| `MYSQL_MAX_ALLOWED_PACKET` | The maximum size of one packet or any generated/intermediate string | 200M
| `MYSQL_FT_MIN_WORD_LEN` | The minimum length of the word to be included in a FULLTEXT index | 4
| `MYSQL_FT_MAX_WORD_LEN` | The maximum length of the word to be included in a FULLTEXT index | 20
| `MYSQL_AIO` | Controls the `innodb_use_native_aio` setting value in case the native AIO is broken. See http://help.directadmin.com/item.php?id=529 | 1
| `MYSQL_TABLE_OPEN_CACHE` | The number of open tables for all threads | 400
| `MYSQL_KEY_BUFFER_SIZE` | The size of the buffer used for index blocks | 32M (or 10% of available memory)
| `MYSQL_SORT_BUFFER_SIZE` | The size of the buffer used for sorting | 256K
| `MYSQL_READ_BUFFER_SIZE` | The size of the buffer used for a sequential scan | 8M (or 5% of available memory)
| `MYSQL_INNODB_BUFFER_POOL_SIZE`| The size of the buffer pool where InnoDB caches table and index data | 32M (or 50% of available memory)
| `MYSQL_INNODB_LOG_FILE_SIZE` | The size of each log file in a log group | 8M (or 15% of available available)
| `MYSQL_INNODB_LOG_BUFFER_SIZE` | The size of the buffer that InnoDB uses to write to the log files on disk | 8M (or 15% of available memory)
| `MYSQL_DEFAULTS_FILE` | Point to an alternative configuration file | /etc/my.cnf
| `MYSQL_BINLOG_FORMAT` | Set sets the binlog format, supported values are `row` and `statement` | statement
You can also set the following mount points by passing the `-v /host:/container` flag to Docker.
| Volume mount point | Description |
| :----------------------- | -------------------- |
| `/var/lib/mysql/data` | MySQL data 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 `rhscl/mariadb-100-rhel7` 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 mariadb_database -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -p 3306:3306 rhscl/mariadb-100-rhel7
```
This will create a container named `mariadb_database` running MySQL with database
`db` and user with credentials `user:pass`. Port 3306 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/mysql/data` argument. This will be the MySQL
data directory.
If the database directory is not initialized, the entrypoint script will first
run [`mysql_install_db`](https://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html)
and setup necessary database users and passwords. After the database is initialized,
or if it was already present, `mysqld` is executed and will run as PID 1. You can
stop the detached container by running `docker stop mariadb_database`.
MariaDB auto-tuning
-------------------
When the MySQL image is run with the `--memory` parameter set and you didn't
specify value for some parameters, their values will be automatically
calculated based on the available memory.
| Variable name | Configuration parameter | Relative value
| :-------------------------------| ------------------------- | --------------
| `MYSQL_KEY_BUFFER_SIZE` | `key_buffer_size` | 10%
| `MYSQL_READ_BUFFER_SIZE` | `read_buffer_size` | 5%
| `MYSQL_INNODB_BUFFER_POOL_SIZE` | `innodb_buffer_pool_size` | 50%
| `MYSQL_INNODB_LOG_FILE_SIZE` | `innodb_log_file_size` | 15%
| `MYSQL_INNODB_LOG_BUFFER_SIZE` | `innodb_log_buffer_size` | 15%
MySQL root user
---------------------------------
The root user has no password set by default, only allowing local connections.
You can set it by setting the `MYSQL_ROOT_PASSWORD` environment variable. This
will allow you to login to the root account remotely. Local connections will
still not require a password.
To disable remote root access, simply unset `MYSQL_ROOT_PASSWORD` and restart
the container.
Changing passwords
------------------
Since passwords are part of the image configuration, the only supported method
to change passwords for the database user (`MYSQL_USER`) and root user is by
changing the environment variables `MYSQL_PASSWORD` and `MYSQL_ROOT_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.
Default my.cnf file
-------------------
With environment variables we are able to customize a lot of different parameters
or configurations for the mysql bootstrap configurations. If you'd prefer to use
your own configuration file, you can override the `MYSQL_DEFAULTS_FILE` env
variable with the full path of the file you wish to use. For example, the default
location is `/etc/my.cnf` but you can change it to `/etc/mysql/my.cnf` by setting
`MYSQL_DEFAULTS_FILE=/etc/mysql/my.cnf`
Changing the replication binlog_format
--------------------------------------
Some applications may wish to use `row` binlog_formats (for example, those built
with change-data-capture in mind). The default replication/binlog format is
`statement` but to change it you can set the `MYSQL_BINLOG_FORMAT` environment
variable. For example `MYSQL_BINLOG_FORMAT=row`. Now when you run the database
with `master` replication turned on (ie, set the Docker/container `cmd` to be
`run-mysqld-master`) the binlog will emit the actual data for the rows that change
as opposed to the statements (ie, DML like insert...) that caused the change.

View file

@ -1,164 +0,0 @@
#!/bin/bash
source ${CONTAINER_SCRIPTS_PATH}/helpers.sh
# Data directory where MySQL database files live. The data subdirectory is here
# because .bashrc and my.cnf both live in /var/lib/mysql/ and we don't want a
# volume to override it.
export MYSQL_DATADIR=/var/lib/mysql/data
# Configuration settings.
export MYSQL_DEFAULTS_FILE=${MYSQL_DEFAULTS_FILE:-/etc/my.cnf}
export MYSQL_BINLOG_FORMAT=${MYSQL_BINLOG_FORMAT:-STATEMENT}
export MYSQL_LOWER_CASE_TABLE_NAMES=${MYSQL_LOWER_CASE_TABLE_NAMES:-0}
export MYSQL_MAX_CONNECTIONS=${MYSQL_MAX_CONNECTIONS:-151}
export MYSQL_FT_MIN_WORD_LEN=${MYSQL_FT_MIN_WORD_LEN:-4}
export MYSQL_FT_MAX_WORD_LEN=${MYSQL_FT_MAX_WORD_LEN:-20}
export MYSQL_AIO=${MYSQL_AIO:-1}
export MYSQL_MAX_ALLOWED_PACKET=${MYSQL_MAX_ALLOWED_PACKET:-200M}
export MYSQL_TABLE_OPEN_CACHE=${MYSQL_TABLE_OPEN_CACHE:-400}
export MYSQL_SORT_BUFFER_SIZE=${MYSQL_SORT_BUFFER_SIZE:-256K}
if [ -n "${NO_MEMORY_LIMIT:-}" -o -z "${MEMORY_LIMIT_IN_BYTES:-}" ]; then
key_buffer_size='32M'
read_buffer_size='8M'
innodb_buffer_pool_size='32M'
innodb_log_file_size='8M'
innodb_log_buffer_size='8M'
else
key_buffer_size="$(python -c "print(int((${MEMORY_LIMIT_IN_BYTES}/(1024*1024))*0.1))")M"
read_buffer_size="$(python -c "print(int((${MEMORY_LIMIT_IN_BYTES}/(1024*1024))*0.05))")M"
innodb_buffer_pool_size="$(python -c "print(int((${MEMORY_LIMIT_IN_BYTES}/(1024*1024))*0.5))")M"
innodb_log_file_size="$(python -c "print(int((${MEMORY_LIMIT_IN_BYTES}/(1024*1024))*0.15))")M"
innodb_log_buffer_size="$(python -c "print(int((${MEMORY_LIMIT_IN_BYTES}/(1024*1024))*0.15))")M"
fi
export MYSQL_KEY_BUFFER_SIZE=${MYSQL_KEY_BUFFER_SIZE:-$key_buffer_size}
export MYSQL_READ_BUFFER_SIZE=${MYSQL_READ_BUFFER_SIZE:-$read_buffer_size}
export MYSQL_INNODB_BUFFER_POOL_SIZE=${MYSQL_INNODB_BUFFER_POOL_SIZE:-$innodb_buffer_pool_size}
export MYSQL_INNODB_LOG_FILE_SIZE=${MYSQL_INNODB_LOG_FILE_SIZE:-$innodb_log_file_size}
export MYSQL_INNODB_LOG_BUFFER_SIZE=${MYSQL_INNODB_LOG_BUFFER_SIZE:-$innodb_log_buffer_size}
# Be paranoid and stricter than we should be.
# https://dev.mysql.com/doc/refman/en/identifiers.html
mysql_identifier_regex='^[a-zA-Z0-9_]+$'
mysql_password_regex='^[a-zA-Z0-9_~!@#$%^&*()-=<>,.?;:|]+$'
# Variables that are used to connect to local mysql during initialization
mysql_flags="-u root --socket=/tmp/mysql.sock"
admin_flags="--defaults-file=$MYSQL_DEFAULTS_FILE $mysql_flags"
# Make sure env variables don't propagate to mysqld process.
function unset_env_vars() {
log_info 'Cleaning up environment variables MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE and MYSQL_ROOT_PASSWORD ...'
unset MYSQL_USER MYSQL_PASSWORD MYSQL_DATABASE MYSQL_ROOT_PASSWORD
}
# Poll until MySQL responds to our ping.
function wait_for_mysql() {
pid=$1 ; shift
while [ true ]; do
if [ -d "/proc/$pid" ]; then
mysqladmin --socket=/tmp/mysql.sock ping &>/dev/null && log_info "MySQL started successfully" && return 0
else
return 1
fi
log_info "Waiting for MySQL to start ..."
sleep 1
done
}
# Start local MySQL server with a defaults file
function start_local_mysql() {
log_info 'Starting MySQL server with disabled networking ...'
${MYSQL_PREFIX}/libexec/mysqld \
--defaults-file=$MYSQL_DEFAULTS_FILE \
--skip-networking --socket=/tmp/mysql.sock "$@" &
mysql_pid=$!
wait_for_mysql $mysql_pid
}
# Shutdown mysql flushing privileges
function shutdown_local_mysql() {
log_info 'Shutting down MySQL ...'
mysqladmin $admin_flags flush-privileges shutdown
}
# Initialize the MySQL database (create user accounts and the initial database)
function initialize_database() {
log_info 'Initializing database ...'
log_info 'Running mysql_install_db ...'
# Using --rpm since we need mysql_install_db behaves as in RPM
# Using empty --basedir to work-around https://bugzilla.redhat.com/show_bug.cgi?id=1406391
mysql_install_db --rpm --datadir=$MYSQL_DATADIR --basedir=''
start_local_mysql "$@"
if [ -v MYSQL_RUNNING_AS_SLAVE ]; then
log_info 'Initialization finished'
return 0
fi
if [ -v MYSQL_RUNNING_AS_MASTER ]; then
# Save master status into a separate database.
STATUS_INFO=$(mysql $admin_flags -e 'SHOW MASTER STATUS\G')
BINLOG_POSITION=$(echo "$STATUS_INFO" | grep 'Position:' | head -n 1 | sed -e 's/^\s*Position: //')
BINLOG_FILE=$(echo "$STATUS_INFO" | grep 'File:' | head -n 1 | sed -e 's/^\s*File: //')
GTID_INFO=$(mysql $admin_flags -e "SELECT BINLOG_GTID_POS('$BINLOG_FILE', '$BINLOG_POSITION') AS gtid_value \G")
GTID_VALUE=$(echo "$GTID_INFO" | grep 'gtid_value:' | head -n 1 | sed -e 's/^\s*gtid_value: //')
mysqladmin $admin_flags create replication
mysql $admin_flags <<EOSQL
use replication
CREATE TABLE replication (gtid VARCHAR(256));
INSERT INTO replication (gtid) VALUES ('$GTID_VALUE');
EOSQL
fi
# Do not care what option is compulsory here, just create what is specified
if [ -v MYSQL_USER ]; then
log_info "Creating user specified by MYSQL_USER (${MYSQL_USER}) ..."
mysql $mysql_flags <<EOSQL
CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';
EOSQL
fi
if [ -v MYSQL_DATABASE ]; then
log_info "Creating database ${MYSQL_DATABASE} ..."
mysqladmin $admin_flags create "${MYSQL_DATABASE}"
if [ -v MYSQL_USER ]; then
log_info "Granting privileges to user ${MYSQL_USER} for ${MYSQL_DATABASE} ..."
mysql $mysql_flags <<EOSQL
GRANT ALL ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%' ;
FLUSH PRIVILEGES ;
EOSQL
fi
fi
if [ -v MYSQL_ROOT_PASSWORD ]; then
log_info "Setting password for MySQL root user ..."
mysql $mysql_flags <<EOSQL
CREATE USER IF NOT EXISTS 'root'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' WITH GRANT OPTION;
EOSQL
fi
log_info 'Initialization finished'
}
# The 'server_id' number for slave needs to be within 1-4294967295 range.
# This function will take the 'hostname' if the container, hash it and turn it
# into the number.
# See: https://dev.mysql.com/doc/refman/en/replication-options.html#option_mysqld_server-id
function server_id() {
checksum=$(sha256sum <<< $(hostname -i))
checksum=${checksum:0:14}
echo -n $((0x${checksum}%4294967295))
}
function wait_for_mysql_master() {
while true; do
log_info "Waiting for MySQL master (${MYSQL_MASTER_SERVICE_NAME}) to accept connections ..."
mysqladmin --host=${MYSQL_MASTER_SERVICE_NAME} --user="${MYSQL_MASTER_USER}" \
--password="${MYSQL_MASTER_PASSWORD}" ping &>/dev/null && log_info "MySQL master is ready" && return 0
sleep 1
done
}

View file

@ -1,24 +0,0 @@
function log_info {
echo "---> `date +%T` $@"
}
function log_and_run {
log_info "Running $@"
"$@"
}
function log_volume_info {
CONTAINER_DEBUG=${CONTAINER_DEBUG:-}
if [[ "${CONTAINER_DEBUG,,}" != "true" ]]; then
return
fi
log_info "Volume info for $@:"
set +e
log_and_run mount
while [ $# -gt 0 ]; do
log_and_run ls -alZ $1
shift
done
set -e
}

View file

@ -1,5 +0,0 @@
[mysqld]
datadir = ${MYSQL_DATADIR}
basedir = ${MYSQL_PREFIX}
plugin-dir = ${MYSQL_PREFIX}/lib64/mysql/plugin

View file

@ -1,7 +0,0 @@
[mysqld]
server-id = ${MYSQL_SERVER_ID}
log_bin = ${MYSQL_DATADIR}/mysql-bin.log
binlog_do_db = mysql
binlog_do_db = ${MYSQL_DATABASE}
binlog_format = ${MYSQL_BINLOG_FORMAT}

View file

@ -1,26 +0,0 @@
[mysqld]
#
# Settings configured by the user
#
# Sets how the table names are stored and compared. Default: 0
lower_case_table_names = ${MYSQL_LOWER_CASE_TABLE_NAMES}
# The maximum permitted number of simultaneous client connections. Default: 151
max_connections = ${MYSQL_MAX_CONNECTIONS}
# The minimum/maximum lengths of the word to be included in a FULLTEXT index. Default: 4/20
ft_min_word_len = ${MYSQL_FT_MIN_WORD_LEN}
ft_max_word_len = ${MYSQL_FT_MAX_WORD_LEN}
# In case the native AIO is broken. Default: 1
# See http://help.directadmin.com/item.php?id=529
innodb_use_native_aio = ${MYSQL_AIO}
[myisamchk]
# The minimum/maximum lengths of the word to be included in a FULLTEXT index. Default: 4/20
#
# To ensure that myisamchk and the server use the same values for full-text
# parameters, we placed them in both sections.
ft_min_word_len = ${MYSQL_FT_MIN_WORD_LEN}
ft_max_word_len = ${MYSQL_FT_MAX_WORD_LEN}

View file

@ -1,4 +0,0 @@
[mysqld]
log-slave-updates = ON

View file

@ -1,7 +0,0 @@
[mysqld]
server-id = ${MYSQL_SERVER_ID}
log_bin = ${MYSQL_DATADIR}/mysql-bin.log
relay-log = ${MYSQL_DATADIR}/mysql-relay-bin.log
binlog_do_db = mysql
binlog_do_db = ${MYSQL_DATABASE}

View file

@ -1,28 +0,0 @@
[mysqld]
key_buffer_size = ${MYSQL_KEY_BUFFER_SIZE}
max_allowed_packet = ${MYSQL_MAX_ALLOWED_PACKET}
table_open_cache = ${MYSQL_TABLE_OPEN_CACHE}
sort_buffer_size = ${MYSQL_SORT_BUFFER_SIZE}
read_buffer_size = ${MYSQL_READ_BUFFER_SIZE}
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 256K
myisam_sort_buffer_size = 2M
# It is recommended that innodb_buffer_pool_size is configured to 50 to 75 percent of system memory.
innodb_buffer_pool_size = ${MYSQL_INNODB_BUFFER_POOL_SIZE}
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = ${MYSQL_INNODB_LOG_FILE_SIZE}
innodb_log_buffer_size = ${MYSQL_INNODB_LOG_BUFFER_SIZE}
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M

View file

@ -1,23 +0,0 @@
# Set the password for MySQL user and root everytime this container is started.
# This allows to change the password by editing the deployment configuration.
if [[ -v MYSQL_USER && -v MYSQL_PASSWORD ]]; then
mysql $mysql_flags <<EOSQL
SET PASSWORD FOR '${MYSQL_USER}'@'%' = PASSWORD('${MYSQL_PASSWORD}');
EOSQL
fi
# The MYSQL_ROOT_PASSWORD is optional, therefore we need to either enable remote
# access with a password if the variable is set or disable remote access otherwise.
if [ -v MYSQL_ROOT_PASSWORD ]; then
# create a user if it doesn't exist and set its password
mysql $mysql_flags <<EOSQL
CREATE USER IF NOT EXISTS 'root'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' WITH GRANT OPTION;
EOSQL
else
mysql $mysql_flags <<EOSQL
DROP USER IF EXISTS 'root'@'%';
FLUSH PRIVILEGES;
EOSQL
fi

View file

@ -1,3 +0,0 @@
# This will make scl collection binaries work out of box.
unset BASH_ENV PROMPT_COMMAND ENV
source scl_source enable ${ENABLED_COLLECTIONS}

View file

@ -1,18 +0,0 @@
function validate_replication_variables() {
if ! [[ -v MYSQL_DATABASE && -v MYSQL_MASTER_USER && -v MYSQL_MASTER_PASSWORD && \
( "${MYSQL_RUNNING_AS_SLAVE:-0}" != "1" || -v MYSQL_MASTER_SERVICE_NAME ) ]]; then
echo
echo "For master/slave replication, you have to specify following environment variables:"
echo " MYSQL_MASTER_SERVICE_NAME (slave only)"
echo " MYSQL_DATABASE"
echo " MYSQL_MASTER_USER"
echo " MYSQL_MASTER_PASSWORD"
echo
fi
[[ "$MYSQL_DATABASE" =~ $mysql_identifier_regex ]] || usage "Invalid database name"
[[ "$MYSQL_MASTER_USER" =~ $mysql_identifier_regex ]] || usage "Invalid MySQL master username"
[ ${#MYSQL_MASTER_USER} -le 16 ] || usage "MySQL master username too long (maximum 16 characters)"
[[ "$MYSQL_MASTER_PASSWORD" =~ $mysql_password_regex ]] || usage "Invalid MySQL master password"
}
validate_replication_variables

View file

@ -1,78 +0,0 @@
function usage() {
[ $# == 1 ] && echo "error: $1"
echo "You must either specify the following environment variables:"
echo " MYSQL_USER (regex: '$mysql_identifier_regex')"
echo " MYSQL_PASSWORD (regex: '$mysql_password_regex')"
echo " MYSQL_DATABASE (regex: '$mysql_identifier_regex')"
echo "Or the following environment variable:"
echo " MYSQL_ROOT_PASSWORD (regex: '$mysql_password_regex')"
echo "Or both."
echo "Optional Settings:"
echo " MYSQL_LOWER_CASE_TABLE_NAMES (default: 0)"
echo " MYSQL_MAX_CONNECTIONS (default: 151)"
echo " MYSQL_FT_MIN_WORD_LEN (default: 4)"
echo " MYSQL_FT_MAX_WORD_LEN (default: 20)"
echo " MYSQL_AIO (default: 1)"
echo " MYSQL_KEY_BUFFER_SIZE (default: 32M or 10% of available memory)"
echo " MYSQL_MAX_ALLOWED_PACKET (default: 200M)"
echo " MYSQL_TABLE_OPEN_CACHE (default: 400)"
echo " MYSQL_SORT_BUFFER_SIZE (default: 256K)"
echo " MYSQL_READ_BUFFER_SIZE (default: 8M or 5% of available memory)"
echo " MYSQL_INNODB_BUFFER_POOL_SIZE (default: 32M or 50% of available memory)"
echo " MYSQL_INNODB_LOG_FILE_SIZE (default: 8M or 15% of available memory)"
echo " MYSQL_INNODB_LOG_BUFFER_SIZE (default: 8M or 15% of available memory)"
echo
echo "For more information, see https://github.com/sclorg/mariadb-container"
exit 1
}
function validate_variables() {
# Check basic sanity of specified variables
if [[ -v MYSQL_USER && -v MYSQL_PASSWORD ]]; then
[[ "$MYSQL_USER" =~ $mysql_identifier_regex ]] || usage "Invalid MySQL username"
[ ${#MYSQL_USER} -le 16 ] || usage "MySQL username too long (maximum 16 characters)"
[[ "$MYSQL_PASSWORD" =~ $mysql_password_regex ]] || usage "Invalid password"
user_specified=1
fi
if [ -v MYSQL_ROOT_PASSWORD ]; then
[[ "$MYSQL_ROOT_PASSWORD" =~ $mysql_password_regex ]] || usage "Invalid root password"
root_specified=1
fi
# If MYSQL_USER == "root", we have a special case
if [[ "${user_specified:-0}" == "1" && "$MYSQL_USER" == "root" ]]; then
if [[ "${root_specified:-0}" == "1" ]]; then
usage "When setting MYSQL_USER to 'root' you can only set either MYSQL_PASSWORD or MYSQL_ROOT_PASSWORD"
fi
# We will now behave as if MYSQL_USER was not specified
export MYSQL_ROOT_PASSWORD="$MYSQL_PASSWORD"
export -n MYSQL_USER
export -n MYSQL_PASSWORD
user_specified=0
root_specified=1
fi
# Either combination of user/pass/db or root password is ok
if [[ "${user_specified:-0}" == "0" && "${root_specified:-0}" == "0" ]]; then
usage
fi
# If the root user is not specified, database name is required
if [[ "${root_specified:-0}" == "0" ]]; then
[ -v MYSQL_DATABASE ] || usage "You need to specify database name or root password"
fi
if [ -v MYSQL_DATABASE ]; then
[[ "$MYSQL_DATABASE" =~ $mysql_identifier_regex ]] || usage "Invalid database name"
[ ${#MYSQL_DATABASE} -le 64 ] || usage "Database name too long (maximum 64 characters)"
fi
# Specifically check of incomplete specification
if [[ -v MYSQL_USER || -v MYSQL_PASSWORD || -v MYSQL_DATABASE ]] && \
[[ "${user_specified:-0}" == "0" ]]; then
usage
fi
}
validate_variables

View file

437
test/run
View file

@ -1,437 +0,0 @@
#!/bin/bash
#
# Test the MySQL image.
#
# IMAGE_NAME specifies the name of the candidate image used for testing.
# The image has to be available before this script is executed.
#
set -o errexit
set -o nounset
shopt -s nullglob
IMAGE_NAME=${IMAGE_NAME-centos/mariadb-101-centos7-candidate}
CIDFILE_DIR=$(mktemp --suffix=mysql_test_cidfiles -d)
function cleanup() {
local cidfile
for cidfile in $CIDFILE_DIR/* ; do
local CONTAINER
CONTAINER=$(cat $cidfile)
echo "Stopping and removing container $CONTAINER..."
docker stop $CONTAINER >/dev/null
local exit_status
exit_status=$(docker inspect -f '{{.State.ExitCode}}' $CONTAINER)
if [ "$exit_status" != "0" ]; then
echo "Inspecting container $CONTAINER"
docker inspect $CONTAINER
echo "Dumping logs for $CONTAINER"
docker logs $CONTAINER
fi
docker rm -v $CONTAINER >/dev/null
rm $cidfile
echo "Done."
done
rmdir $CIDFILE_DIR
}
trap cleanup EXIT SIGINT
function get_cid() {
local id="$1" ; shift || return 1
echo $(cat "$CIDFILE_DIR/$id")
}
function get_container_ip() {
local id="$1" ; shift
docker inspect --format='{{.NetworkSettings.IPAddress}}' $(get_cid "$id")
}
function mysql_cmd() {
local container_ip="$1"; shift
local login="$1"; shift
local password="$1"; shift
docker run --rm "$IMAGE_NAME" mysql --host "$container_ip" -u"$login" -p"$password" "$@" db
}
function test_connection() {
local name=$1 ; shift
local login=$1 ; shift
local password=$1 ; shift
local ip
ip=$(get_container_ip $name)
echo " Testing MySQL connection to $ip..."
local max_attempts=20
local sleep_time=2
local i
for i in $(seq $max_attempts); do
echo " Trying to connect..."
if mysql_cmd "$ip" "$login" "$password" <<< 'SELECT 1;'; then
echo " Success!"
return 0
fi
sleep $sleep_time
done
echo " Giving up: Failed to connect. Logs:"
docker logs $(get_cid $name)
return 1
}
function test_mysql() {
local container_ip="$1"
local login="$2"
local password="$3"
echo " Testing MySQL"
mysql_cmd "$container_ip" "$login" "$password" <<< 'CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));'
mysql_cmd "$container_ip" "$login" "$password" <<< 'INSERT INTO tbl VALUES ("foo1", "bar1");'
mysql_cmd "$container_ip" "$login" "$password" <<< 'INSERT INTO tbl VALUES ("foo2", "bar2");'
mysql_cmd "$container_ip" "$login" "$password" <<< 'INSERT INTO tbl VALUES ("foo3", "bar3");'
mysql_cmd "$container_ip" "$login" "$password" <<< 'SELECT * FROM tbl;'
mysql_cmd "$container_ip" "$login" "$password" <<< 'DROP TABLE tbl;'
echo " Success!"
}
function create_container() {
local name=$1 ; shift
cidfile="$CIDFILE_DIR/$name"
# create container with a cidfile in a directory for cleanup
local container_id
container_id="$(docker run ${DOCKER_ARGS:-} --cidfile $cidfile -d "$@" $IMAGE_NAME ${CONTAINER_ARGS:-})"
echo "Created container $container_id"
}
function run_change_password_test() {
local tmpdir=$(mktemp -d)
mkdir "${tmpdir}/data" && chmod -R a+rwx "${tmpdir}"
# Create MySQL container with persistent volume and set the initial password
create_container "testpass1" -e MYSQL_USER=user -e MYSQL_PASSWORD=foo \
-e MYSQL_DATABASE=db -v ${tmpdir}:/var/lib/mysql/data:Z
test_connection testpass1 user foo
docker stop $(get_cid testpass1) >/dev/null
# Create second container with changed password
create_container "testpass2" -e MYSQL_USER=user -e MYSQL_PASSWORD=bar \
-e MYSQL_DATABASE=db -v ${tmpdir}:/var/lib/mysql/data:Z
test_connection testpass2 user bar
# The old password should not work anymore
if mysql_cmd "$(get_container_ip testpass2)" user foo -e 'SELECT 1;'; then
return 1
fi
}
function run_replication_test() {
local cluster_args="-e MYSQL_MASTER_USER=master -e MYSQL_MASTER_PASSWORD=master -e MYSQL_DATABASE=db"
local max_attempts=30
# Run the MySQL master
docker run $cluster_args -e MYSQL_USER=user -e MYSQL_PASSWORD=foo \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_INNODB_BUFFER_POOL_SIZE=5M \
-d --cidfile ${CIDFILE_DIR}/master.cid $IMAGE_NAME mysqld-master >/dev/null
local master_ip
master_ip=$(get_container_ip master.cid)
# Run the MySQL slave
docker run $cluster_args -e MYSQL_MASTER_SERVICE_NAME=${master_ip} \
-e MYSQL_INNODB_BUFFER_POOL_SIZE=5M \
-d --cidfile ${CIDFILE_DIR}/slave.cid $IMAGE_NAME mysqld-slave >/dev/null
local slave_ip
slave_ip=$(get_container_ip slave.cid)
# Now wait till the MASTER will see the SLAVE
local i
for i in $(seq $max_attempts); do
result="$(mysql_cmd "$master_ip" root root -e 'SHOW SLAVE HOSTS;' | grep "$slave_ip" || true)"
if [[ -n "${result}" ]]; then
echo "${slave_ip} successfully registered as SLAVE for ${master_ip}"
break
fi
if [[ "${i}" == "${max_attempts}" ]]; then
echo "The ${slave_ip} failed to register in MASTER"
echo "Dumping logs for $(get_cid slave.cid)"
docker logs $(get_cid slave.cid)
return 1
fi
sleep 1
done
# do some real work to test replication in practice
mysql_cmd "$master_ip" root root -e "CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (24);"
# read value from slave and check whether it is expectd
for i in $(seq $max_attempts); do
set +e
result="$(mysql_cmd "${slave_ip}" root root -e "select * from t1 \G" | grep -e ^a | grep 24)"
set -e
if [[ ! -z "${result}" ]]; then
echo "${slave_ip} successfully got value from MASTER ${master_ip}"
break
fi
if [[ "${i}" == "${max_attempts}" ]]; then
echo "The ${slave_ip} failed to see value added on MASTER"
echo "Dumping logs for $(get_cid slave.cid)"
docker logs $(get_cid slave.cid)
return 1
fi
sleep 1
done
}
function assert_login_access() {
local container_ip=$1; shift
local USER=$1 ; shift
local PASS=$1 ; shift
local success=$1 ; shift
if mysql_cmd "$container_ip" "$USER" "$PASS" <<< 'SELECT 1;' ; then
if $success ; then
echo " $USER($PASS) access granted as expected"
return
fi
else
if ! $success ; then
echo " $USER($PASS) access denied as expected"
return
fi
fi
echo " $USER($PASS) login assertion failed"
exit 1
}
function assert_local_access() {
local id="$1" ; shift
docker exec $(get_cid "$id") bash -c 'mysql <<< "SELECT 1;"'
}
# Make sure the invocation of docker run fails.
function assert_container_creation_fails() {
# Time the docker run command. It should fail. If it doesn't fail,
# mysqld will keep running so we kill it with SIGKILL to make sure
# timeout returns a non-zero value.
local ret=0
timeout -s 9 --preserve-status 60s docker run --rm "$@" $IMAGE_NAME >/dev/null || ret=$?
# Timeout will exit with a high number.
if [ $ret -gt 30 ]; then
return 1
fi
}
function try_image_invalid_combinations() {
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_DATABASE=db "$@"
assert_container_creation_fails -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db "$@"
}
function run_container_creation_tests() {
echo " Testing image entrypoint usage"
assert_container_creation_fails
try_image_invalid_combinations
try_image_invalid_combinations -e MYSQL_ROOT_PASSWORD=root_pass
local VERY_LONG_DB_NAME="very_long_database_name_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD=pass
assert_container_creation_fails -e MYSQL_USER=\$invalid -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -e MYSQL_ROOT_PASSWORD=root_pass
assert_container_creation_fails -e MYSQL_USER=very_long_username -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -e MYSQL_ROOT_PASSWORD=root_pass
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD="\"" -e MYSQL_DATABASE=db -e MYSQL_ROOT_PASSWORD=root_pass
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=\$invalid -e MYSQL_ROOT_PASSWORD=root_pass
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=$VERY_LONG_DB_NAME -e MYSQL_ROOT_PASSWORD=root_pass
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -e MYSQL_ROOT_PASSWORD="\""
assert_container_creation_fails -e MYSQL_USER=root -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -e MYSQL_ROOT_PASSWORD=pass
echo " Success!"
}
function test_config_option() {
local container_name="$1"
local configuration="$2"
local option_name="$3"
local option_value="$4"
if ! echo "$configuration" | grep -qx "$option_name[[:space:]]*=[[:space:]]*$option_value"; then
local configs="$(docker exec -t "$(get_cid $container_name)" bash -c 'set +f; shopt -s nullglob; echo /etc/my.cnf /etc/my.cnf.d/* /opt/rh/mysql*/root/etc/my.cnf /opt/rh/mysql*/root/etc/my.cnf.d/* | paste -s')"
echo >&2 "FAIL: option '$option_name' should have value '$option_value', but it wasn't found in any of the configuration files ($configs):"
echo >&2
echo >&2 "$configuration"
echo >&2
return 1
fi
return 0
}
function run_configuration_tests() {
echo " Testing image configuration settings"
local container_name=config_test
create_container \
"$container_name" \
--env MYSQL_USER=config_test_user \
--env MYSQL_PASSWORD=config_test \
--env MYSQL_DATABASE=db \
--env MYSQL_LOWER_CASE_TABLE_NAMES=1 \
--env MYSQL_MAX_CONNECTIONS=1337 \
--env MYSQL_FT_MIN_WORD_LEN=8 \
--env MYSQL_FT_MAX_WORD_LEN=15 \
--env MYSQL_MAX_ALLOWED_PACKET=10M \
--env MYSQL_TABLE_OPEN_CACHE=100 \
--env MYSQL_SORT_BUFFER_SIZE=256K \
--env MYSQL_KEY_BUFFER_SIZE=16M \
--env MYSQL_READ_BUFFER_SIZE=16M \
--env MYSQL_INNODB_BUFFER_POOL_SIZE=16M \
--env MYSQL_INNODB_LOG_FILE_SIZE=4M \
--env MYSQL_INNODB_LOG_BUFFER_SIZE=4M \
--env WORKAROUND_DOCKER_BUG_14203=
#
test_connection "$container_name" config_test_user config_test
# TODO: this check is far from perfect and could be improved:
# - we should look for an option in the desired config, not in all of them
# - we should respect section of the config (now we have duplicated options from a different sections)
local configuration
configuration="$(docker exec -t "$(get_cid $container_name)" bash -c 'set +f; shopt -s nullglob; egrep -hv "^(#|\!|\[|$)" /etc/my.cnf /etc/my.cnf.d/* /opt/rh/mysql*/root/etc/my.cnf /opt/rh/mysql*/root/etc/my.cnf.d/*' | sed 's,\(^[[:space:]]\+\|[[:space:]]\+$\),,' | sort -u)"
test_config_option "$container_name" "$configuration" lower_case_table_names 1
test_config_option "$container_name" "$configuration" max_connections 1337
test_config_option "$container_name" "$configuration" ft_min_word_len 8
test_config_option "$container_name" "$configuration" ft_max_word_len 15
test_config_option "$container_name" "$configuration" max_allowed_packet 10M
test_config_option "$container_name" "$configuration" table_open_cache 100
test_config_option "$container_name" "$configuration" sort_buffer_size 256K
test_config_option "$container_name" "$configuration" key_buffer_size 16M
test_config_option "$container_name" "$configuration" read_buffer_size 16M
test_config_option "$container_name" "$configuration" innodb_buffer_pool_size 16M
test_config_option "$container_name" "$configuration" innodb_log_file_size 4M
test_config_option "$container_name" "$configuration" innodb_log_buffer_size 4M
docker stop "$(get_cid $container_name)" >/dev/null
echo " Success!"
echo " Testing image auto-calculated configuration settings"
container_name=dynamic_config_test
DOCKER_ARGS='--memory=256m' create_container \
"$container_name" \
--env MYSQL_USER=config_test_user \
--env MYSQL_PASSWORD=config_test \
--env MYSQL_DATABASE=db
test_connection "$container_name" config_test_user config_test
configuration="$(docker exec -t "$(get_cid $container_name)" bash -c 'set +f; shopt -s nullglob; egrep -hv "^(#|\!|\[|$)" /etc/my.cnf /etc/my.cnf.d/* /opt/rh/mysql*/root/etc/my.cnf /opt/rh/mysql*/root/etc/my.cnf.d/*' | sed 's,\(^[[:space:]]\+\|[[:space:]]\+$\),,' | sort -u)"
test_config_option "$container_name" "$configuration" key_buffer_size 25M
test_config_option "$container_name" "$configuration" read_buffer_size 12M
test_config_option "$container_name" "$configuration" innodb_buffer_pool_size 128M
test_config_option "$container_name" "$configuration" innodb_log_file_size 38M
test_config_option "$container_name" "$configuration" innodb_log_buffer_size 38M
docker stop "$(get_cid $container_name)" >/dev/null
echo " Success!"
}
test_scl_usage() {
local name="$1"
local run_cmd="$2"
local expected="$3"
echo " Testing the image SCL enable"
local out
out=$(docker run --rm ${IMAGE_NAME} /bin/bash -c "${run_cmd}")
if ! echo "${out}" | grep -q "${expected}"; then
echo "ERROR[/bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
fi
out=$(docker exec $(get_cid $name) /bin/bash -c "${run_cmd}" 2>&1)
if ! echo "${out}" | grep -q "${expected}"; then
echo "ERROR[exec /bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
fi
out=$(docker exec $(get_cid $name) /bin/sh -ic "${run_cmd}" 2>&1)
if ! echo "${out}" | grep -q "${expected}"; then
echo "ERROR[exec /bin/sh -ic "${run_cmd}"] Expected '${expected}', got '${out}'"
return 1
fi
}
function run_tests() {
local name=$1 ; shift
envs="-e MYSQL_USER=$USER -e MYSQL_PASSWORD=$PASS -e MYSQL_DATABASE=db"
if [ -v ROOT_PASS ]; then
envs="$envs -e MYSQL_ROOT_PASSWORD=$ROOT_PASS"
fi
create_container $name $envs
test_connection "$name" "$USER" "$PASS"
echo " Testing scl usage"
test_scl_usage $name 'mysql --version' '10.1'
echo " Testing login accesses"
local container_ip
container_ip=$(get_container_ip $name)
assert_login_access "$container_ip" "$USER" "$PASS" true
assert_login_access "$container_ip" "$USER" "${PASS}_foo" false
if [ -v ROOT_PASS ]; then
assert_login_access "$container_ip" root "$ROOT_PASS" true
assert_login_access "$container_ip" root "${ROOT_PASS}_foo" false
else
assert_login_access "$container_ip" root 'foo' false
assert_login_access "$container_ip" root '' false
fi
assert_local_access "$name"
echo " Success!"
test_mysql "$container_ip" "$USER" "$PASS"
}
run_doc_test() {
local tmpdir=$(mktemp -d)
local f
echo " Testing documentation in the container image"
# Extract the help files from the container
for f in /usr/share/container-scripts/mysql/README.md help.1 ; do
docker run --rm ${IMAGE_NAME} /bin/bash -c "cat /${f}" >${tmpdir}/$(basename ${f})
# Check whether the files include some important information
for term in MYSQL_ROOT_PASSWORD volume 3306 ; do
if ! cat ${tmpdir}/$(basename ${f}) | grep -q -e "${term}" ; then
echo "ERROR: File /${f} does not include '${term}'."
return 1
fi
done
done
# Check whether the files use the correct format
if ! file ${tmpdir}/help.1 | grep -q roff ; then
echo "ERROR: /help.1 is not in troff or groff format"
return 1
fi
echo " Success!"
echo
}
# Tests.
run_container_creation_tests
run_configuration_tests
# Set lower buffer pool size to avoid running out of memory.
export CONTAINER_ARGS="run-mysqld --innodb_buffer_pool_size=5242880"
# Normal tests
USER=user PASS=pass run_tests no_root
USER=user1 PASS=pass1 ROOT_PASS=r00t run_tests root
# Test with arbitrary uid for the container
DOCKER_ARGS="-u 12345" USER=user PASS=pass run_tests no_root_altuid
DOCKER_ARGS="-u 12345" USER=user1 PASS=pass1 ROOT_PASS=r00t run_tests root_altuid
# Test the password change
run_change_password_test
# Replication tests
run_replication_test
run_doc_test