Implement MySQL check script for Docker

Story: 2001694
Task: 23321

Change-Id: I103c864832cd85ec528080cb7d49393c09127c60
This commit is contained in:
Dobroslaw Zybort 2018-07-25 14:05:35 +02:00 committed by Witold Bedyk
parent 1cce6824ed
commit dcea427a62
2 changed files with 83 additions and 9 deletions

View File

@ -5,7 +5,7 @@
# https://github.com/pyca/cryptography/pull/4270 # https://github.com/pyca/cryptography/pull/4270
FROM python:3.5.5-alpine3.7 FROM python:3.5.5-alpine3.7
COPY wait_for.sh kafka_wait_for_topics.py / COPY wait_for.sh kafka_wait_for_topics.py mysql_check.py /
COPY ashrc /root/.ashrc COPY ashrc /root/.ashrc
ENV \ ENV \
@ -23,7 +23,7 @@ LABEL org.opencontainers.image.revision="$BASE_GIT_COMMIT"
LABEL org.opencontainers.image.licenses="Apache-2.0" LABEL org.opencontainers.image.licenses="Apache-2.0"
RUN \ RUN \
chmod +x /wait_for.sh /kafka_wait_for_topics.py && \ chmod +x /wait_for.sh /kafka_wait_for_topics.py /mysql_check.py && \
apk add --no-cache \ apk add --no-cache \
su-exec=0.2-r0 \ su-exec=0.2-r0 \
tini=0.16.1-r0 \ tini=0.16.1-r0 \

View File

@ -19,15 +19,34 @@
It's checking if requested database already exists. It's checking if requested database already exists.
For using this script you need to set some environment variables:
* `MYSQL_HOST` for connection string to MySQL.
Example: `mysql`, `192.168.10.6`.
Default: `mysql`.
* `MYSQL_PORT` for connection string to MySQL port.
Default: `3306`.
* `MYSQL_USER` for user that is cappable to connect to MySQL.
Default: `monapi`.
* `MYSQL_PASSWORD` for user password.
Default: `password`.
* `MYSQL_DB` for database that you need to have before starting service.
Default: `mon`.
After making sure that this environment variables are set you can simply After making sure that this environment variables are set you can simply
execute this script in the following way: execute this script in the following way:
`python3 mysql_check.py && ./start_service.sh` `python3 mysql_check.py && ./start_service.sh`
`python3 mysql_check.py || exit 1` `python3 mysql_check.py || exit 1`
Additional environment variables available are:
* `LOG_LEVEL` - default to `INFO`
* `MYSQL_WAIT_RETRIES` - number of retries, default to `24`
* `MYSQL_WAIT_INTERVAL` - in seconds, default to `5`
""" """
import logging import logging
import os import os
import sys import sys
import time
import pymysql import pymysql
@ -42,7 +61,7 @@ logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
MYSQL_HOST = os.environ.get('MYSQL_HOST', 'mysql') MYSQL_HOST = os.environ.get('MYSQL_HOST', 'mysql')
MYSQL_PORT = os.environ.get('MYSQL_HOST', 3306) MYSQL_PORT = os.environ.get('MYSQL_PORT', 3306)
MYSQL_USER = os.environ.get('MYSQL_USER', 'monapi') MYSQL_USER = os.environ.get('MYSQL_USER', 'monapi')
MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', 'password') MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', 'password')
MYSQL_DB = os.environ.get('MYSQL_DB', 'mon') MYSQL_DB = os.environ.get('MYSQL_DB', 'mon')
@ -50,9 +69,64 @@ MYSQL_DB = os.environ.get('MYSQL_DB', 'mon')
MYSQL_WAIT_RETRIES = int(os.environ.get('MYSQL_WAIT_RETRIES', '24')) MYSQL_WAIT_RETRIES = int(os.environ.get('MYSQL_WAIT_RETRIES', '24'))
MYSQL_WAIT_INTERVAL = int(os.environ.get('MYSQL_WAIT_INTERVAL', '5')) MYSQL_WAIT_INTERVAL = int(os.environ.get('MYSQL_WAIT_INTERVAL', '5'))
# TODO(Dobroslaw): All checks and retry.
db = pymysql.connect( def retry(retries=MYSQL_WAIT_RETRIES, delay=MYSQL_WAIT_INTERVAL,
host=MYSQL_HOST, port=MYSQL_PORT, check_exceptions=()):
user=MYSQL_USER, passwd=MYSQL_PASSWORD, """Retry decorator."""
db=MYSQL_DB def decorator(func):
) """Decorator."""
def f_retry(*args, **kwargs):
"""Retry running function on exception after delay."""
for i in range(1, retries + 1):
try:
return func(*args, **kwargs)
# pylint: disable=W0703
# We want to catch all exceptions here to retry.
except check_exceptions + (Exception,) as exc:
if i < retries:
logger.info('Connection attempt %d of %d failed',
i, retries)
if isinstance(exc, check_exceptions):
logger.debug('Caught known exception, retrying...',
exc_info=True)
else:
logger.warn(
'Caught unknown exception, retrying...',
exc_info=True)
else:
logger.exception('Failed after %d attempts', retries)
raise
# No exception so wait before retrying
time.sleep(delay)
return f_retry
return decorator
@retry(check_exceptions=(pymysql.err.OperationalError,))
def connect_mysql(host, port, user, password, database):
"""Connect to MySQL with retries."""
return pymysql.connect(
host=host, port=port,
user=user, passwd=password,
db=database
)
def main():
"""Start main part of the wait script."""
logger.info('Waiting for database: `%s`', MYSQL_DB)
connect_mysql(
host=MYSQL_HOST, port=MYSQL_PORT,
user=MYSQL_USER, password=MYSQL_PASSWORD,
database=MYSQL_DB
)
logger.info('Database `%s` found', MYSQL_DB)
if __name__ == '__main__':
main()