Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions 5.5/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM centos:centos7
# MySQL image for OpenShift.
#
# Volumes:
# * /var/lib/mysql - Datastore for MySQL
# * /var/lib/mysql/data - Datastore for MySQL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe explain the reasoning in docs or in comment

# Environment:
# * $MYSQL_USER - Database user name
# * $MYSQL_PASSWORD - User's password
Expand All @@ -26,14 +26,16 @@ RUN rpmkeys --import file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 && \
yum -y --setopt=tsflags=nodocs install https://www.softwarecollections.org/en/scls/rhscl/mysql55/epel-7-x86_64/download/rhscl-mysql55-epel-7-x86_64.noarch.rpm && \
yum -y --setopt=tsflags=nodocs install hostname mysql55 && \
yum clean all && \
mkdir -p /var/lib/mysql && chown mysql.mysql /var/lib/mysql && \
mkdir -p /var/lib/mysql/data && chown mysql.mysql /var/lib/mysql/data && \
test "$(id mysql)" = "uid=27(mysql) gid=27(mysql) groups=27(mysql)"

COPY run-mysqld.sh /usr/local/bin/
COPY contrib /opt/openshift/
COPY contrib/.bashrc /var/lib/mysql/
COPY contrib/etc /opt/openshift/etc/

VOLUME ["/var/lib/mysql"]
VOLUME ["/var/lib/mysql/data"]

USER mysql

ENTRYPOINT ["run-mysqld.sh"]
CMD ["mysqld"]
10 changes: 6 additions & 4 deletions 5.5/Dockerfile.rhel7
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM rhel7
# MySQL image for OpenShift.
#
# Volumes:
# * /var/lib/mysql - Datastore for MySQL
# * /var/lib/mysql/data - Datastore for MySQL
# Environment:
# * $MYSQL_USER - Database user name
# * $MYSQL_PASSWORD - User's password
Expand All @@ -27,14 +27,16 @@ RUN yum install -y yum-utils hostname && \
yum-config-manager --enable rhel-7-server-optional-rpms && \
yum install -y --setopt=tsflags=nodocs mysql55 && \
yum clean all && \
mkdir -p /var/lib/mysql && chown mysql.mysql /var/lib/mysql && \
mkdir -p /var/lib/mysql/data && chown mysql.mysql /var/lib/mysql/data && \
test "$(id mysql)" = "uid=27(mysql) gid=27(mysql) groups=27(mysql)"

COPY run-mysqld.sh /usr/local/bin/
COPY contrib /opt/openshift/
COPY contrib/.bashrc /var/lib/mysql/
COPY contrib/etc /opt/openshift/etc/

VOLUME ["/var/lib/mysql"]
VOLUME ["/var/lib/mysql/data"]

USER mysql

ENTRYPOINT ["run-mysqld.sh"]
CMD ["mysqld"]
2 changes: 2 additions & 0 deletions 5.5/contrib/.bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# This will make scl collection binaries work out of box.
source scl_source enable mysql55
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so does this work if i just docker exec into a running container with /bin/sh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, but will work with interactive bash shell.

2 changes: 1 addition & 1 deletion 5.5/contrib/etc/my.cnf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[mysqld]
user=mysql

datadir=/var/lib/mysql
datadir=/var/lib/mysql/data
basedir=/opt/rh/mysql55/root/usr
plugin-dir=/opt/rh/mysql55/root/usr/lib64/mysql/plugin

Expand Down
90 changes: 49 additions & 41 deletions 5.5/run-mysqld.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
#!/bin/bash -e
#!/bin/bash

# For SCL enablement
source $HOME/.bashrc

set -eu

# Data directory where MySQL database files live. The data subdirectory is here
# because .bashrc lives in /var/lib/mysql/ and we don't want a volume to
# override it.
MYSQL_DATADIR=/var/lib/mysql/data
MYSQL_DEFAULTS_FILE=/opt/openshift/etc/my.cnf

# Be paranoid and stricter than we should be.
# https://dev.mysql.com/doc/refman/5.5/en/identifiers.html
mysql_identifier_regex='^[a-zA-Z0-9_]+$'
mysql_password_regex='^[a-zA-Z0-9_~!@#$%^&*()-=<>,.?;:|]+$'

function usage {
function usage() {
if [ $# == 2 ]; then
echo "error: $1"
fi
echo "You must specify following environment variables:"
echo " \$MYSQL_USER (regex: '$mysql_identifier_regex')"
echo " \$MYSQL_PASSWORD (regex: '$mysql_password_regex')"
Expand All @@ -15,38 +29,24 @@ function usage {
exit 1
}

function valid_mysql_identifier {
local var="$1" ; shift
[[ "${var}" =~ $mysql_identifier_regex ]]
}

function valid_mysql_password {
local var="$1" ; shift
[[ "${var}" =~ $mysql_password_regex ]]
function check_env_vars() {
[[ "$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"
[[ "$MYSQL_DATABASE" =~ $mysql_identifier_regex ]] || usage "Invalid database name"
[ ${#MYSQL_DATABASE} -le 64 ] || usage "Database name too long (maximum 64 characters)"
if [ -v MYSQL_ROOT_PASSWORD ]; then
[[ "$MYSQL_ROOT_PASSWORD" =~ $mysql_password_regex ]] || usage "Invalid root password"
fi
}

valid_mysql_identifier "$MYSQL_USER" || usage
valid_mysql_password "$MYSQL_PASSWORD" || usage
valid_mysql_identifier "$MYSQL_DATABASE" || usage

# Make sure env variables don't propagate to mysqld process.
mysql_user="$MYSQL_USER" ; unset MYSQL_USER
mysql_pass="$MYSQL_PASSWORD" ; unset MYSQL_PASSWORD
mysql_db="$MYSQL_DATABASE" ; unset MYSQL_DATABASE

# Root password.
if [ "$MYSQL_ROOT_PASSWORD" ]; then
valid_mysql_password "$MYSQL_ROOT_PASSWORD" || usage
root_pass="$MYSQL_ROOT_PASSWORD"
fi
unset MYSQL_ROOT_PASSWORD

# SCL in CentOS/RHEL 7 doesn't support --exec, we need to do it ourselves
# The '|| exit 1' is here so -e doesn't propagate into scl_source.
source scl_source enable mysql55 || exit 1
function unset_env_vars() {
unset MYSQL_USER MYSQL_PASSWORD MYSQL_DATABASE MYSQL_ROOT_PASSWORD
}

# Poll until MySQL responds to our ping.
function wait_for_mysql {
function wait_for_mysql() {
pid=$1 ; shift

while [ true ]; do
Expand All @@ -60,39 +60,47 @@ function wait_for_mysql {
done
}

if [ ! -d '/var/lib/mysql/mysql' ]; then
if [ "$1" = "mysqld" -a ! -d "$MYSQL_DATADIR/mysql" ]; then

shift
check_env_vars

echo 'Running mysql_install_db'
mysql_install_db --datadir=/var/lib/mysql
mysql_install_db --datadir=$MYSQL_DATADIR

# Now start mysqld and add appropriate users.
echo 'Starting mysqld to create users'
/opt/rh/mysql55/root/usr/libexec/mysqld \
--defaults-file=/opt/openshift/etc/my.cnf \
--defaults-file=$MYSQL_DEFAULTS_FILE \
--skip-networking --socket=/tmp/mysql.sock &
mysql_pid=$!
wait_for_mysql $mysql_pid

# Set common flags.
mysql_flags="-u root --socket=/tmp/mysql.sock"
admin_flags="--defaults-file=/opt/openshift/etc/my.cnf $mysql_flags"
admin_flags="--defaults-file=$MYSQL_DEFAULTS_FILE $mysql_flags"

mysqladmin $admin_flags -f drop test
mysqladmin $admin_flags create "${mysql_db}"
mysqladmin $admin_flags create "${MYSQL_DATABASE}"
mysql $mysql_flags <<-EOSQL
CREATE USER '${mysql_user}'@'%' IDENTIFIED BY '${mysql_pass}';
GRANT ALL ON \`${mysql_db}\`.* TO '${mysql_user}'@'%' ;
CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';
GRANT ALL ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_USER}'@'%' ;
FLUSH PRIVILEGES ;
EOSQL

if [ -v root_pass ]; then
if [ -v MYSQL_ROOT_PASSWORD ]; then
mysql $mysql_flags <<-EOSQL
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${root_pass}';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';
EOSQL
fi
mysqladmin $admin_flags flush-privileges shutdown

unset_env_vars

exec /opt/rh/mysql55/root/usr/libexec/mysqld \
--defaults-file=$MYSQL_DEFAULTS_FILE \
"$@" 2>&1
fi

exec /opt/rh/mysql55/root/usr/libexec/mysqld \
--defaults-file=/opt/openshift/etc/my.cnf \
"$@" 2>&1
unset_env_vars
exec "$@"
64 changes: 52 additions & 12 deletions 5.5/test/run
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ IMAGE_NAME=${IMAGE_NAME-openshift/mysql-55-centos7-candidate}

CIDFILE_DIR=$(mktemp --suffix=mysql_test_cidfiles -d)

cleanup() {
function cleanup() {
for cidfile in $CIDFILE_DIR/* ; do
CONTAINER=$(cat $cidfile)

Expand All @@ -32,21 +32,21 @@ cleanup() {
}
trap cleanup EXIT SIGINT

get_cid () {
function get_cid() {
local id="$1" ; shift || return 1
echo $(cat "$CIDFILE_DIR/$id")
}

get_container_ip() {
function get_container_ip() {
local id="$1" ; shift
docker inspect --format='{{.NetworkSettings.IPAddress}}' $(get_cid "$id")
}

mysql_cmd() {
docker run --rm --entrypoint=scl $IMAGE_NAME enable mysql55 -- mysql --host $CONTAINER_IP -u$USER -p"$PASS" "$@" db
function mysql_cmd() {
docker run --rm $IMAGE_NAME mysql --host $CONTAINER_IP -u$USER -p"$PASS" "$@" db
}

test_connection() {
function test_connection() {
local name=$1 ; shift
ip=$(get_container_ip $name)
echo " Testing MySQL connection to $ip..."
Expand All @@ -69,7 +69,7 @@ test_connection() {
return 1
}

test_mysql() {
function test_mysql() {
echo " Testing MySQL"
mysql_cmd <<< "CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));"
mysql_cmd <<< "INSERT INTO tbl VALUES ('foo1', 'bar1');"
Expand All @@ -80,27 +80,66 @@ test_mysql() {
echo " Success!"
}

create_container() {
function create_container() {
local name=$1 ; shift
cidfile="$CIDFILE_DIR/$name"
# create container with a cidfile in a directory for cleanup
docker run --cidfile $cidfile -d "$@" $IMAGE_NAME
echo "Created container $(cat $cidfile)"
}

assert_login_access() {
function assert_login_access() {
local USER=$1 ; shift
local PASS=$1 ; shift
local SUCCESS=$1 ; shift
local success=$1 ; shift

if $SUCCESS; then
if $success; then
mysql_cmd <<< "SELECT 1;" && echo " $USER($PASS) access granted as expected"
else
mysql_cmd <<< "SELECT 1;" || echo " $USER($PASS) access denied as expected"
fi
}

run_tests() {
# Make sure the invocation of docker run fails.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image_creation seems like the wrong name for this... do you mean db creation?

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.
set +e
timeout -s 9 --preserve-status 60s docker run --rm "$@" $IMAGE_NAME
ret=$?
set -e

# Timeout will exit with a high number.
if [ $ret -gt 30 ]; then
return 1
fi
}

function try_image_invalid_combinations() {
assert_container_creation_fails "$@"
assert_container_creation_fails -e MYSQL_USER=user -e MYSQL_PASSWORD=pass "$@"
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"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again this isn't image creation, it's container creation or db creation.

try_image_invalid_combinations
try_image_invalid_combinations -e MYSQL_ROOT_PASSWORD=root_pass

VERY_LONG_DB_NAME="very_long_database_name_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
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="\""
echo " Success!"
}

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
Expand All @@ -125,5 +164,6 @@ run_tests() {

# Tests.

run_container_creation_tests
USER=user PASS=pass run_tests no_root
USER=user1 PASS=pass1 ROOT_PASS=r00t run_tests root
Loading